blob: bc8aaeb5ed7d69ee1cd33e3083b861f92c55899a [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530197static vos_wake_lock_t wlan_wake_lock;
198
Jeff Johnson295189b2012-06-20 16:38:30 -0700199/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700200static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700203static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
204static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
206void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800207void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700208
Jeff Johnson295189b2012-06-20 16:38:30 -0700209v_U16_t hdd_select_queue(struct net_device *dev,
210 struct sk_buff *skb);
211
212#ifdef WLAN_FEATURE_PACKET_FILTERING
213static void hdd_set_multicast_list(struct net_device *dev);
214#endif
215
216void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
217
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800218#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800219void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
220static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700221static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
222 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
223 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700224static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
225 tANI_U8 *pTargetApBssid,
226 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800227#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530228
229/* Store WLAN driver info in a global variable such that crash debugger
230 can extract it from driver debug symbol and crashdump for post processing */
231tANI_U8 g_wlan_driver[ ] = "pronto_driver";
232
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800233#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700234VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800235#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700236
Mihir Shetee1093ba2014-01-21 20:13:32 +0530237static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530238const char * hdd_device_modetoString(v_U8_t device_mode)
239{
240 switch(device_mode)
241 {
242 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
243 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
244 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
246 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
247 CASE_RETURN_STRING( WLAN_HDD_FTM );
248 CASE_RETURN_STRING( WLAN_HDD_IBSS );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
250 default:
251 return "device_mode Unknown";
252 }
253}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530254
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530255static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700256 unsigned long state,
257 void *ndev)
258{
259 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700261 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262#ifdef WLAN_BTAMP_FEATURE
263 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700264#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530265 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700266
267 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700268 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700269 (strncmp(dev->name, "p2p", 3)))
270 return NOTIFY_DONE;
271
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700274
Jeff Johnson27cee452013-03-27 11:10:24 -0700275 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 VOS_ASSERT(0);
279 return NOTIFY_DONE;
280 }
281
Jeff Johnson27cee452013-03-27 11:10:24 -0700282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
283 if (NULL == pHddCtx)
284 {
285 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
286 VOS_ASSERT(0);
287 return NOTIFY_DONE;
288 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800289 if (pHddCtx->isLogpInProgress)
290 return NOTIFY_DONE;
291
Jeff Johnson27cee452013-03-27 11:10:24 -0700292
293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
294 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700295
296 switch (state) {
297 case NETDEV_REGISTER:
298 break;
299
300 case NETDEV_UNREGISTER:
301 break;
302
303 case NETDEV_UP:
304 break;
305
306 case NETDEV_DOWN:
307 break;
308
309 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700310 if(TRUE == pAdapter->isLinkUpSvcNeeded)
311 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 break;
313
314 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530315 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530316 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530317 {
318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
319 "%s: Timeout occurred while waiting for abortscan %ld",
320 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 }
322 else
323 {
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530325 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 }
327#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 status = WLANBAP_StopAmp();
330 if(VOS_STATUS_SUCCESS != status )
331 {
332 pHddCtx->isAmpAllowed = VOS_TRUE;
333 hddLog(VOS_TRACE_LEVEL_FATAL,
334 "%s: Failed to stop AMP", __func__);
335 }
336 else
337 {
338 //a state m/c implementation in PAL is TBD to avoid this delay
339 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700340 if ( pHddCtx->isAmpAllowed )
341 {
342 WLANBAP_DeregisterFromHCI();
343 pHddCtx->isAmpAllowed = VOS_FALSE;
344 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 }
346#endif //WLAN_BTAMP_FEATURE
347 break;
348
349 default:
350 break;
351 }
352
353 return NOTIFY_DONE;
354}
355
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530356static int hdd_netdev_notifier_call(struct notifier_block * nb,
357 unsigned long state,
358 void *ndev)
359{
360 int ret;
361 vos_ssr_protect(__func__);
362 ret = __hdd_netdev_notifier_call( nb, state, ndev);
363 vos_ssr_unprotect(__func__);
364 return ret;
365}
366
Jeff Johnson295189b2012-06-20 16:38:30 -0700367struct notifier_block hdd_netdev_notifier = {
368 .notifier_call = hdd_netdev_notifier_call,
369};
370
371/*---------------------------------------------------------------------------
372 * Function definitions
373 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700374void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
375void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700376//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700377static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700378#ifndef MODULE
379/* current con_mode - used only for statically linked driver
380 * con_mode is changed by userspace to indicate a mode change which will
381 * result in calling the module exit and init functions. The module
382 * exit function will clean up based on the value of con_mode prior to it
383 * being changed by userspace. So curr_con_mode records the current con_mode
384 * for exit when con_mode becomes the next mode for init
385 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700386static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700387#endif
388
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800389/**---------------------------------------------------------------------------
390
391 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
392
393 Called immediately after the cfg.ini is read in order to configure
394 the desired trace levels.
395
396 \param - moduleId - module whose trace level is being configured
397 \param - bitmask - bitmask of log levels to be enabled
398
399 \return - void
400
401 --------------------------------------------------------------------------*/
402static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
403{
404 wpt_tracelevel level;
405
406 /* if the bitmask is the default value, then a bitmask was not
407 specified in cfg.ini, so leave the logging level alone (it
408 will remain at the "compiled in" default value) */
409 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
410 {
411 return;
412 }
413
414 /* a mask was specified. start by disabling all logging */
415 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
416
417 /* now cycle through the bitmask until all "set" bits are serviced */
418 level = VOS_TRACE_LEVEL_FATAL;
419 while (0 != bitmask)
420 {
421 if (bitmask & 1)
422 {
423 vos_trace_setValue(moduleId, level, 1);
424 }
425 level++;
426 bitmask >>= 1;
427 }
428}
429
430
Jeff Johnson295189b2012-06-20 16:38:30 -0700431/**---------------------------------------------------------------------------
432
433 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
434
435 Called immediately after the cfg.ini is read in order to configure
436 the desired trace levels in the WDI.
437
438 \param - moduleId - module whose trace level is being configured
439 \param - bitmask - bitmask of log levels to be enabled
440
441 \return - void
442
443 --------------------------------------------------------------------------*/
444static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
445{
446 wpt_tracelevel level;
447
448 /* if the bitmask is the default value, then a bitmask was not
449 specified in cfg.ini, so leave the logging level alone (it
450 will remain at the "compiled in" default value) */
451 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
452 {
453 return;
454 }
455
456 /* a mask was specified. start by disabling all logging */
457 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
458
459 /* now cycle through the bitmask until all "set" bits are serviced */
460 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
461 while (0 != bitmask)
462 {
463 if (bitmask & 1)
464 {
465 wpalTraceSetLevel(moduleId, level, 1);
466 }
467 level++;
468 bitmask >>= 1;
469 }
470}
Jeff Johnson295189b2012-06-20 16:38:30 -0700471
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530472/*
473 * FUNCTION: wlan_hdd_validate_context
474 * This function is used to check the HDD context
475 */
476int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
477{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530478
479 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
480 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530482 "%s: HDD context is Null", __func__);
483 return -ENODEV;
484 }
485
486 if (pHddCtx->isLogpInProgress)
487 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530489 "%s: LOGP %s. Ignore!!", __func__,
490 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
491 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530492 return -EAGAIN;
493 }
494
Mihir Shete18156292014-03-11 15:38:30 +0530495 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530496 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530498 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
499 return -EAGAIN;
500 }
501 return 0;
502}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700503#ifdef CONFIG_ENABLE_LINUX_REG
504void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
505{
506 hdd_adapter_t *pAdapter = NULL;
507 hdd_station_ctx_t *pHddStaCtx = NULL;
508 eCsrPhyMode phyMode;
509 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530510
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700511 if (NULL == pHddCtx)
512 {
513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
514 "HDD Context is null !!");
515 return ;
516 }
517
518 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
519 if (NULL == pAdapter)
520 {
521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
522 "pAdapter is null !!");
523 return ;
524 }
525
526 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
527 if (NULL == pHddStaCtx)
528 {
529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
530 "pHddStaCtx is null !!");
531 return ;
532 }
533
534 cfg_param = pHddCtx->cfg_ini;
535 if (NULL == cfg_param)
536 {
537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
538 "cfg_params not available !!");
539 return ;
540 }
541
542 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
543
544 if (!pHddCtx->isVHT80Allowed)
545 {
546 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
547 (eCSR_DOT11_MODE_11ac == phyMode) ||
548 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
549 {
550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
551 "Setting phymode to 11n!!");
552 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
553 }
554 }
555 else
556 {
557 /*New country Supports 11ac as well resetting value back from .ini*/
558 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
559 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
560 return ;
561 }
562
563 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
564 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
565 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
566 {
567 VOS_STATUS vosStatus;
568
569 // need to issue a disconnect to CSR.
570 INIT_COMPLETION(pAdapter->disconnect_comp_var);
571 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
572 pAdapter->sessionId,
573 eCSR_DISCONNECT_REASON_UNSPECIFIED );
574
575 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530576 {
577 long ret;
578
579 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700580 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530581 if (0 >= ret)
582 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
583 ret);
584 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700585
586 }
587}
588#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530589void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
590{
591 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
592 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
593 hdd_config_t *cfg_param;
594 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530595 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530596
597 if (NULL == pHddCtx)
598 {
599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
600 "HDD Context is null !!");
601 return ;
602 }
603
604 cfg_param = pHddCtx->cfg_ini;
605
606 if (NULL == cfg_param)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
609 "cfg_params not available !!");
610 return ;
611 }
612
613 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
614
615 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
616 {
617 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
618 (eCSR_DOT11_MODE_11ac == phyMode) ||
619 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
620 {
621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
622 "Setting phymode to 11n!!");
623 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
624 }
625 }
626 else
627 {
628 /*New country Supports 11ac as well resetting value back from .ini*/
629 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
630 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
631 return ;
632 }
633
634 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
635 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
636 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
637 {
638 VOS_STATUS vosStatus;
639
640 // need to issue a disconnect to CSR.
641 INIT_COMPLETION(pAdapter->disconnect_comp_var);
642 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
643 pAdapter->sessionId,
644 eCSR_DISCONNECT_REASON_UNSPECIFIED );
645
646 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530647 {
648 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530649 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530650 if (ret <= 0)
651 {
652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
653 "wait on disconnect_comp_var is failed %ld", ret);
654 }
655 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530656
657 }
658}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700659#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530660
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700661void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
662{
663 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
664 hdd_config_t *cfg_param;
665
666 if (NULL == pHddCtx)
667 {
668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
669 "HDD Context is null !!");
670 return ;
671 }
672
673 cfg_param = pHddCtx->cfg_ini;
674
675 if (NULL == cfg_param)
676 {
677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
678 "cfg_params not available !!");
679 return ;
680 }
681
Agarwal Ashish738843c2014-09-25 12:27:56 +0530682 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
683 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700684 {
685 /*New country doesn't support DFS */
686 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
687 }
688 else
689 {
690 /*New country Supports DFS as well resetting value back from .ini*/
691 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
692 }
693
694}
695
Rajeev79dbe4c2013-10-05 11:03:42 +0530696#ifdef FEATURE_WLAN_BATCH_SCAN
697
698/**---------------------------------------------------------------------------
699
700 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
701 input string
702
703 This function extracts assigned integer from string in below format:
704 "STRING=10" : extracts integer 10 from this string
705
706 \param - pInPtr Pointer to input string
707 \param - base Base for string to int conversion(10 for decimal 16 for hex)
708 \param - pOutPtr Pointer to variable in which extracted integer needs to be
709 assigned
710 \param - pLastArg to tell whether it is last arguement in input string or
711 not
712
713 \return - NULL for failure cases
714 pointer to next arguement in input string for success cases
715 --------------------------------------------------------------------------*/
716static tANI_U8 *
717hdd_extract_assigned_int_from_str
718(
719 tANI_U8 *pInPtr,
720 tANI_U8 base,
721 tANI_U32 *pOutPtr,
722 tANI_U8 *pLastArg
723)
724{
725 int tempInt;
726 int v = 0;
727 char buf[32];
728 int val = 0;
729 *pLastArg = FALSE;
730
731 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
732 if (NULL == pInPtr)
733 {
734 return NULL;
735 }
736
737 pInPtr++;
738
739 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
740
741 val = sscanf(pInPtr, "%32s ", buf);
742 if (val < 0 && val > strlen(pInPtr))
743 {
744 return NULL;
745 }
746 pInPtr += val;
747 v = kstrtos32(buf, base, &tempInt);
748 if (v < 0)
749 {
750 return NULL;
751 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800752 if (tempInt < 0)
753 {
754 tempInt = 0;
755 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530756 *pOutPtr = tempInt;
757
758 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
759 if (NULL == pInPtr)
760 {
761 *pLastArg = TRUE;
762 return NULL;
763 }
764 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
765
766 return pInPtr;
767}
768
769/**---------------------------------------------------------------------------
770
771 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
772 input string
773
774 This function extracts assigned character from string in below format:
775 "STRING=A" : extracts char 'A' from this string
776
777 \param - pInPtr Pointer to input string
778 \param - pOutPtr Pointer to variable in which extracted char needs to be
779 assigned
780 \param - pLastArg to tell whether it is last arguement in input string or
781 not
782
783 \return - NULL for failure cases
784 pointer to next arguement in input string for success cases
785 --------------------------------------------------------------------------*/
786static tANI_U8 *
787hdd_extract_assigned_char_from_str
788(
789 tANI_U8 *pInPtr,
790 tANI_U8 *pOutPtr,
791 tANI_U8 *pLastArg
792)
793{
794 *pLastArg = FALSE;
795
796 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
797 if (NULL == pInPtr)
798 {
799 return NULL;
800 }
801
802 pInPtr++;
803
804 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
805
806 *pOutPtr = *pInPtr;
807
808 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
809 if (NULL == pInPtr)
810 {
811 *pLastArg = TRUE;
812 return NULL;
813 }
814 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
815
816 return pInPtr;
817}
818
819
820/**---------------------------------------------------------------------------
821
822 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
823
824 This function parses set batch scan command in below format:
825 WLS_BATCHING_SET <space> followed by below arguements
826 "SCANFREQ=XX" : Optional defaults to 30 sec
827 "MSCAN=XX" : Required number of scans to attempt to batch
828 "BESTN=XX" : Best Network (RSSI) defaults to 16
829 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
830 A. implies only 5 GHz , B. implies only 2.4GHz
831 "RTT=X" : optional defaults to 0
832 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
833 error
834
835 For example input commands:
836 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
837 translated into set batch scan with following parameters:
838 a) Frequence 60 seconds
839 b) Batch 10 scans together
840 c) Best RSSI to be 20
841 d) 5GHz band only
842 e) RTT is equal to 0
843
844 \param - pValue Pointer to input channel list
845 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
846
847 \return - 0 for success non-zero for failure
848
849 --------------------------------------------------------------------------*/
850static int
851hdd_parse_set_batchscan_command
852(
853 tANI_U8 *pValue,
854 tSirSetBatchScanReq *pHddSetBatchScanReq
855)
856{
857 tANI_U8 *inPtr = pValue;
858 tANI_U8 val = 0;
859 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800860 tANI_U32 nScanFreq;
861 tANI_U32 nMscan;
862 tANI_U32 nBestN;
863 tANI_U8 ucRfBand;
864 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800865 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530866
867 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800868 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
869 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
870 nRtt = 0;
871 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530872
873 /*go to space after WLS_BATCHING_SET command*/
874 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
875 /*no argument after the command*/
876 if (NULL == inPtr)
877 {
878 return -EINVAL;
879 }
880
881 /*no space after the command*/
882 else if (SPACE_ASCII_VALUE != *inPtr)
883 {
884 return -EINVAL;
885 }
886
887 /*removing empty spaces*/
888 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
889
890 /*no argument followed by spaces*/
891 if ('\0' == *inPtr)
892 {
893 return -EINVAL;
894 }
895
896 /*check and parse SCANFREQ*/
897 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
898 {
899 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800900 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800901
Rajeev Kumarc933d982013-11-18 20:04:20 -0800902 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800903 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800904 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800905 }
906
Rajeev79dbe4c2013-10-05 11:03:42 +0530907 if ( (NULL == inPtr) || (TRUE == lastArg))
908 {
909 return -EINVAL;
910 }
911 }
912
913 /*check and parse MSCAN*/
914 if ((strncmp(inPtr, "MSCAN", 5) == 0))
915 {
916 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800917 &nMscan, &lastArg);
918
919 if (0 == nMscan)
920 {
921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
922 "invalid MSCAN=%d", nMscan);
923 return -EINVAL;
924 }
925
Rajeev79dbe4c2013-10-05 11:03:42 +0530926 if (TRUE == lastArg)
927 {
928 goto done;
929 }
930 else if (NULL == inPtr)
931 {
932 return -EINVAL;
933 }
934 }
935 else
936 {
937 return -EINVAL;
938 }
939
940 /*check and parse BESTN*/
941 if ((strncmp(inPtr, "BESTN", 5) == 0))
942 {
943 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800944 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800945
Rajeev Kumarc933d982013-11-18 20:04:20 -0800946 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800947 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800948 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800949 }
950
Rajeev79dbe4c2013-10-05 11:03:42 +0530951 if (TRUE == lastArg)
952 {
953 goto done;
954 }
955 else if (NULL == inPtr)
956 {
957 return -EINVAL;
958 }
959 }
960
961 /*check and parse CHANNEL*/
962 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
963 {
964 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800965
Rajeev79dbe4c2013-10-05 11:03:42 +0530966 if (('A' == val) || ('a' == val))
967 {
c_hpothuebf89732014-02-25 13:00:24 +0530968 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530969 }
970 else if (('B' == val) || ('b' == val))
971 {
c_hpothuebf89732014-02-25 13:00:24 +0530972 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530973 }
974 else
975 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800976 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
977 }
978
979 if (TRUE == lastArg)
980 {
981 goto done;
982 }
983 else if (NULL == inPtr)
984 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530985 return -EINVAL;
986 }
987 }
988
989 /*check and parse RTT*/
990 if ((strncmp(inPtr, "RTT", 3) == 0))
991 {
992 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800993 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530994 if (TRUE == lastArg)
995 {
996 goto done;
997 }
998 if (NULL == inPtr)
999 {
1000 return -EINVAL;
1001 }
1002 }
1003
1004
1005done:
1006
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001007 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1008 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1009 pHddSetBatchScanReq->bestNetwork = nBestN;
1010 pHddSetBatchScanReq->rfBand = ucRfBand;
1011 pHddSetBatchScanReq->rtt = nRtt;
1012
Rajeev79dbe4c2013-10-05 11:03:42 +05301013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1014 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1015 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1016 pHddSetBatchScanReq->scanFrequency,
1017 pHddSetBatchScanReq->numberOfScansToBatch,
1018 pHddSetBatchScanReq->bestNetwork,
1019 pHddSetBatchScanReq->rfBand,
1020 pHddSetBatchScanReq->rtt);
1021
1022 return 0;
1023}/*End of hdd_parse_set_batchscan_command*/
1024
1025/**---------------------------------------------------------------------------
1026
1027 \brief hdd_set_batch_scan_req_callback () - This function is called after
1028 receiving set batch scan response from FW and it saves set batch scan
1029 response data FW to HDD context and sets the completion event on
1030 which hdd_ioctl is waiting
1031
1032 \param - callbackContext Pointer to HDD adapter
1033 \param - pRsp Pointer to set batch scan response data received from FW
1034
1035 \return - nothing
1036
1037 --------------------------------------------------------------------------*/
1038static void hdd_set_batch_scan_req_callback
1039(
1040 void *callbackContext,
1041 tSirSetBatchScanRsp *pRsp
1042)
1043{
1044 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1045 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1046
1047 /*sanity check*/
1048 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1049 {
1050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1051 "%s: Invalid pAdapter magic", __func__);
1052 VOS_ASSERT(0);
1053 return;
1054 }
1055 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1056
1057 /*save set batch scan response*/
1058 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1059
1060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1061 "Received set batch scan rsp from FW with nScansToBatch=%d",
1062 pHddSetBatchScanRsp->nScansToBatch);
1063
1064 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1065 complete(&pAdapter->hdd_set_batch_scan_req_var);
1066
1067 return;
1068}/*End of hdd_set_batch_scan_req_callback*/
1069
1070
1071/**---------------------------------------------------------------------------
1072
1073 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1074 info in hdd batch scan response queue
1075
1076 \param - pAdapter Pointer to hdd adapter
1077 \param - pAPMetaInfo Pointer to access point meta info
1078 \param - scanId scan ID of batch scan response
1079 \param - isLastAp tells whether AP is last AP in batch scan response or not
1080
1081 \return - nothing
1082
1083 --------------------------------------------------------------------------*/
1084static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1085 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1086{
1087 tHddBatchScanRsp *pHead;
1088 tHddBatchScanRsp *pNode;
1089 tHddBatchScanRsp *pPrev;
1090 tHddBatchScanRsp *pTemp;
1091 tANI_U8 ssidLen;
1092
1093 /*head of hdd batch scan response queue*/
1094 pHead = pAdapter->pBatchScanRsp;
1095
1096 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1097 if (NULL == pNode)
1098 {
1099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1100 "%s: Could not allocate memory", __func__);
1101 VOS_ASSERT(0);
1102 return;
1103 }
1104
1105 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1106 sizeof(pNode->ApInfo.bssid));
1107 ssidLen = strlen(pApMetaInfo->ssid);
1108 if (SIR_MAX_SSID_SIZE < ssidLen)
1109 {
1110 /*invalid scan result*/
1111 vos_mem_free(pNode);
1112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1113 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1114 return;
1115 }
1116 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1117 /*null terminate ssid*/
1118 pNode->ApInfo.ssid[ssidLen] = '\0';
1119 pNode->ApInfo.ch = pApMetaInfo->ch;
1120 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1121 pNode->ApInfo.age = pApMetaInfo->timestamp;
1122 pNode->ApInfo.batchId = scanId;
1123 pNode->ApInfo.isLastAp = isLastAp;
1124
1125 pNode->pNext = NULL;
1126 if (NULL == pHead)
1127 {
1128 pAdapter->pBatchScanRsp = pNode;
1129 }
1130 else
1131 {
1132 pTemp = pHead;
1133 while (NULL != pTemp)
1134 {
1135 pPrev = pTemp;
1136 pTemp = pTemp->pNext;
1137 }
1138 pPrev->pNext = pNode;
1139 }
1140
1141 return;
1142}/*End of hdd_populate_batch_scan_rsp_queue*/
1143
1144/**---------------------------------------------------------------------------
1145
1146 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1147 receiving batch scan response indication from FW. It saves get batch scan
1148 response data in HDD batch scan response queue. This callback sets the
1149 completion event on which hdd_ioctl is waiting only after getting complete
1150 batch scan response data from FW
1151
1152 \param - callbackContext Pointer to HDD adapter
1153 \param - pRsp Pointer to get batch scan response data received from FW
1154
1155 \return - nothing
1156
1157 --------------------------------------------------------------------------*/
1158static void hdd_batch_scan_result_ind_callback
1159(
1160 void *callbackContext,
1161 void *pRsp
1162)
1163{
1164 v_BOOL_t isLastAp;
1165 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001166 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301167 tANI_U32 numberScanList;
1168 tANI_U32 nextScanListOffset;
1169 tANI_U32 nextApMetaInfoOffset;
1170 hdd_adapter_t* pAdapter;
1171 tpSirBatchScanList pScanList;
1172 tpSirBatchScanNetworkInfo pApMetaInfo;
1173 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1174 tSirSetBatchScanReq *pReq;
1175
1176 pAdapter = (hdd_adapter_t *)callbackContext;
1177 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001178 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301179 {
1180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1181 "%s: Invalid pAdapter magic", __func__);
1182 VOS_ASSERT(0);
1183 return;
1184 }
1185
1186 /*initialize locals*/
1187 pReq = &pAdapter->hddSetBatchScanReq;
1188 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1189 isLastAp = FALSE;
1190 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001191 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301192 numberScanList = 0;
1193 nextScanListOffset = 0;
1194 nextApMetaInfoOffset = 0;
1195 pScanList = NULL;
1196 pApMetaInfo = NULL;
1197
1198 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1199 {
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1202 isLastAp = TRUE;
1203 goto done;
1204 }
1205
1206 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1208 "Batch scan rsp: numberScalList %d", numberScanList);
1209
1210 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1211 {
1212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1213 "%s: numberScanList %d", __func__, numberScanList);
1214 isLastAp = TRUE;
1215 goto done;
1216 }
1217
1218 while (numberScanList)
1219 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001220 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301221 nextScanListOffset);
1222 if (NULL == pScanList)
1223 {
1224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1225 "%s: pScanList is %p", __func__, pScanList);
1226 isLastAp = TRUE;
1227 goto done;
1228 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001229 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001231 "Batch scan rsp: numApMetaInfo %d scanId %d",
1232 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301233
1234 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1235 {
1236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1237 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1238 isLastAp = TRUE;
1239 goto done;
1240 }
1241
Rajeev Kumarce651e42013-10-21 18:57:15 -07001242 /*Initialize next AP meta info offset for next scan list*/
1243 nextApMetaInfoOffset = 0;
1244
Rajeev79dbe4c2013-10-05 11:03:42 +05301245 while (numApMetaInfo)
1246 {
1247 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1248 nextApMetaInfoOffset);
1249 if (NULL == pApMetaInfo)
1250 {
1251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1252 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1253 isLastAp = TRUE;
1254 goto done;
1255 }
1256 /*calculate AP age*/
1257 pApMetaInfo->timestamp =
1258 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1259
1260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001261 "%s: bssId "MAC_ADDRESS_STR
1262 " ch %d rssi %d timestamp %d", __func__,
1263 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1264 pApMetaInfo->ch, pApMetaInfo->rssi,
1265 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301266
1267 /*mark last AP in batch scan response*/
1268 if ((TRUE == pBatchScanRsp->isLastResult) &&
1269 (1 == numberScanList) && (1 == numApMetaInfo))
1270 {
1271 isLastAp = TRUE;
1272 }
1273
1274 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1275 /*store batch scan repsonse in hdd queue*/
1276 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1277 pScanList->scanId, isLastAp);
1278 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1279
1280 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1281 numApMetaInfo--;
1282 }
1283
Rajeev Kumarce651e42013-10-21 18:57:15 -07001284 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1285 + (sizeof(tSirBatchScanNetworkInfo)
1286 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301287 numberScanList--;
1288 }
1289
1290done:
1291
1292 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1293 requested from hdd_ioctl*/
1294 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1295 (TRUE == isLastAp))
1296 {
1297 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1298 complete(&pAdapter->hdd_get_batch_scan_req_var);
1299 }
1300
1301 return;
1302}/*End of hdd_batch_scan_result_ind_callback*/
1303
1304/**---------------------------------------------------------------------------
1305
1306 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1307 response as per batch scan FR request format by putting proper markers
1308
1309 \param - pDest pointer to destination buffer
1310 \param - cur_len current length
1311 \param - tot_len total remaining size which can be written to user space
1312 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1313 \param - pAdapter Pointer to HDD adapter
1314
1315 \return - ret no of characters written
1316
1317 --------------------------------------------------------------------------*/
1318static tANI_U32
1319hdd_format_batch_scan_rsp
1320(
1321 tANI_U8 *pDest,
1322 tANI_U32 cur_len,
1323 tANI_U32 tot_len,
1324 tHddBatchScanRsp *pApMetaInfo,
1325 hdd_adapter_t* pAdapter
1326)
1327{
1328 tANI_U32 ret = 0;
1329 tANI_U32 rem_len = 0;
1330 tANI_U8 temp_len = 0;
1331 tANI_U8 temp_total_len = 0;
1332 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1333 tANI_U8 *pTemp = temp;
1334
1335 /*Batch scan reponse needs to be returned to user space in
1336 following format:
1337 "scancount=X\n" where X is the number of scans in current batch
1338 batch
1339 "trunc\n" optional present if current scan truncated
1340 "bssid=XX:XX:XX:XX:XX:XX\n"
1341 "ssid=XXXX\n"
1342 "freq=X\n" frequency in Mhz
1343 "level=XX\n"
1344 "age=X\n" ms
1345 "dist=X\n" cm (-1 if not available)
1346 "errror=X\n" (-1if not available)
1347 "====\n" (end of ap marker)
1348 "####\n" (end of scan marker)
1349 "----\n" (end of results)*/
1350 /*send scan result in above format to user space based on
1351 available length*/
1352 /*The GET response may have more data than the driver can return in its
1353 buffer. In that case the buffer should be filled to the nearest complete
1354 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1355 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1356 The final buffer should end with "----\n"*/
1357
1358 /*sanity*/
1359 if (cur_len > tot_len)
1360 {
1361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1362 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1363 return 0;
1364 }
1365 else
1366 {
1367 rem_len = (tot_len - cur_len);
1368 }
1369
1370 /*end scan marker*/
1371 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1372 {
1373 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1374 pTemp += temp_len;
1375 temp_total_len += temp_len;
1376 }
1377
1378 /*bssid*/
1379 temp_len = snprintf(pTemp, sizeof(temp),
1380 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1381 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1382 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1383 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1384 pTemp += temp_len;
1385 temp_total_len += temp_len;
1386
1387 /*ssid*/
1388 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1389 pApMetaInfo->ApInfo.ssid);
1390 pTemp += temp_len;
1391 temp_total_len += temp_len;
1392
1393 /*freq*/
1394 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001395 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301396 pTemp += temp_len;
1397 temp_total_len += temp_len;
1398
1399 /*level*/
1400 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1401 pApMetaInfo->ApInfo.rssi);
1402 pTemp += temp_len;
1403 temp_total_len += temp_len;
1404
1405 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001406 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301407 pApMetaInfo->ApInfo.age);
1408 pTemp += temp_len;
1409 temp_total_len += temp_len;
1410
1411 /*dist*/
1412 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1413 pTemp += temp_len;
1414 temp_total_len += temp_len;
1415
1416 /*error*/
1417 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1418 pTemp += temp_len;
1419 temp_total_len += temp_len;
1420
1421 /*end AP marker*/
1422 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1423 pTemp += temp_len;
1424 temp_total_len += temp_len;
1425
1426 /*last AP in batch scan response*/
1427 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1428 {
1429 /*end scan marker*/
1430 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1431 pTemp += temp_len;
1432 temp_total_len += temp_len;
1433
1434 /*end batch scan result marker*/
1435 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1436 pTemp += temp_len;
1437 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001438
Rajeev79dbe4c2013-10-05 11:03:42 +05301439 }
1440
1441 if (temp_total_len < rem_len)
1442 {
1443 ret = temp_total_len + 1;
1444 strlcpy(pDest, temp, ret);
1445 pAdapter->isTruncated = FALSE;
1446 }
1447 else
1448 {
1449 pAdapter->isTruncated = TRUE;
1450 if (rem_len >= strlen("%%%%"))
1451 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001452 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301453 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001454 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301455 {
1456 ret = 0;
1457 }
1458 }
1459
1460 return ret;
1461
1462}/*End of hdd_format_batch_scan_rsp*/
1463
1464/**---------------------------------------------------------------------------
1465
1466 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1467 buffer starting with head of hdd batch scan response queue
1468
1469 \param - pAdapter Pointer to HDD adapter
1470 \param - pDest Pointer to user data buffer
1471 \param - cur_len current offset in user buffer
1472 \param - rem_len remaining no of bytes in user buffer
1473
1474 \return - number of bytes written in user buffer
1475
1476 --------------------------------------------------------------------------*/
1477
1478tANI_U32 hdd_populate_user_batch_scan_rsp
1479(
1480 hdd_adapter_t* pAdapter,
1481 tANI_U8 *pDest,
1482 tANI_U32 cur_len,
1483 tANI_U32 rem_len
1484)
1485{
1486 tHddBatchScanRsp *pHead;
1487 tHddBatchScanRsp *pPrev;
1488 tANI_U32 len;
1489
Rajeev79dbe4c2013-10-05 11:03:42 +05301490 pAdapter->isTruncated = FALSE;
1491
1492 /*head of hdd batch scan response queue*/
1493 pHead = pAdapter->pBatchScanRsp;
1494 while (pHead)
1495 {
1496 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1497 pAdapter);
1498 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001499 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301500 cur_len += len;
1501 if(TRUE == pAdapter->isTruncated)
1502 {
1503 /*result is truncated return rest of scan rsp in next req*/
1504 cur_len = rem_len;
1505 break;
1506 }
1507 pPrev = pHead;
1508 pHead = pHead->pNext;
1509 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001510 if (TRUE == pPrev->ApInfo.isLastAp)
1511 {
1512 pAdapter->prev_batch_id = 0;
1513 }
1514 else
1515 {
1516 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1517 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301518 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001519 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301520 }
1521
1522 return cur_len;
1523}/*End of hdd_populate_user_batch_scan_rsp*/
1524
1525/**---------------------------------------------------------------------------
1526
1527 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1528 scan response data from HDD queue to user space
1529 It does following in detail:
1530 a) if HDD has enough data in its queue then it 1st copies data to user
1531 space and then send get batch scan indication message to FW. In this
1532 case it does not wait on any event and batch scan response data will
1533 be populated in HDD response queue in MC thread context after receiving
1534 indication from FW
1535 b) else send get batch scan indication message to FW and wait on an event
1536 which will be set once HDD receives complete batch scan response from
1537 FW and then this function returns batch scan response to user space
1538
1539 \param - pAdapter Pointer to HDD adapter
1540 \param - pPrivData Pointer to priv_data
1541
1542 \return - 0 for success -EFAULT for failure
1543
1544 --------------------------------------------------------------------------*/
1545
1546int hdd_return_batch_scan_rsp_to_user
1547(
1548 hdd_adapter_t* pAdapter,
1549 hdd_priv_data_t *pPrivData,
1550 tANI_U8 *command
1551)
1552{
1553 tANI_U8 *pDest;
1554 tANI_U32 count = 0;
1555 tANI_U32 len = 0;
1556 tANI_U32 cur_len = 0;
1557 tANI_U32 rem_len = 0;
1558 eHalStatus halStatus;
1559 unsigned long rc;
1560 tSirTriggerBatchScanResultInd *pReq;
1561
1562 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1563 pReq->param = 0;/*batch scan client*/
1564 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1565 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1566
1567 cur_len = pPrivData->used_len;
1568 if (pPrivData->total_len > pPrivData->used_len)
1569 {
1570 rem_len = pPrivData->total_len - pPrivData->used_len;
1571 }
1572 else
1573 {
1574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1575 "%s: Invalid user data buffer total_len %d used_len %d",
1576 __func__, pPrivData->total_len, pPrivData->used_len);
1577 return -EFAULT;
1578 }
1579
1580 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1581 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1582 cur_len, rem_len);
1583 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1584
1585 /*enough scan result available in cache to return to user space or
1586 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001587 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301588 {
1589 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1590 halStatus = sme_TriggerBatchScanResultInd(
1591 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1592 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1593 pAdapter);
1594 if ( eHAL_STATUS_SUCCESS == halStatus )
1595 {
1596 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1597 {
1598 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1599 rc = wait_for_completion_timeout(
1600 &pAdapter->hdd_get_batch_scan_req_var,
1601 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1602 if (0 == rc)
1603 {
1604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1605 "%s: Timeout waiting to fetch batch scan rsp from fw",
1606 __func__);
1607 return -EFAULT;
1608 }
1609 }
1610
1611 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001612 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301613 pDest += len;
1614 cur_len += len;
1615
1616 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1617 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1618 cur_len, rem_len);
1619 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1620
1621 count = 0;
1622 len = (len - pPrivData->used_len);
1623 pDest = (command + pPrivData->used_len);
1624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001625 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301626 while(count < len)
1627 {
1628 printk("%c", *(pDest + count));
1629 count++;
1630 }
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1632 "%s: copy %d data to user buffer", __func__, len);
1633 if (copy_to_user(pPrivData->buf, pDest, len))
1634 {
1635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "%s: failed to copy data to user buffer", __func__);
1637 return -EFAULT;
1638 }
1639 }
1640 else
1641 {
1642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1643 "sme_GetBatchScanScan returned failure halStatus %d",
1644 halStatus);
1645 return -EINVAL;
1646 }
1647 }
1648 else
1649 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301650 count = 0;
1651 len = (len - pPrivData->used_len);
1652 pDest = (command + pPrivData->used_len);
1653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001654 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301655 while(count < len)
1656 {
1657 printk("%c", *(pDest + count));
1658 count++;
1659 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1661 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301662 if (copy_to_user(pPrivData->buf, pDest, len))
1663 {
1664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1665 "%s: failed to copy data to user buffer", __func__);
1666 return -EFAULT;
1667 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301668 }
1669
1670 return 0;
1671} /*End of hdd_return_batch_scan_rsp_to_user*/
1672
Rajeev Kumar8b373292014-01-08 20:36:55 -08001673
1674/**---------------------------------------------------------------------------
1675
1676 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1677 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1678 WLS_BATCHING VERSION
1679 WLS_BATCHING SET
1680 WLS_BATCHING GET
1681 WLS_BATCHING STOP
1682
1683 \param - pAdapter Pointer to HDD adapter
1684 \param - pPrivdata Pointer to priv_data
1685 \param - command Pointer to command
1686
1687 \return - 0 for success -EFAULT for failure
1688
1689 --------------------------------------------------------------------------*/
1690
1691int hdd_handle_batch_scan_ioctl
1692(
1693 hdd_adapter_t *pAdapter,
1694 hdd_priv_data_t *pPrivdata,
1695 tANI_U8 *command
1696)
1697{
1698 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001699 hdd_context_t *pHddCtx;
1700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301701 ENTER();
1702
Yue Mae36e3552014-03-05 17:06:20 -08001703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1704 ret = wlan_hdd_validate_context(pHddCtx);
1705 if (ret)
1706 {
Yue Mae36e3552014-03-05 17:06:20 -08001707 goto exit;
1708 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001709
1710 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1711 {
1712 char extra[32];
1713 tANI_U8 len = 0;
1714 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1715
1716 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1717 {
1718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1719 "%s: Batch scan feature is not supported by FW", __func__);
1720 ret = -EINVAL;
1721 goto exit;
1722 }
1723
1724 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1725 version);
1726 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1727 {
1728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1729 "%s: failed to copy data to user buffer", __func__);
1730 ret = -EFAULT;
1731 goto exit;
1732 }
1733 ret = HDD_BATCH_SCAN_VERSION;
1734 }
1735 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1736 {
1737 int status;
1738 tANI_U8 *value = (command + 16);
1739 eHalStatus halStatus;
1740 unsigned long rc;
1741 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1742 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1743
1744 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1745 {
1746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1747 "%s: Batch scan feature is not supported by FW", __func__);
1748 ret = -EINVAL;
1749 goto exit;
1750 }
1751
1752 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1753 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1754 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1755 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1756 {
1757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301758 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001759 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301760 hdd_device_modetoString(pAdapter->device_mode),
1761 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001762 ret = -EINVAL;
1763 goto exit;
1764 }
1765
1766 status = hdd_parse_set_batchscan_command(value, pReq);
1767 if (status)
1768 {
1769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1770 "Invalid WLS_BATCHING SET command");
1771 ret = -EINVAL;
1772 goto exit;
1773 }
1774
1775
1776 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1777 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1778 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1779 pAdapter);
1780
1781 if ( eHAL_STATUS_SUCCESS == halStatus )
1782 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301783 char extra[32];
1784 tANI_U8 len = 0;
1785 tANI_U8 mScan = 0;
1786
Rajeev Kumar8b373292014-01-08 20:36:55 -08001787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1788 "sme_SetBatchScanReq returned success halStatus %d",
1789 halStatus);
1790 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1791 {
1792 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1793 rc = wait_for_completion_timeout(
1794 &pAdapter->hdd_set_batch_scan_req_var,
1795 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1796 if (0 == rc)
1797 {
1798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1799 "%s: Timeout waiting for set batch scan to complete",
1800 __func__);
1801 ret = -EINVAL;
1802 goto exit;
1803 }
1804 }
1805 if ( !pRsp->nScansToBatch )
1806 {
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1808 "%s: Received set batch scan failure response from FW",
1809 __func__);
1810 ret = -EINVAL;
1811 goto exit;
1812 }
1813 /*As per the Batch Scan Framework API we should return the MIN of
1814 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301815 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001816
1817 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1818
1819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301821 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1822 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1823 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1824 {
1825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "%s: failed to copy MSCAN value to user buffer", __func__);
1827 ret = -EFAULT;
1828 goto exit;
1829 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001830 }
1831 else
1832 {
1833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1834 "sme_SetBatchScanReq returned failure halStatus %d",
1835 halStatus);
1836 ret = -EINVAL;
1837 goto exit;
1838 }
1839 }
1840 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1841 {
1842 eHalStatus halStatus;
1843 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1844 pInd->param = 0;
1845
1846 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1847 {
1848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 "%s: Batch scan feature is not supported by FW", __func__);
1850 ret = -EINVAL;
1851 goto exit;
1852 }
1853
1854 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1855 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001857 "Batch scan is not yet enabled batch scan state %d",
1858 pAdapter->batchScanState);
1859 ret = -EINVAL;
1860 goto exit;
1861 }
1862
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001863 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1864 hdd_deinit_batch_scan(pAdapter);
1865 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1866
Rajeev Kumar8b373292014-01-08 20:36:55 -08001867 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1868
1869 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1870 pAdapter->sessionId);
1871 if ( eHAL_STATUS_SUCCESS == halStatus )
1872 {
1873 ret = 0;
1874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1875 "sme_StopBatchScanInd returned success halStatus %d",
1876 halStatus);
1877 }
1878 else
1879 {
1880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1881 "sme_StopBatchScanInd returned failure halStatus %d",
1882 halStatus);
1883 ret = -EINVAL;
1884 goto exit;
1885 }
1886 }
1887 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1888 {
1889 tANI_U32 remain_len;
1890
1891 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1892 {
1893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1894 "%s: Batch scan feature is not supported by FW", __func__);
1895 ret = -EINVAL;
1896 goto exit;
1897 }
1898
1899 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1900 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001902 "Batch scan is not yet enabled could not return results"
1903 "Batch Scan state %d",
1904 pAdapter->batchScanState);
1905 ret = -EINVAL;
1906 goto exit;
1907 }
1908
1909 pPrivdata->used_len = 16;
1910 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1911 if (remain_len < pPrivdata->total_len)
1912 {
1913 /*Clear previous batch scan response data if any*/
1914 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1915 }
1916 else
1917 {
1918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1919 "Invalid total length from user space can't fetch batch"
1920 " scan response total_len %d used_len %d remain len %d",
1921 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1922 ret = -EINVAL;
1923 goto exit;
1924 }
1925 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1926 }
1927
1928exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301929 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001930 return ret;
1931}
1932
1933
Rajeev79dbe4c2013-10-05 11:03:42 +05301934#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1935
c_hpothu92367912014-05-01 15:18:17 +05301936static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1937{
c_hpothu39eb1e32014-06-26 16:31:50 +05301938 bcnMissRateContext_t *pCBCtx;
1939
1940 if (NULL == data)
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1943 return;
1944 }
c_hpothu92367912014-05-01 15:18:17 +05301945
1946 /* there is a race condition that exists between this callback
1947 function and the caller since the caller could time out either
1948 before or while this code is executing. we use a spinlock to
1949 serialize these actions */
1950 spin_lock(&hdd_context_lock);
1951
c_hpothu39eb1e32014-06-26 16:31:50 +05301952 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301953 gbcnMissRate = -1;
1954
c_hpothu39eb1e32014-06-26 16:31:50 +05301955 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301956 {
1957 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301958 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301959 spin_unlock(&hdd_context_lock);
1960 return ;
1961 }
1962
1963 if (VOS_STATUS_SUCCESS == status)
1964 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301965 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301966 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301967 else
1968 {
1969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1970 }
1971
c_hpothu92367912014-05-01 15:18:17 +05301972 complete(&(pCBCtx->completion));
1973 spin_unlock(&hdd_context_lock);
1974
1975 return;
1976}
1977
Abhishek Singh08aa7762014-12-16 13:59:03 +05301978void hdd_FWStatisCB( VOS_STATUS status,
1979 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301980{
1981 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301982 hdd_adapter_t *pAdapter;
1983
1984 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1985
Abhishek Singh08aa7762014-12-16 13:59:03 +05301986 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301987 {
1988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1989 return;
1990 }
1991 /* there is a race condition that exists between this callback
1992 function and the caller since the caller could time out either
1993 before or while this code is executing. we use a spinlock to
1994 serialize these actions */
1995 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301996 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301997 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1998 {
1999 hddLog(VOS_TRACE_LEVEL_ERROR,
2000 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2001 spin_unlock(&hdd_context_lock);
2002 return;
2003 }
2004 pAdapter = fwStatsCtx->pAdapter;
2005 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2006 {
2007 hddLog(VOS_TRACE_LEVEL_ERROR,
2008 FL("pAdapter returned is NULL or invalid"));
2009 spin_unlock(&hdd_context_lock);
2010 return;
2011 }
2012 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302013 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302014 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302015 switch( fwStatsResult->type )
2016 {
2017 case FW_UBSP_STATS:
2018 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302019 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302020 hddLog(VOS_TRACE_LEVEL_INFO,
2021 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302022 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2023 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302024 }
2025 break;
2026 default:
2027 {
2028 hddLog(VOS_TRACE_LEVEL_ERROR,
2029 FL(" No handling for stats type %d"),fwStatsResult->type);
2030 }
2031 }
2032 }
2033 complete(&(fwStatsCtx->completion));
2034 spin_unlock(&hdd_context_lock);
2035 return;
2036}
2037
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302038static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2039{
2040 int ret = 0;
2041
2042 if (!pCfg || !command || !extra || !len)
2043 {
2044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2045 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2046 ret = -EINVAL;
2047 return ret;
2048 }
2049
2050 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2051 {
2052 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2053 (int)pCfg->nActiveMaxChnTime);
2054 return ret;
2055 }
2056 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2057 {
2058 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2059 (int)pCfg->nActiveMinChnTime);
2060 return ret;
2061 }
2062 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2063 {
2064 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2065 (int)pCfg->nPassiveMaxChnTime);
2066 return ret;
2067 }
2068 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2069 {
2070 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2071 (int)pCfg->nPassiveMinChnTime);
2072 return ret;
2073 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302074 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2075 {
2076 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2077 (int)pCfg->nActiveMaxChnTime);
2078 return ret;
2079 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302080 else
2081 {
2082 ret = -EINVAL;
2083 }
2084
2085 return ret;
2086}
2087
2088static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2089{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302090 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302091 hdd_config_t *pCfg;
2092 tANI_U8 *value = command;
2093 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302094 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302095
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302096 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2097 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302098 {
2099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2100 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2101 ret = -EINVAL;
2102 return ret;
2103 }
2104
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302105 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2106 sme_GetConfigParam(hHal, &smeConfig);
2107
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302108 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2109 {
2110 value = value + 24;
2111 temp = kstrtou32(value, 10, &val);
2112 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2113 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2114 {
2115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2116 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2117 ret = -EFAULT;
2118 return ret;
2119 }
2120 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302121 smeConfig.csrConfig.nActiveMaxChnTime = val;
2122 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302123 }
2124 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2125 {
2126 value = value + 24;
2127 temp = kstrtou32(value, 10, &val);
2128 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2129 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2130 {
2131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2132 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2133 ret = -EFAULT;
2134 return ret;
2135 }
2136 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302137 smeConfig.csrConfig.nActiveMinChnTime = val;
2138 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302139 }
2140 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2141 {
2142 value = value + 25;
2143 temp = kstrtou32(value, 10, &val);
2144 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2145 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2146 {
2147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2148 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2149 ret = -EFAULT;
2150 return ret;
2151 }
2152 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302153 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2154 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302155 }
2156 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2157 {
2158 value = value + 25;
2159 temp = kstrtou32(value, 10, &val);
2160 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2161 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2162 {
2163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2164 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2165 ret = -EFAULT;
2166 return ret;
2167 }
2168 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302169 smeConfig.csrConfig.nPassiveMinChnTime = val;
2170 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302171 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302172 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2173 {
2174 value = value + 13;
2175 temp = kstrtou32(value, 10, &val);
2176 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2177 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2178 {
2179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2180 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2181 ret = -EFAULT;
2182 return ret;
2183 }
2184 pCfg->nActiveMaxChnTime = val;
2185 smeConfig.csrConfig.nActiveMaxChnTime = val;
2186 sme_UpdateConfig(hHal, &smeConfig);
2187 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302188 else
2189 {
2190 ret = -EINVAL;
2191 }
2192
2193 return ret;
2194}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302195static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2196 tANI_U8 cmd_len)
2197{
2198 tANI_U8 *value;
2199 tANI_U8 fcc_constraint;
2200
2201 eHalStatus status;
2202 int ret = 0;
2203 value = cmd + cmd_len + 1;
2204
2205 ret = kstrtou8(value, 10, &fcc_constraint);
2206 if ((ret < 0) || (fcc_constraint > 1)) {
2207 /*
2208 * If the input value is greater than max value of datatype,
2209 * then also it is a failure
2210 */
2211 hddLog(VOS_TRACE_LEVEL_ERROR,
2212 "%s: value out of range", __func__);
2213 return -EINVAL;
2214 }
2215
2216 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2217 if (status != eHAL_STATUS_SUCCESS)
2218 ret = -EPERM;
2219
2220 return ret;
2221}
2222
2223
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302224
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002225static int hdd_driver_command(hdd_adapter_t *pAdapter,
2226 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002227{
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 hdd_priv_data_t priv_data;
2229 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302230 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2231 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002232 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302233 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302234
2235 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002236 /*
2237 * Note that valid pointers are provided by caller
2238 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002239
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002240 /* copy to local struct to avoid numerous changes to legacy code */
2241 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002242
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002243 if (priv_data.total_len <= 0 ||
2244 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002245 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002246 hddLog(VOS_TRACE_LEVEL_WARN,
2247 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2248 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002249 ret = -EINVAL;
2250 goto exit;
2251 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302252 status = wlan_hdd_validate_context(pHddCtx);
2253 if (0 != status)
2254 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302255 ret = -EINVAL;
2256 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302257 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002258 /* Allocate +1 for '\0' */
2259 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 if (!command)
2261 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002262 hddLog(VOS_TRACE_LEVEL_ERROR,
2263 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002264 ret = -ENOMEM;
2265 goto exit;
2266 }
2267
2268 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2269 {
2270 ret = -EFAULT;
2271 goto exit;
2272 }
2273
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002274 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002275 command[priv_data.total_len] = '\0';
2276
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002277 /* at one time the following block of code was conditional. braces
2278 * have been retained to avoid re-indenting the legacy code
2279 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002280 {
2281 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2282
2283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002284 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002285
2286 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2287 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302288 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2289 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2290 pAdapter->sessionId, (unsigned)
2291 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2292 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2293 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2294 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002295 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2296 sizeof(tSirMacAddr)))
2297 {
2298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002299 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002300 ret = -EFAULT;
2301 }
2302 }
Amar Singhal0974e402013-02-12 14:27:46 -08002303 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002304 {
Amar Singhal0974e402013-02-12 14:27:46 -08002305 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002306
Jeff Johnson295189b2012-06-20 16:38:30 -07002307 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002308
2309 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002312 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Anand N Sunkad27354cf2015-07-13 14:39:11 +05302313 if(VOS_FTM_MODE != hdd_get_conparam())
2314 {
2315 /* Change band request received */
2316 ret = hdd_setBand_helper(pAdapter->dev, ptr);
2317 if(ret < 0)
2318 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2319 "%s: failed to set band ret=%d", __func__, ret);
2320 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002321 }
Kiet Lamf040f472013-11-20 21:15:23 +05302322 else if(strncmp(command, "SETWMMPS", 8) == 0)
2323 {
2324 tANI_U8 *ptr = command;
2325 ret = hdd_wmmps_helper(pAdapter, ptr);
2326 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302327
2328 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2329 {
2330 tANI_U8 *ptr = command;
2331 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2332 }
2333
Jeff Johnson32d95a32012-09-10 13:15:23 -07002334 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2335 {
2336 char *country_code;
2337
2338 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002339
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002340 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002341 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002342#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302343 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002344#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002345 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2346 (void *)(tSmeChangeCountryCallback)
2347 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302348 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002349 if (eHAL_STATUS_SUCCESS == ret)
2350 {
2351 ret = wait_for_completion_interruptible_timeout(
2352 &pAdapter->change_country_code,
2353 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2354 if (0 >= ret)
2355 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302357 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002358 }
2359 }
2360 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002361 {
2362 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002363 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002364 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002365 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002366
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002367 }
2368 /*
2369 command should be a string having format
2370 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2371 */
Amar Singhal0974e402013-02-12 14:27:46 -08002372 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002373 {
Amar Singhal0974e402013-02-12 14:27:46 -08002374 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002375
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002377 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002378
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002379 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002380 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002381 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2382 {
2383 int suspend = 0;
2384 tANI_U8 *ptr = (tANI_U8*)command + 15;
2385
2386 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302387 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2388 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2389 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002390 hdd_set_wlan_suspend_mode(suspend);
2391 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002392#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2393 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2394 {
2395 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002396 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002397 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2398 eHalStatus status = eHAL_STATUS_SUCCESS;
2399
2400 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2401 value = value + 15;
2402
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002403 /* Convert the value from ascii to integer */
2404 ret = kstrtos8(value, 10, &rssi);
2405 if (ret < 0)
2406 {
2407 /* If the input value is greater than max value of datatype, then also
2408 kstrtou8 fails */
2409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2410 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002411 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002412 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2413 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2414 ret = -EINVAL;
2415 goto exit;
2416 }
2417
Srinivas Girigowdade697412013-02-14 16:31:48 -08002418 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002419
Srinivas Girigowdade697412013-02-14 16:31:48 -08002420 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2421 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2422 {
2423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2424 "Neighbor lookup threshold value %d is out of range"
2425 " (Min: %d Max: %d)", lookUpThreshold,
2426 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2427 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2428 ret = -EINVAL;
2429 goto exit;
2430 }
2431
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302432 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2433 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2434 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2436 "%s: Received Command to Set Roam trigger"
2437 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2438
2439 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2440 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2441 if (eHAL_STATUS_SUCCESS != status)
2442 {
2443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2444 "%s: Failed to set roam trigger, try again", __func__);
2445 ret = -EPERM;
2446 goto exit;
2447 }
2448
2449 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302450 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002451 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2452 }
2453 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2454 {
2455 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2456 int rssi = (-1) * lookUpThreshold;
2457 char extra[32];
2458 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2460 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2461 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002462 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05302463 len = VOS_MIN(priv_data.total_len, len + 1);
2464 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002465 {
2466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2467 "%s: failed to copy data to user buffer", __func__);
2468 ret = -EFAULT;
2469 goto exit;
2470 }
2471 }
2472 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2473 {
2474 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002475 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002476 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002477
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478 /* input refresh period is in terms of seconds */
2479 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2480 value = value + 18;
2481 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002482 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002483 if (ret < 0)
2484 {
2485 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002486 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002488 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002489 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002490 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2491 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002492 ret = -EINVAL;
2493 goto exit;
2494 }
2495
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2497 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002498 {
2499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002500 "Roam scan period value %d is out of range"
2501 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002502 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2503 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002504 ret = -EINVAL;
2505 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302506 }
2507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2508 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2509 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002510 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002511
2512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2513 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002514 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002515
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002516 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2517 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002518 }
2519 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2520 {
2521 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2522 char extra[32];
2523 tANI_U8 len = 0;
2524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2526 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2527 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002528 len = scnprintf(extra, sizeof(extra), "%s %d",
2529 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002530 /* Returned value is in units of seconds */
2531 if (copy_to_user(priv_data.buf, &extra, len + 1))
2532 {
2533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2534 "%s: failed to copy data to user buffer", __func__);
2535 ret = -EFAULT;
2536 goto exit;
2537 }
2538 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002539 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2540 {
2541 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002542 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002543 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002544
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002545 /* input refresh period is in terms of seconds */
2546 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2547 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002548
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002549 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002550 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002551 if (ret < 0)
2552 {
2553 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002554 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002556 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002557 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002558 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2559 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2560 ret = -EINVAL;
2561 goto exit;
2562 }
2563
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002564 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2565 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2566 {
2567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2568 "Neighbor scan results refresh period value %d is out of range"
2569 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2570 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2571 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2572 ret = -EINVAL;
2573 goto exit;
2574 }
2575 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2576
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2578 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002579 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002580
2581 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2582 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2583 }
2584 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2585 {
2586 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2587 char extra[32];
2588 tANI_U8 len = 0;
2589
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002590 len = scnprintf(extra, sizeof(extra), "%s %d",
2591 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002592 /* Returned value is in units of seconds */
2593 if (copy_to_user(priv_data.buf, &extra, len + 1))
2594 {
2595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2596 "%s: failed to copy data to user buffer", __func__);
2597 ret = -EFAULT;
2598 goto exit;
2599 }
2600 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002601#ifdef FEATURE_WLAN_LFR
2602 /* SETROAMMODE */
2603 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2604 {
2605 tANI_U8 *value = command;
2606 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2607
2608 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2609 value = value + SIZE_OF_SETROAMMODE + 1;
2610
2611 /* Convert the value from ascii to integer */
2612 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2613 if (ret < 0)
2614 {
2615 /* If the input value is greater than max value of datatype, then also
2616 kstrtou8 fails */
2617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2618 "%s: kstrtou8 failed range [%d - %d]", __func__,
2619 CFG_LFR_FEATURE_ENABLED_MIN,
2620 CFG_LFR_FEATURE_ENABLED_MAX);
2621 ret = -EINVAL;
2622 goto exit;
2623 }
2624 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2625 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2626 {
2627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2628 "Roam Mode value %d is out of range"
2629 " (Min: %d Max: %d)", roamMode,
2630 CFG_LFR_FEATURE_ENABLED_MIN,
2631 CFG_LFR_FEATURE_ENABLED_MAX);
2632 ret = -EINVAL;
2633 goto exit;
2634 }
2635
2636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2637 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2638 /*
2639 * Note that
2640 * SETROAMMODE 0 is to enable LFR while
2641 * SETROAMMODE 1 is to disable LFR, but
2642 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2643 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2644 */
2645 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2646 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2647 else
2648 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2649
2650 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2651 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2652 }
2653 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302654 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002655 {
2656 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2657 char extra[32];
2658 tANI_U8 len = 0;
2659
2660 /*
2661 * roamMode value shall be inverted because the sementics is different.
2662 */
2663 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2664 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2665 else
2666 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2667
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002668 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002669 if (copy_to_user(priv_data.buf, &extra, len + 1))
2670 {
2671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2672 "%s: failed to copy data to user buffer", __func__);
2673 ret = -EFAULT;
2674 goto exit;
2675 }
2676 }
2677#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002678#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002679#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002680 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2681 {
2682 tANI_U8 *value = command;
2683 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2684
2685 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2686 value = value + 13;
2687 /* Convert the value from ascii to integer */
2688 ret = kstrtou8(value, 10, &roamRssiDiff);
2689 if (ret < 0)
2690 {
2691 /* If the input value is greater than max value of datatype, then also
2692 kstrtou8 fails */
2693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2694 "%s: kstrtou8 failed range [%d - %d]", __func__,
2695 CFG_ROAM_RSSI_DIFF_MIN,
2696 CFG_ROAM_RSSI_DIFF_MAX);
2697 ret = -EINVAL;
2698 goto exit;
2699 }
2700
2701 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2702 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2703 {
2704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2705 "Roam rssi diff value %d is out of range"
2706 " (Min: %d Max: %d)", roamRssiDiff,
2707 CFG_ROAM_RSSI_DIFF_MIN,
2708 CFG_ROAM_RSSI_DIFF_MAX);
2709 ret = -EINVAL;
2710 goto exit;
2711 }
2712
2713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2714 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2715
2716 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2717 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2718 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302719 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002720 {
2721 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2722 char extra[32];
2723 tANI_U8 len = 0;
2724
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302725 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2726 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2727 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002728 len = scnprintf(extra, sizeof(extra), "%s %d",
2729 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002730 if (copy_to_user(priv_data.buf, &extra, len + 1))
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: failed to copy data to user buffer", __func__);
2734 ret = -EFAULT;
2735 goto exit;
2736 }
2737 }
2738#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002739#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002740 else if (strncmp(command, "GETBAND", 7) == 0)
2741 {
2742 int band = -1;
2743 char extra[32];
2744 tANI_U8 len = 0;
2745 hdd_getBand_helper(pHddCtx, &band);
2746
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302747 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2748 TRACE_CODE_HDD_GETBAND_IOCTL,
2749 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002750 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002751 if (copy_to_user(priv_data.buf, &extra, len + 1))
2752 {
2753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 "%s: failed to copy data to user buffer", __func__);
2755 ret = -EFAULT;
2756 goto exit;
2757 }
2758 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002759 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2760 {
2761 tANI_U8 *value = command;
2762 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2763 tANI_U8 numChannels = 0;
2764 eHalStatus status = eHAL_STATUS_SUCCESS;
2765
2766 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2767 if (eHAL_STATUS_SUCCESS != status)
2768 {
2769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2770 "%s: Failed to parse channel list information", __func__);
2771 ret = -EINVAL;
2772 goto exit;
2773 }
2774
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302775 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2776 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2777 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002778 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2782 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2783 ret = -EINVAL;
2784 goto exit;
2785 }
2786 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2787 numChannels);
2788 if (eHAL_STATUS_SUCCESS != status)
2789 {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s: Failed to update channel list information", __func__);
2792 ret = -EINVAL;
2793 goto exit;
2794 }
2795 }
2796 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2797 {
2798 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2799 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002800 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002801 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002802 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002803
2804 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2805 ChannelList, &numChannels ))
2806 {
2807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2808 "%s: failed to get roam scan channel list", __func__);
2809 ret = -EFAULT;
2810 goto exit;
2811 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302812 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2813 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2814 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002815 /* output channel list is of the format
2816 [Number of roam scan channels][Channel1][Channel2]... */
2817 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002818 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002819 for (j = 0; (j < numChannels); j++)
2820 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002821 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2822 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002823 }
2824
2825 if (copy_to_user(priv_data.buf, &extra, len + 1))
2826 {
2827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2828 "%s: failed to copy data to user buffer", __func__);
2829 ret = -EFAULT;
2830 goto exit;
2831 }
2832 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002833 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2834 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002835 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002836 char extra[32];
2837 tANI_U8 len = 0;
2838
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002839 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002840 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002841 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002842 hdd_is_okc_mode_enabled(pHddCtx) &&
2843 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2844 {
2845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002846 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002847 " hence this operation is not permitted!", __func__);
2848 ret = -EPERM;
2849 goto exit;
2850 }
2851
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002852 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002853 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002854 if (copy_to_user(priv_data.buf, &extra, len + 1))
2855 {
2856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2857 "%s: failed to copy data to user buffer", __func__);
2858 ret = -EFAULT;
2859 goto exit;
2860 }
2861 }
2862 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2863 {
2864 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2865 char extra[32];
2866 tANI_U8 len = 0;
2867
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002868 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002869 then this operation is not permitted (return FAILURE) */
2870 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002871 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002872 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2873 {
2874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002875 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002876 " hence this operation is not permitted!", __func__);
2877 ret = -EPERM;
2878 goto exit;
2879 }
2880
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002881 len = scnprintf(extra, sizeof(extra), "%s %d",
2882 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002883 if (copy_to_user(priv_data.buf, &extra, len + 1))
2884 {
2885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2886 "%s: failed to copy data to user buffer", __func__);
2887 ret = -EFAULT;
2888 goto exit;
2889 }
2890 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002891 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002892 {
2893 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2894 char extra[32];
2895 tANI_U8 len = 0;
2896
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002897 len = scnprintf(extra, sizeof(extra), "%s %d",
2898 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002899 if (copy_to_user(priv_data.buf, &extra, len + 1))
2900 {
2901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2902 "%s: failed to copy data to user buffer", __func__);
2903 ret = -EFAULT;
2904 goto exit;
2905 }
2906 }
2907 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2908 {
2909 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2910 char extra[32];
2911 tANI_U8 len = 0;
2912
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002913 len = scnprintf(extra, sizeof(extra), "%s %d",
2914 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05302915 len = VOS_MIN(priv_data.total_len, len + 1);
2916 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002917 {
2918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2919 "%s: failed to copy data to user buffer", __func__);
2920 ret = -EFAULT;
2921 goto exit;
2922 }
2923 }
2924 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2925 {
2926 tANI_U8 *value = command;
2927 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2928
2929 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2930 value = value + 26;
2931 /* Convert the value from ascii to integer */
2932 ret = kstrtou8(value, 10, &minTime);
2933 if (ret < 0)
2934 {
2935 /* If the input value is greater than max value of datatype, then also
2936 kstrtou8 fails */
2937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2938 "%s: kstrtou8 failed range [%d - %d]", __func__,
2939 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2940 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2941 ret = -EINVAL;
2942 goto exit;
2943 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002944 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2945 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2946 {
2947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2948 "scan min channel time value %d is out of range"
2949 " (Min: %d Max: %d)", minTime,
2950 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2951 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2952 ret = -EINVAL;
2953 goto exit;
2954 }
2955
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302956 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2957 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2958 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2960 "%s: Received Command to change channel min time = %d", __func__, minTime);
2961
2962 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2963 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2964 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002965 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2966 {
2967 tANI_U8 *value = command;
2968 tANI_U8 channel = 0;
2969 tANI_U8 dwellTime = 0;
2970 tANI_U8 bufLen = 0;
2971 tANI_U8 *buf = NULL;
2972 tSirMacAddr targetApBssid;
2973 eHalStatus status = eHAL_STATUS_SUCCESS;
2974 struct ieee80211_channel chan;
2975 tANI_U8 finalLen = 0;
2976 tANI_U8 *finalBuf = NULL;
2977 tANI_U8 temp = 0;
2978 u64 cookie;
2979 hdd_station_ctx_t *pHddStaCtx = NULL;
2980 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2981
2982 /* if not associated, no need to send action frame */
2983 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2984 {
2985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2986 ret = -EINVAL;
2987 goto exit;
2988 }
2989
2990 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2991 &dwellTime, &buf, &bufLen);
2992 if (eHAL_STATUS_SUCCESS != status)
2993 {
2994 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2995 "%s: Failed to parse send action frame data", __func__);
2996 ret = -EINVAL;
2997 goto exit;
2998 }
2999
3000 /* if the target bssid is different from currently associated AP,
3001 then no need to send action frame */
3002 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3003 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3004 {
3005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3006 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003007 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003008 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003009 goto exit;
3010 }
3011
3012 /* if the channel number is different from operating channel then
3013 no need to send action frame */
3014 if (channel != pHddStaCtx->conn_info.operationChannel)
3015 {
3016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3017 "%s: channel(%d) is different from operating channel(%d)",
3018 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3019 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003020 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003021 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003022 goto exit;
3023 }
3024 chan.center_freq = sme_ChnToFreq(channel);
3025
3026 finalLen = bufLen + 24;
3027 finalBuf = vos_mem_malloc(finalLen);
3028 if (NULL == finalBuf)
3029 {
3030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3031 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003032 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003033 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003034 goto exit;
3035 }
3036 vos_mem_zero(finalBuf, finalLen);
3037
3038 /* Fill subtype */
3039 temp = SIR_MAC_MGMT_ACTION << 4;
3040 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3041
3042 /* Fill type */
3043 temp = SIR_MAC_MGMT_FRAME;
3044 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3045
3046 /* Fill destination address (bssid of the AP) */
3047 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3048
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003049 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003050 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3051
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003052 /* Fill BSSID (AP mac address) */
3053 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003054
3055 /* Fill received buffer from 24th address */
3056 vos_mem_copy(finalBuf + 24, buf, bufLen);
3057
Jeff Johnson11c33152013-04-16 17:52:40 -07003058 /* done with the parsed buffer */
3059 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003060 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003061
DARAM SUDHA39eede62014-02-12 11:16:40 +05303062 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003063#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3064 &(pAdapter->wdev),
3065#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003066 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003067#endif
3068 &chan, 0,
3069#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3070 NL80211_CHAN_HT20, 1,
3071#endif
3072 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003073 1, &cookie );
3074 vos_mem_free(finalBuf);
3075 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003076 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3077 {
3078 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3079 char extra[32];
3080 tANI_U8 len = 0;
3081
3082 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003083 len = scnprintf(extra, sizeof(extra), "%s %d",
3084 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303085 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3086 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3087 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303088 len = VOS_MIN(priv_data.total_len, len + 1);
3089 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003090 {
3091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3092 "%s: failed to copy data to user buffer", __func__);
3093 ret = -EFAULT;
3094 goto exit;
3095 }
3096 }
3097 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3098 {
3099 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003100 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003101
3102 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3103 value = value + 19;
3104 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003105 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003106 if (ret < 0)
3107 {
3108 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003109 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003111 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003112 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3113 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3114 ret = -EINVAL;
3115 goto exit;
3116 }
3117
3118 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3119 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3120 {
3121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3122 "lfr mode value %d is out of range"
3123 " (Min: %d Max: %d)", maxTime,
3124 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3125 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3126 ret = -EINVAL;
3127 goto exit;
3128 }
3129
3130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3131 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3132
3133 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3134 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3135 }
3136 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3137 {
3138 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3139 char extra[32];
3140 tANI_U8 len = 0;
3141
3142 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003143 len = scnprintf(extra, sizeof(extra), "%s %d",
3144 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003145 if (copy_to_user(priv_data.buf, &extra, len + 1))
3146 {
3147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3148 "%s: failed to copy data to user buffer", __func__);
3149 ret = -EFAULT;
3150 goto exit;
3151 }
3152 }
3153 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3154 {
3155 tANI_U8 *value = command;
3156 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3157
3158 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3159 value = value + 16;
3160 /* Convert the value from ascii to integer */
3161 ret = kstrtou16(value, 10, &val);
3162 if (ret < 0)
3163 {
3164 /* If the input value is greater than max value of datatype, then also
3165 kstrtou16 fails */
3166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3167 "%s: kstrtou16 failed range [%d - %d]", __func__,
3168 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3169 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3170 ret = -EINVAL;
3171 goto exit;
3172 }
3173
3174 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3175 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3176 {
3177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3178 "scan home time value %d is out of range"
3179 " (Min: %d Max: %d)", val,
3180 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3181 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3182 ret = -EINVAL;
3183 goto exit;
3184 }
3185
3186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3187 "%s: Received Command to change scan home time = %d", __func__, val);
3188
3189 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3190 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3191 }
3192 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3193 {
3194 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3195 char extra[32];
3196 tANI_U8 len = 0;
3197
3198 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003199 len = scnprintf(extra, sizeof(extra), "%s %d",
3200 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003201 if (copy_to_user(priv_data.buf, &extra, len + 1))
3202 {
3203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3204 "%s: failed to copy data to user buffer", __func__);
3205 ret = -EFAULT;
3206 goto exit;
3207 }
3208 }
3209 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3210 {
3211 tANI_U8 *value = command;
3212 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3213
3214 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3215 value = value + 17;
3216 /* Convert the value from ascii to integer */
3217 ret = kstrtou8(value, 10, &val);
3218 if (ret < 0)
3219 {
3220 /* If the input value is greater than max value of datatype, then also
3221 kstrtou8 fails */
3222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3223 "%s: kstrtou8 failed range [%d - %d]", __func__,
3224 CFG_ROAM_INTRA_BAND_MIN,
3225 CFG_ROAM_INTRA_BAND_MAX);
3226 ret = -EINVAL;
3227 goto exit;
3228 }
3229
3230 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3231 (val > CFG_ROAM_INTRA_BAND_MAX))
3232 {
3233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3234 "intra band mode value %d is out of range"
3235 " (Min: %d Max: %d)", val,
3236 CFG_ROAM_INTRA_BAND_MIN,
3237 CFG_ROAM_INTRA_BAND_MAX);
3238 ret = -EINVAL;
3239 goto exit;
3240 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3242 "%s: Received Command to change intra band = %d", __func__, val);
3243
3244 pHddCtx->cfg_ini->nRoamIntraBand = val;
3245 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3246 }
3247 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3248 {
3249 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3250 char extra[32];
3251 tANI_U8 len = 0;
3252
3253 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003254 len = scnprintf(extra, sizeof(extra), "%s %d",
3255 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003256 if (copy_to_user(priv_data.buf, &extra, len + 1))
3257 {
3258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3259 "%s: failed to copy data to user buffer", __func__);
3260 ret = -EFAULT;
3261 goto exit;
3262 }
3263 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003264 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3265 {
3266 tANI_U8 *value = command;
3267 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3268
3269 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3270 value = value + 15;
3271 /* Convert the value from ascii to integer */
3272 ret = kstrtou8(value, 10, &nProbes);
3273 if (ret < 0)
3274 {
3275 /* If the input value is greater than max value of datatype, then also
3276 kstrtou8 fails */
3277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3278 "%s: kstrtou8 failed range [%d - %d]", __func__,
3279 CFG_ROAM_SCAN_N_PROBES_MIN,
3280 CFG_ROAM_SCAN_N_PROBES_MAX);
3281 ret = -EINVAL;
3282 goto exit;
3283 }
3284
3285 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3286 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3287 {
3288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3289 "NProbes value %d is out of range"
3290 " (Min: %d Max: %d)", nProbes,
3291 CFG_ROAM_SCAN_N_PROBES_MIN,
3292 CFG_ROAM_SCAN_N_PROBES_MAX);
3293 ret = -EINVAL;
3294 goto exit;
3295 }
3296
3297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3298 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3299
3300 pHddCtx->cfg_ini->nProbes = nProbes;
3301 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3302 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303303 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003304 {
3305 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3306 char extra[32];
3307 tANI_U8 len = 0;
3308
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003309 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003310 if (copy_to_user(priv_data.buf, &extra, len + 1))
3311 {
3312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3313 "%s: failed to copy data to user buffer", __func__);
3314 ret = -EFAULT;
3315 goto exit;
3316 }
3317 }
3318 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3319 {
3320 tANI_U8 *value = command;
3321 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3322
3323 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3324 /* input value is in units of msec */
3325 value = value + 20;
3326 /* Convert the value from ascii to integer */
3327 ret = kstrtou16(value, 10, &homeAwayTime);
3328 if (ret < 0)
3329 {
3330 /* If the input value is greater than max value of datatype, then also
3331 kstrtou8 fails */
3332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3333 "%s: kstrtou8 failed range [%d - %d]", __func__,
3334 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3335 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3336 ret = -EINVAL;
3337 goto exit;
3338 }
3339
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003340 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3341 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3342 {
3343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3344 "homeAwayTime value %d is out of range"
3345 " (Min: %d Max: %d)", homeAwayTime,
3346 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3347 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3348 ret = -EINVAL;
3349 goto exit;
3350 }
3351
3352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3353 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003354 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3355 {
3356 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3357 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3358 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003359 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303360 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003361 {
3362 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3363 char extra[32];
3364 tANI_U8 len = 0;
3365
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003366 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003367 if (copy_to_user(priv_data.buf, &extra, len + 1))
3368 {
3369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3370 "%s: failed to copy data to user buffer", __func__);
3371 ret = -EFAULT;
3372 goto exit;
3373 }
3374 }
3375 else if (strncmp(command, "REASSOC", 7) == 0)
3376 {
3377 tANI_U8 *value = command;
3378 tANI_U8 channel = 0;
3379 tSirMacAddr targetApBssid;
3380 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003381#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3382 tCsrHandoffRequest handoffInfo;
3383#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003384 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003385 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3386
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003387 /* if not associated, no need to proceed with reassoc */
3388 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3389 {
3390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3391 ret = -EINVAL;
3392 goto exit;
3393 }
3394
3395 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3396 if (eHAL_STATUS_SUCCESS != status)
3397 {
3398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3399 "%s: Failed to parse reassoc command data", __func__);
3400 ret = -EINVAL;
3401 goto exit;
3402 }
3403
3404 /* if the target bssid is same as currently associated AP,
3405 then no need to proceed with reassoc */
3406 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3407 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3408 {
3409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3410 ret = -EINVAL;
3411 goto exit;
3412 }
3413
3414 /* Check channel number is a valid channel number */
3415 if(VOS_STATUS_SUCCESS !=
3416 wlan_hdd_validate_operation_channel(pAdapter, channel))
3417 {
3418 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003419 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003420 return -EINVAL;
3421 }
3422
3423 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003424#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3425 handoffInfo.channel = channel;
3426 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3427 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3428#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003429 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003430 else if (strncmp(command, "SETWESMODE", 10) == 0)
3431 {
3432 tANI_U8 *value = command;
3433 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3434
3435 /* Move pointer to ahead of SETWESMODE<delimiter> */
3436 value = value + 11;
3437 /* Convert the value from ascii to integer */
3438 ret = kstrtou8(value, 10, &wesMode);
3439 if (ret < 0)
3440 {
3441 /* If the input value is greater than max value of datatype, then also
3442 kstrtou8 fails */
3443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3444 "%s: kstrtou8 failed range [%d - %d]", __func__,
3445 CFG_ENABLE_WES_MODE_NAME_MIN,
3446 CFG_ENABLE_WES_MODE_NAME_MAX);
3447 ret = -EINVAL;
3448 goto exit;
3449 }
3450
3451 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3452 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3453 {
3454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3455 "WES Mode value %d is out of range"
3456 " (Min: %d Max: %d)", wesMode,
3457 CFG_ENABLE_WES_MODE_NAME_MIN,
3458 CFG_ENABLE_WES_MODE_NAME_MAX);
3459 ret = -EINVAL;
3460 goto exit;
3461 }
3462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3463 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3464
3465 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3466 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3467 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303468 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003469 {
3470 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3471 char extra[32];
3472 tANI_U8 len = 0;
3473
Arif Hussain826d9412013-11-12 16:44:54 -08003474 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003475 if (copy_to_user(priv_data.buf, &extra, len + 1))
3476 {
3477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3478 "%s: failed to copy data to user buffer", __func__);
3479 ret = -EFAULT;
3480 goto exit;
3481 }
3482 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003483#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003484#ifdef FEATURE_WLAN_LFR
3485 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3486 {
3487 tANI_U8 *value = command;
3488 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3489
3490 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3491 value = value + 12;
3492 /* Convert the value from ascii to integer */
3493 ret = kstrtou8(value, 10, &lfrMode);
3494 if (ret < 0)
3495 {
3496 /* If the input value is greater than max value of datatype, then also
3497 kstrtou8 fails */
3498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3499 "%s: kstrtou8 failed range [%d - %d]", __func__,
3500 CFG_LFR_FEATURE_ENABLED_MIN,
3501 CFG_LFR_FEATURE_ENABLED_MAX);
3502 ret = -EINVAL;
3503 goto exit;
3504 }
3505
3506 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3507 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3508 {
3509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3510 "lfr mode value %d is out of range"
3511 " (Min: %d Max: %d)", lfrMode,
3512 CFG_LFR_FEATURE_ENABLED_MIN,
3513 CFG_LFR_FEATURE_ENABLED_MAX);
3514 ret = -EINVAL;
3515 goto exit;
3516 }
3517
3518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3519 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3520
3521 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3522 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3523 }
3524#endif
3525#ifdef WLAN_FEATURE_VOWIFI_11R
3526 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3527 {
3528 tANI_U8 *value = command;
3529 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3530
3531 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3532 value = value + 18;
3533 /* Convert the value from ascii to integer */
3534 ret = kstrtou8(value, 10, &ft);
3535 if (ret < 0)
3536 {
3537 /* If the input value is greater than max value of datatype, then also
3538 kstrtou8 fails */
3539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3540 "%s: kstrtou8 failed range [%d - %d]", __func__,
3541 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3542 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3543 ret = -EINVAL;
3544 goto exit;
3545 }
3546
3547 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3548 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3549 {
3550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3551 "ft mode value %d is out of range"
3552 " (Min: %d Max: %d)", ft,
3553 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3554 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3555 ret = -EINVAL;
3556 goto exit;
3557 }
3558
3559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3560 "%s: Received Command to change ft mode = %d", __func__, ft);
3561
3562 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3563 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3564 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303565 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3566 {
3567 tANI_U8 *value = command;
3568 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303569
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303570 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3571 value = value + 15;
3572 /* Convert the value from ascii to integer */
3573 ret = kstrtou8(value, 10, &dfsScanMode);
3574 if (ret < 0)
3575 {
3576 /* If the input value is greater than max value of
3577 datatype, then also kstrtou8 fails
3578 */
3579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3580 "%s: kstrtou8 failed range [%d - %d]", __func__,
3581 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3582 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3583 ret = -EINVAL;
3584 goto exit;
3585 }
3586
3587 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3588 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3589 {
3590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3591 "dfsScanMode value %d is out of range"
3592 " (Min: %d Max: %d)", dfsScanMode,
3593 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3594 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3595 ret = -EINVAL;
3596 goto exit;
3597 }
3598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3599 "%s: Received Command to Set DFS Scan Mode = %d",
3600 __func__, dfsScanMode);
3601
3602 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3603 }
3604 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3605 {
3606 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3607 char extra[32];
3608 tANI_U8 len = 0;
3609
3610 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3611 if (copy_to_user(priv_data.buf, &extra, len + 1))
3612 {
3613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3614 "%s: failed to copy data to user buffer", __func__);
3615 ret = -EFAULT;
3616 goto exit;
3617 }
3618 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303619 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3620 {
3621 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303622 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303623 tSirMacAddr targetApBssid;
3624 tANI_U8 trigger = 0;
3625 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303626 tHalHandle hHal;
3627 v_U32_t roamId = 0;
3628 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303629 hdd_station_ctx_t *pHddStaCtx = NULL;
3630 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303631 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303632
3633 /* if not associated, no need to proceed with reassoc */
3634 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3635 {
3636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3637 ret = -EINVAL;
3638 goto exit;
3639 }
3640
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303641 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303642 if (eHAL_STATUS_SUCCESS != status)
3643 {
3644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3645 "%s: Failed to parse reassoc command data", __func__);
3646 ret = -EINVAL;
3647 goto exit;
3648 }
3649
3650 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303651 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303652 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3653 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3654 {
3655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3656 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3657 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303658 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3659 &modProfileFields);
3660 sme_RoamReassoc(hHal, pAdapter->sessionId,
3661 NULL, modProfileFields, &roamId, 1);
3662 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303663 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303664
3665 /* Check channel number is a valid channel number */
3666 if(VOS_STATUS_SUCCESS !=
3667 wlan_hdd_validate_operation_channel(pAdapter, channel))
3668 {
3669 hddLog(VOS_TRACE_LEVEL_ERROR,
3670 "%s: Invalid Channel [%d]", __func__, channel);
3671 return -EINVAL;
3672 }
3673
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303674 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303675
3676 /* Proceed with scan/roam */
3677 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3678 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303679 (tSmeFastRoamTrigger)(trigger),
3680 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303681 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003682#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003683#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003684 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3685 {
3686 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003687 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003688
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003689 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003690 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003691 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003692 hdd_is_okc_mode_enabled(pHddCtx) &&
3693 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3694 {
3695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003696 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003697 " hence this operation is not permitted!", __func__);
3698 ret = -EPERM;
3699 goto exit;
3700 }
3701
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003702 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3703 value = value + 11;
3704 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003705 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003706 if (ret < 0)
3707 {
3708 /* If the input value is greater than max value of datatype, then also
3709 kstrtou8 fails */
3710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3711 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003712 CFG_ESE_FEATURE_ENABLED_MIN,
3713 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003714 ret = -EINVAL;
3715 goto exit;
3716 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003717 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3718 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003719 {
3720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003721 "Ese mode value %d is out of range"
3722 " (Min: %d Max: %d)", eseMode,
3723 CFG_ESE_FEATURE_ENABLED_MIN,
3724 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003725 ret = -EINVAL;
3726 goto exit;
3727 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003729 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003730
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003731 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3732 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003733 }
3734#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003735 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3736 {
3737 tANI_U8 *value = command;
3738 tANI_BOOLEAN roamScanControl = 0;
3739
3740 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3741 value = value + 19;
3742 /* Convert the value from ascii to integer */
3743 ret = kstrtou8(value, 10, &roamScanControl);
3744 if (ret < 0)
3745 {
3746 /* If the input value is greater than max value of datatype, then also
3747 kstrtou8 fails */
3748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3749 "%s: kstrtou8 failed ", __func__);
3750 ret = -EINVAL;
3751 goto exit;
3752 }
3753
3754 if (0 != roamScanControl)
3755 {
3756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3757 "roam scan control invalid value = %d",
3758 roamScanControl);
3759 ret = -EINVAL;
3760 goto exit;
3761 }
3762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3763 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3764
3765 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3766 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003767#ifdef FEATURE_WLAN_OKC
3768 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3769 {
3770 tANI_U8 *value = command;
3771 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3772
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003773 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003774 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003775 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003776 hdd_is_okc_mode_enabled(pHddCtx) &&
3777 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3778 {
3779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003780 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003781 " hence this operation is not permitted!", __func__);
3782 ret = -EPERM;
3783 goto exit;
3784 }
3785
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003786 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3787 value = value + 11;
3788 /* Convert the value from ascii to integer */
3789 ret = kstrtou8(value, 10, &okcMode);
3790 if (ret < 0)
3791 {
3792 /* If the input value is greater than max value of datatype, then also
3793 kstrtou8 fails */
3794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3795 "%s: kstrtou8 failed range [%d - %d]", __func__,
3796 CFG_OKC_FEATURE_ENABLED_MIN,
3797 CFG_OKC_FEATURE_ENABLED_MAX);
3798 ret = -EINVAL;
3799 goto exit;
3800 }
3801
3802 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3803 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3804 {
3805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3806 "Okc mode value %d is out of range"
3807 " (Min: %d Max: %d)", okcMode,
3808 CFG_OKC_FEATURE_ENABLED_MIN,
3809 CFG_OKC_FEATURE_ENABLED_MAX);
3810 ret = -EINVAL;
3811 goto exit;
3812 }
3813
3814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3815 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3816
3817 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3818 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003819#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303820 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003821 {
3822 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3823 char extra[32];
3824 tANI_U8 len = 0;
3825
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003826 len = scnprintf(extra, sizeof(extra), "%s %d",
3827 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003828 if (copy_to_user(priv_data.buf, &extra, len + 1))
3829 {
3830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3831 "%s: failed to copy data to user buffer", __func__);
3832 ret = -EFAULT;
3833 goto exit;
3834 }
3835 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303836#ifdef WLAN_FEATURE_PACKET_FILTERING
3837 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3838 {
3839 tANI_U8 filterType = 0;
3840 tANI_U8 *value = command;
3841
3842 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3843 value = value + 22;
3844
3845 /* Convert the value from ascii to integer */
3846 ret = kstrtou8(value, 10, &filterType);
3847 if (ret < 0)
3848 {
3849 /* If the input value is greater than max value of datatype,
3850 * then also kstrtou8 fails
3851 */
3852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3853 "%s: kstrtou8 failed range ", __func__);
3854 ret = -EINVAL;
3855 goto exit;
3856 }
3857
3858 if (filterType != 0 && filterType != 1)
3859 {
3860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3861 "%s: Accepted Values are 0 and 1 ", __func__);
3862 ret = -EINVAL;
3863 goto exit;
3864 }
3865 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3866 pAdapter->sessionId);
3867 }
3868#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303869 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3870 {
Kiet Lamad161252014-07-22 11:23:32 -07003871 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303872 int ret;
3873
Kiet Lamad161252014-07-22 11:23:32 -07003874 dhcpPhase = command + 11;
3875 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303876 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003878 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303879
3880 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003881
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303882 ret = wlan_hdd_scan_abort(pAdapter);
3883 if (ret < 0)
3884 {
3885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3886 FL("failed to abort existing scan %d"), ret);
3887 }
3888
Kiet Lamad161252014-07-22 11:23:32 -07003889 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3890 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303891 }
Kiet Lamad161252014-07-22 11:23:32 -07003892 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303893 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003895 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303896
3897 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003898
3899 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3900 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303901 }
3902 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003903 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3904 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3906 FL("making default scan to ACTIVE"));
3907 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003908 }
3909 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3910 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3912 FL("making default scan to PASSIVE"));
3913 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003914 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303915 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3916 {
3917 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3918 char extra[32];
3919 tANI_U8 len = 0;
3920
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303921 memset(extra, 0, sizeof(extra));
3922 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3923 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303924 {
3925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3926 "%s: failed to copy data to user buffer", __func__);
3927 ret = -EFAULT;
3928 goto exit;
3929 }
3930 ret = len;
3931 }
3932 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3933 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303934 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303935 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003936 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3937 {
3938 tANI_U8 filterType = 0;
3939 tANI_U8 *value;
3940 value = command + 9;
3941
3942 /* Convert the value from ascii to integer */
3943 ret = kstrtou8(value, 10, &filterType);
3944 if (ret < 0)
3945 {
3946 /* If the input value is greater than max value of datatype,
3947 * then also kstrtou8 fails
3948 */
3949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3950 "%s: kstrtou8 failed range ", __func__);
3951 ret = -EINVAL;
3952 goto exit;
3953 }
3954 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3955 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3956 {
3957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3958 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3959 " 2-Sink ", __func__);
3960 ret = -EINVAL;
3961 goto exit;
3962 }
3963 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3964 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303965 pScanInfo = &pHddCtx->scan_info;
3966 if (filterType && pScanInfo != NULL &&
3967 pHddCtx->scan_info.mScanPending)
3968 {
3969 /*Miracast Session started. Abort Scan */
3970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3971 "%s, Aborting Scan For Miracast",__func__);
3972 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3973 eCSR_SCAN_ABORT_DEFAULT);
3974 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003975 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303976 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003977 }
Leo Chang614d2072013-08-22 14:59:44 -07003978 else if (strncmp(command, "SETMCRATE", 9) == 0)
3979 {
Leo Chang614d2072013-08-22 14:59:44 -07003980 tANI_U8 *value = command;
3981 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003982 tSirRateUpdateInd *rateUpdate;
3983 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003984
3985 /* Only valid for SAP mode */
3986 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3987 {
3988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3989 "%s: SAP mode is not running", __func__);
3990 ret = -EFAULT;
3991 goto exit;
3992 }
3993
3994 /* Move pointer to ahead of SETMCRATE<delimiter> */
3995 /* input value is in units of hundred kbps */
3996 value = value + 10;
3997 /* Convert the value from ascii to integer, decimal base */
3998 ret = kstrtouint(value, 10, &targetRate);
3999
Leo Chang1f98cbd2013-10-17 15:03:52 -07004000 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4001 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004002 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004003 hddLog(VOS_TRACE_LEVEL_ERROR,
4004 "%s: SETMCRATE indication alloc fail", __func__);
4005 ret = -EFAULT;
4006 goto exit;
4007 }
4008 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4009
4010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4011 "MC Target rate %d", targetRate);
4012 /* Ignore unicast */
4013 rateUpdate->ucastDataRate = -1;
4014 rateUpdate->mcastDataRate24GHz = targetRate;
4015 rateUpdate->mcastDataRate5GHz = targetRate;
4016 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4017 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4018 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4019 if (eHAL_STATUS_SUCCESS != status)
4020 {
4021 hddLog(VOS_TRACE_LEVEL_ERROR,
4022 "%s: SET_MC_RATE failed", __func__);
4023 vos_mem_free(rateUpdate);
4024 ret = -EFAULT;
4025 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004026 }
4027 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304028#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004029 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304030 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004031 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304032 }
4033#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004034#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004035 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4036 {
4037 tANI_U8 *value = command;
4038 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4039 tANI_U8 numChannels = 0;
4040 eHalStatus status = eHAL_STATUS_SUCCESS;
4041
4042 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4043 if (eHAL_STATUS_SUCCESS != status)
4044 {
4045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4046 "%s: Failed to parse channel list information", __func__);
4047 ret = -EINVAL;
4048 goto exit;
4049 }
4050
4051 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4052 {
4053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4054 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4055 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4056 ret = -EINVAL;
4057 goto exit;
4058 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004059 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004060 ChannelList,
4061 numChannels);
4062 if (eHAL_STATUS_SUCCESS != status)
4063 {
4064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4065 "%s: Failed to update channel list information", __func__);
4066 ret = -EINVAL;
4067 goto exit;
4068 }
4069 }
4070 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4071 {
4072 tANI_U8 *value = command;
4073 char extra[128] = {0};
4074 int len = 0;
4075 tANI_U8 tid = 0;
4076 hdd_station_ctx_t *pHddStaCtx = NULL;
4077 tAniTrafStrmMetrics tsmMetrics;
4078 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4079
4080 /* if not associated, return error */
4081 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4082 {
4083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4084 ret = -EINVAL;
4085 goto exit;
4086 }
4087
4088 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4089 value = value + 12;
4090 /* Convert the value from ascii to integer */
4091 ret = kstrtou8(value, 10, &tid);
4092 if (ret < 0)
4093 {
4094 /* If the input value is greater than max value of datatype, then also
4095 kstrtou8 fails */
4096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4097 "%s: kstrtou8 failed range [%d - %d]", __func__,
4098 TID_MIN_VALUE,
4099 TID_MAX_VALUE);
4100 ret = -EINVAL;
4101 goto exit;
4102 }
4103
4104 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4105 {
4106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4107 "tid value %d is out of range"
4108 " (Min: %d Max: %d)", tid,
4109 TID_MIN_VALUE,
4110 TID_MAX_VALUE);
4111 ret = -EINVAL;
4112 goto exit;
4113 }
4114
4115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4116 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4117
4118 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4119 {
4120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4121 "%s: failed to get tsm stats", __func__);
4122 ret = -EFAULT;
4123 goto exit;
4124 }
4125
4126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4127 "UplinkPktQueueDly(%d)\n"
4128 "UplinkPktQueueDlyHist[0](%d)\n"
4129 "UplinkPktQueueDlyHist[1](%d)\n"
4130 "UplinkPktQueueDlyHist[2](%d)\n"
4131 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304132 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004133 "UplinkPktLoss(%d)\n"
4134 "UplinkPktCount(%d)\n"
4135 "RoamingCount(%d)\n"
4136 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4137 tsmMetrics.UplinkPktQueueDlyHist[0],
4138 tsmMetrics.UplinkPktQueueDlyHist[1],
4139 tsmMetrics.UplinkPktQueueDlyHist[2],
4140 tsmMetrics.UplinkPktQueueDlyHist[3],
4141 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4142 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4143
4144 /* Output TSM stats is of the format
4145 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4146 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004147 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004148 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4149 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4150 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4151 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4152 tsmMetrics.RoamingDly);
4153
4154 if (copy_to_user(priv_data.buf, &extra, len + 1))
4155 {
4156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4157 "%s: failed to copy data to user buffer", __func__);
4158 ret = -EFAULT;
4159 goto exit;
4160 }
4161 }
4162 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4163 {
4164 tANI_U8 *value = command;
4165 tANI_U8 *cckmIe = NULL;
4166 tANI_U8 cckmIeLen = 0;
4167 eHalStatus status = eHAL_STATUS_SUCCESS;
4168
4169 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4170 if (eHAL_STATUS_SUCCESS != status)
4171 {
4172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4173 "%s: Failed to parse cckm ie data", __func__);
4174 ret = -EINVAL;
4175 goto exit;
4176 }
4177
4178 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4179 {
4180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4181 "%s: CCKM Ie input length is more than max[%d]", __func__,
4182 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004183 vos_mem_free(cckmIe);
4184 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004185 ret = -EINVAL;
4186 goto exit;
4187 }
4188 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004189 vos_mem_free(cckmIe);
4190 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004191 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004192 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4193 {
4194 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004195 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004196 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004197
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004198 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004199 if (eHAL_STATUS_SUCCESS != status)
4200 {
4201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004202 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004203 ret = -EINVAL;
4204 goto exit;
4205 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004206 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4207 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4208 hdd_indicateEseBcnReportNoResults (pAdapter,
4209 eseBcnReq.bcnReq[0].measurementToken,
4210 0x02, //BIT(1) set for measurement done
4211 0); // no BSS
4212 goto exit;
4213 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004214
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004215 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4216 if (eHAL_STATUS_SUCCESS != status)
4217 {
4218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4219 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4220 ret = -EINVAL;
4221 goto exit;
4222 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004223 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004224#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304225 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4226 {
4227 eHalStatus status;
4228 char buf[32], len;
4229 long waitRet;
4230 bcnMissRateContext_t getBcnMissRateCtx;
4231
4232 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4233
4234 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4235 {
4236 hddLog(VOS_TRACE_LEVEL_WARN,
4237 FL("GETBCNMISSRATE: STA is not in connected state"));
4238 ret = -1;
4239 goto exit;
4240 }
4241
4242 init_completion(&(getBcnMissRateCtx.completion));
4243 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4244
4245 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4246 pAdapter->sessionId,
4247 (void *)getBcnMissRateCB,
4248 (void *)(&getBcnMissRateCtx));
4249 if( eHAL_STATUS_SUCCESS != status)
4250 {
4251 hddLog(VOS_TRACE_LEVEL_INFO,
4252 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4253 ret = -EINVAL;
4254 goto exit;
4255 }
4256
4257 waitRet = wait_for_completion_interruptible_timeout
4258 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4259 if(waitRet <= 0)
4260 {
4261 hddLog(VOS_TRACE_LEVEL_ERROR,
4262 FL("failed to wait on bcnMissRateComp %d"), ret);
4263
4264 //Make magic number to zero so that callback is not called.
4265 spin_lock(&hdd_context_lock);
4266 getBcnMissRateCtx.magic = 0x0;
4267 spin_unlock(&hdd_context_lock);
4268 ret = -EINVAL;
4269 goto exit;
4270 }
4271
4272 hddLog(VOS_TRACE_LEVEL_INFO,
4273 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4274
4275 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4276 if (copy_to_user(priv_data.buf, &buf, len + 1))
4277 {
4278 hddLog(VOS_TRACE_LEVEL_ERROR,
4279 "%s: failed to copy data to user buffer", __func__);
4280 ret = -EFAULT;
4281 goto exit;
4282 }
4283 ret = len;
4284 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304285#ifdef FEATURE_WLAN_TDLS
4286 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4287 tANI_U8 *value = command;
4288 int set_value;
4289 /* Move pointer to ahead of TDLSOFFCH*/
4290 value += 26;
4291 sscanf(value, "%d", &set_value);
4292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4293 "%s: Tdls offchannel offset:%d",
4294 __func__, set_value);
4295 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4296 if (ret < 0)
4297 {
4298 ret = -EINVAL;
4299 goto exit;
4300 }
4301
4302 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4303 tANI_U8 *value = command;
4304 int set_value;
4305 /* Move pointer to ahead of tdlsoffchnmode*/
4306 value += 18;
4307 sscanf(value, "%d", &set_value);
4308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4309 "%s: Tdls offchannel mode:%d",
4310 __func__, set_value);
4311 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4312 if (ret < 0)
4313 {
4314 ret = -EINVAL;
4315 goto exit;
4316 }
4317 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4318 tANI_U8 *value = command;
4319 int set_value;
4320 /* Move pointer to ahead of TDLSOFFCH*/
4321 value += 14;
4322 sscanf(value, "%d", &set_value);
4323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4324 "%s: Tdls offchannel num: %d",
4325 __func__, set_value);
4326 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4327 if (ret < 0)
4328 {
4329 ret = -EINVAL;
4330 goto exit;
4331 }
4332 }
4333#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304334 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4335 {
4336 eHalStatus status;
4337 char *buf = NULL;
4338 char len;
4339 long waitRet;
4340 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304341 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304342 tANI_U8 *ptr = command;
4343 int stats = *(ptr + 11) - '0';
4344
4345 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4346 if (!IS_FEATURE_FW_STATS_ENABLE)
4347 {
4348 hddLog(VOS_TRACE_LEVEL_INFO,
4349 FL("Get Firmware stats feature not supported"));
4350 ret = -EINVAL;
4351 goto exit;
4352 }
4353
4354 if (FW_STATS_MAX <= stats || 0 >= stats)
4355 {
4356 hddLog(VOS_TRACE_LEVEL_INFO,
4357 FL(" stats %d not supported"),stats);
4358 ret = -EINVAL;
4359 goto exit;
4360 }
4361
4362 init_completion(&(fwStatsCtx.completion));
4363 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4364 fwStatsCtx.pAdapter = pAdapter;
4365 fwStatsRsp->type = 0;
4366 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304367 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304368 if (eHAL_STATUS_SUCCESS != status)
4369 {
4370 hddLog(VOS_TRACE_LEVEL_ERROR,
4371 FL(" fail to post WDA cmd status = %d"), status);
4372 ret = -EINVAL;
4373 goto exit;
4374 }
4375 waitRet = wait_for_completion_timeout
4376 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4377 if (waitRet <= 0)
4378 {
4379 hddLog(VOS_TRACE_LEVEL_ERROR,
4380 FL("failed to wait on GwtFwstats"));
4381 //Make magic number to zero so that callback is not executed.
4382 spin_lock(&hdd_context_lock);
4383 fwStatsCtx.magic = 0x0;
4384 spin_unlock(&hdd_context_lock);
4385 ret = -EINVAL;
4386 goto exit;
4387 }
4388 if (fwStatsRsp->type)
4389 {
4390 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4391 if (!buf)
4392 {
4393 hddLog(VOS_TRACE_LEVEL_ERROR,
4394 FL(" failed to allocate memory"));
4395 ret = -ENOMEM;
4396 goto exit;
4397 }
4398 switch( fwStatsRsp->type )
4399 {
4400 case FW_UBSP_STATS:
4401 {
4402 len = snprintf(buf, FW_STATE_RSP_LEN,
4403 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304404 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4405 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304406 }
4407 break;
4408 default:
4409 {
4410 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4411 ret = -EFAULT;
4412 kfree(buf);
4413 goto exit;
4414 }
4415 }
4416 if (copy_to_user(priv_data.buf, buf, len + 1))
4417 {
4418 hddLog(VOS_TRACE_LEVEL_ERROR,
4419 FL(" failed to copy data to user buffer"));
4420 ret = -EFAULT;
4421 kfree(buf);
4422 goto exit;
4423 }
4424 ret = len;
4425 kfree(buf);
4426 }
4427 else
4428 {
4429 hddLog(VOS_TRACE_LEVEL_ERROR,
4430 FL("failed to fetch the stats"));
4431 ret = -EFAULT;
4432 goto exit;
4433 }
4434
4435 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304436 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4437 {
4438 /*
4439 * this command wld be called by user-space when it detects WLAN
4440 * ON after airplane mode is set. When APM is set, WLAN turns off.
4441 * But it can be turned back on. Otherwise; when APM is turned back
4442 * off, WLAN wld turn back on. So at that point the command is
4443 * expected to come down. 0 means disable, 1 means enable. The
4444 * constraint is removed when parameter 1 is set or different
4445 * country code is set
4446 */
4447 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4448 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004449 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304450 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4451 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4452 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304453 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4454 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004456 }
4457exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304458 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004459 if (command)
4460 {
4461 kfree(command);
4462 }
4463 return ret;
4464}
4465
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004466#ifdef CONFIG_COMPAT
4467static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4468{
4469 struct {
4470 compat_uptr_t buf;
4471 int used_len;
4472 int total_len;
4473 } compat_priv_data;
4474 hdd_priv_data_t priv_data;
4475 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004476
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004477 /*
4478 * Note that pAdapter and ifr have already been verified by caller,
4479 * and HDD context has also been validated
4480 */
4481 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4482 sizeof(compat_priv_data))) {
4483 ret = -EFAULT;
4484 goto exit;
4485 }
4486 priv_data.buf = compat_ptr(compat_priv_data.buf);
4487 priv_data.used_len = compat_priv_data.used_len;
4488 priv_data.total_len = compat_priv_data.total_len;
4489 ret = hdd_driver_command(pAdapter, &priv_data);
4490 exit:
4491 return ret;
4492}
4493#else /* CONFIG_COMPAT */
4494static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4495{
4496 /* will never be invoked */
4497 return 0;
4498}
4499#endif /* CONFIG_COMPAT */
4500
4501static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4502{
4503 hdd_priv_data_t priv_data;
4504 int ret = 0;
4505
4506 /*
4507 * Note that pAdapter and ifr have already been verified by caller,
4508 * and HDD context has also been validated
4509 */
4510 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4511 ret = -EFAULT;
4512 } else {
4513 ret = hdd_driver_command(pAdapter, &priv_data);
4514 }
4515 return ret;
4516}
4517
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304518int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004519{
4520 hdd_adapter_t *pAdapter;
4521 hdd_context_t *pHddCtx;
4522 int ret;
4523
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304524 ENTER();
4525
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004526 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4527 if (NULL == pAdapter) {
4528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4529 "%s: HDD adapter context is Null", __func__);
4530 ret = -ENODEV;
4531 goto exit;
4532 }
4533 if (dev != pAdapter->dev) {
4534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4535 "%s: HDD adapter/dev inconsistency", __func__);
4536 ret = -ENODEV;
4537 goto exit;
4538 }
4539
4540 if ((!ifr) || (!ifr->ifr_data)) {
4541 ret = -EINVAL;
4542 goto exit;
4543 }
4544
4545 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4546 ret = wlan_hdd_validate_context(pHddCtx);
4547 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004548 ret = -EBUSY;
4549 goto exit;
4550 }
4551
4552 switch (cmd) {
4553 case (SIOCDEVPRIVATE + 1):
4554 if (is_compat_task())
4555 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4556 else
4557 ret = hdd_driver_ioctl(pAdapter, ifr);
4558 break;
4559 default:
4560 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4561 __func__, cmd);
4562 ret = -EINVAL;
4563 break;
4564 }
4565 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304566 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004567 return ret;
4568}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004569
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304570int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4571{
4572 int ret;
4573
4574 vos_ssr_protect(__func__);
4575 ret = __hdd_ioctl(dev, ifr, cmd);
4576 vos_ssr_unprotect(__func__);
4577
4578 return ret;
4579}
4580
Katya Nigame7b69a82015-04-28 15:24:06 +05304581int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4582{
4583 return 0;
4584}
4585
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004586#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004587/**---------------------------------------------------------------------------
4588
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004589 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004590
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004591 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004592 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4593 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4594 <space>Scan Mode N<space>Meas Duration N
4595 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4596 then take N.
4597 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4598 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4599 This function does not take care of removing duplicate channels from the list
4600
4601 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004602 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004603
4604 \return - 0 for success non-zero for failure
4605
4606 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004607static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4608 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004609{
4610 tANI_U8 *inPtr = pValue;
4611 int tempInt = 0;
4612 int j = 0, i = 0, v = 0;
4613 char buf[32];
4614
4615 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4616 /*no argument after the command*/
4617 if (NULL == inPtr)
4618 {
4619 return -EINVAL;
4620 }
4621 /*no space after the command*/
4622 else if (SPACE_ASCII_VALUE != *inPtr)
4623 {
4624 return -EINVAL;
4625 }
4626
4627 /*removing empty spaces*/
4628 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4629
4630 /*no argument followed by spaces*/
4631 if ('\0' == *inPtr) return -EINVAL;
4632
4633 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004634 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004635 if (1 != v) return -EINVAL;
4636
4637 v = kstrtos32(buf, 10, &tempInt);
4638 if ( v < 0) return -EINVAL;
4639
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004640 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004641
4642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004643 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004644
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004645 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004646 {
4647 for (i = 0; i < 4; i++)
4648 {
4649 /*inPtr pointing to the beginning of first space after number of ie fields*/
4650 inPtr = strpbrk( inPtr, " " );
4651 /*no ie data after the number of ie fields argument*/
4652 if (NULL == inPtr) return -EINVAL;
4653
4654 /*removing empty space*/
4655 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4656
4657 /*no ie data after the number of ie fields argument and spaces*/
4658 if ( '\0' == *inPtr ) return -EINVAL;
4659
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004660 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004661 if (1 != v) return -EINVAL;
4662
4663 v = kstrtos32(buf, 10, &tempInt);
4664 if (v < 0) return -EINVAL;
4665
4666 switch (i)
4667 {
4668 case 0: /* Measurement token */
4669 if (tempInt <= 0)
4670 {
4671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4672 "Invalid Measurement Token(%d)", tempInt);
4673 return -EINVAL;
4674 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004675 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004676 break;
4677
4678 case 1: /* Channel number */
4679 if ((tempInt <= 0) ||
4680 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4681 {
4682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4683 "Invalid Channel Number(%d)", tempInt);
4684 return -EINVAL;
4685 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004686 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004687 break;
4688
4689 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004690 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004691 {
4692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4693 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4694 return -EINVAL;
4695 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004696 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004697 break;
4698
4699 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004700 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4701 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004702 {
4703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4704 "Invalid Measurement Duration(%d)", tempInt);
4705 return -EINVAL;
4706 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004707 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004708 break;
4709 }
4710 }
4711 }
4712
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004713 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004714 {
4715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304716 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004717 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004718 pEseBcnReq->bcnReq[j].measurementToken,
4719 pEseBcnReq->bcnReq[j].channel,
4720 pEseBcnReq->bcnReq[j].scanMode,
4721 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004722 }
4723
4724 return VOS_STATUS_SUCCESS;
4725}
4726
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004727static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4728{
4729 struct statsContext *pStatsContext = NULL;
4730 hdd_adapter_t *pAdapter = NULL;
4731
4732 if (NULL == pContext)
4733 {
4734 hddLog(VOS_TRACE_LEVEL_ERROR,
4735 "%s: Bad param, pContext [%p]",
4736 __func__, pContext);
4737 return;
4738 }
4739
Jeff Johnson72a40512013-12-19 10:14:15 -08004740 /* there is a race condition that exists between this callback
4741 function and the caller since the caller could time out either
4742 before or while this code is executing. we use a spinlock to
4743 serialize these actions */
4744 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004745
4746 pStatsContext = pContext;
4747 pAdapter = pStatsContext->pAdapter;
4748 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4749 {
4750 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004751 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004752 hddLog(VOS_TRACE_LEVEL_WARN,
4753 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4754 __func__, pAdapter, pStatsContext->magic);
4755 return;
4756 }
4757
Jeff Johnson72a40512013-12-19 10:14:15 -08004758 /* context is valid so caller is still waiting */
4759
4760 /* paranoia: invalidate the magic */
4761 pStatsContext->magic = 0;
4762
4763 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004764 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4765 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4766 tsmMetrics.UplinkPktQueueDlyHist,
4767 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4768 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4769 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4770 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4771 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4772 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4773 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4774
Jeff Johnson72a40512013-12-19 10:14:15 -08004775 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004776 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004777
4778 /* serialization is complete */
4779 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004780}
4781
4782
4783
4784static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4785 tAniTrafStrmMetrics* pTsmMetrics)
4786{
4787 hdd_station_ctx_t *pHddStaCtx = NULL;
4788 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004789 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004790 long lrc;
4791 struct statsContext context;
4792 hdd_context_t *pHddCtx = NULL;
4793
4794 if (NULL == pAdapter)
4795 {
4796 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4797 return VOS_STATUS_E_FAULT;
4798 }
4799
4800 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4801 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4802
4803 /* we are connected prepare our callback context */
4804 init_completion(&context.completion);
4805 context.pAdapter = pAdapter;
4806 context.magic = STATS_CONTEXT_MAGIC;
4807
4808 /* query tsm stats */
4809 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4810 pHddStaCtx->conn_info.staId[ 0 ],
4811 pHddStaCtx->conn_info.bssId,
4812 &context, pHddCtx->pvosContext, tid);
4813
4814 if (eHAL_STATUS_SUCCESS != hstatus)
4815 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4817 __func__);
4818 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004819 }
4820 else
4821 {
4822 /* request was sent -- wait for the response */
4823 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4824 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004825 if (lrc <= 0)
4826 {
4827 hddLog(VOS_TRACE_LEVEL_ERROR,
4828 "%s: SME %s while retrieving statistics",
4829 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004830 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004831 }
4832 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004833
Jeff Johnson72a40512013-12-19 10:14:15 -08004834 /* either we never sent a request, we sent a request and received a
4835 response or we sent a request and timed out. if we never sent a
4836 request or if we sent a request and got a response, we want to
4837 clear the magic out of paranoia. if we timed out there is a
4838 race condition such that the callback function could be
4839 executing at the same time we are. of primary concern is if the
4840 callback function had already verified the "magic" but had not
4841 yet set the completion variable when a timeout occurred. we
4842 serialize these activities by invalidating the magic while
4843 holding a shared spinlock which will cause us to block if the
4844 callback is currently executing */
4845 spin_lock(&hdd_context_lock);
4846 context.magic = 0;
4847 spin_unlock(&hdd_context_lock);
4848
4849 if (VOS_STATUS_SUCCESS == vstatus)
4850 {
4851 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4852 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4853 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4854 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4855 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4856 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4857 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4858 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4859 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4860 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4861 }
4862 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004863}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004864#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004865
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004866#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004867void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4868{
4869 eCsrBand band = -1;
4870 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4871 switch (band)
4872 {
4873 case eCSR_BAND_ALL:
4874 *pBand = WLAN_HDD_UI_BAND_AUTO;
4875 break;
4876
4877 case eCSR_BAND_24:
4878 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4879 break;
4880
4881 case eCSR_BAND_5G:
4882 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4883 break;
4884
4885 default:
4886 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4887 *pBand = -1;
4888 break;
4889 }
4890}
4891
4892/**---------------------------------------------------------------------------
4893
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004894 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4895
4896 This function parses the send action frame data passed in the format
4897 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4898
Srinivas Girigowda56076852013-08-20 14:00:50 -07004899 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004900 \param - pTargetApBssid Pointer to target Ap bssid
4901 \param - pChannel Pointer to the Target AP channel
4902 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4903 \param - pBuf Pointer to data
4904 \param - pBufLen Pointer to data length
4905
4906 \return - 0 for success non-zero for failure
4907
4908 --------------------------------------------------------------------------*/
4909VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4910 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4911{
4912 tANI_U8 *inPtr = pValue;
4913 tANI_U8 *dataEnd;
4914 int tempInt;
4915 int j = 0;
4916 int i = 0;
4917 int v = 0;
4918 tANI_U8 tempBuf[32];
4919 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004920 /* 12 hexa decimal digits, 5 ':' and '\0' */
4921 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004922
4923 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4924 /*no argument after the command*/
4925 if (NULL == inPtr)
4926 {
4927 return -EINVAL;
4928 }
4929
4930 /*no space after the command*/
4931 else if (SPACE_ASCII_VALUE != *inPtr)
4932 {
4933 return -EINVAL;
4934 }
4935
4936 /*removing empty spaces*/
4937 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4938
4939 /*no argument followed by spaces*/
4940 if ('\0' == *inPtr)
4941 {
4942 return -EINVAL;
4943 }
4944
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004945 v = sscanf(inPtr, "%17s", macAddress);
4946 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004947 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4949 "Invalid MAC address or All hex inputs are not read (%d)", v);
4950 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004951 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004952
4953 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4954 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4955 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4956 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4957 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4958 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004959
4960 /* point to the next argument */
4961 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4962 /*no argument after the command*/
4963 if (NULL == inPtr) return -EINVAL;
4964
4965 /*removing empty spaces*/
4966 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4967
4968 /*no argument followed by spaces*/
4969 if ('\0' == *inPtr)
4970 {
4971 return -EINVAL;
4972 }
4973
4974 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004975 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004976 if (1 != v) return -EINVAL;
4977
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004978 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304979 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304980 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004981
4982 *pChannel = tempInt;
4983
4984 /* point to the next argument */
4985 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4986 /*no argument after the command*/
4987 if (NULL == inPtr) return -EINVAL;
4988 /*removing empty spaces*/
4989 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4990
4991 /*no argument followed by spaces*/
4992 if ('\0' == *inPtr)
4993 {
4994 return -EINVAL;
4995 }
4996
4997 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004998 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004999 if (1 != v) return -EINVAL;
5000
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005001 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005002 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005003
5004 *pDwellTime = tempInt;
5005
5006 /* point to the next argument */
5007 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5008 /*no argument after the command*/
5009 if (NULL == inPtr) return -EINVAL;
5010 /*removing empty spaces*/
5011 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5012
5013 /*no argument followed by spaces*/
5014 if ('\0' == *inPtr)
5015 {
5016 return -EINVAL;
5017 }
5018
5019 /* find the length of data */
5020 dataEnd = inPtr;
5021 while(('\0' != *dataEnd) )
5022 {
5023 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005024 }
Kiet Lambe150c22013-11-21 16:30:32 +05305025 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005026 if ( *pBufLen <= 0) return -EINVAL;
5027
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005028 /* Allocate the number of bytes based on the number of input characters
5029 whether it is even or odd.
5030 if the number of input characters are even, then we need N/2 byte.
5031 if the number of input characters are odd, then we need do (N+1)/2 to
5032 compensate rounding off.
5033 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5034 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5035 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005036 if (NULL == *pBuf)
5037 {
5038 hddLog(VOS_TRACE_LEVEL_FATAL,
5039 "%s: vos_mem_alloc failed ", __func__);
5040 return -EINVAL;
5041 }
5042
5043 /* the buffer received from the upper layer is character buffer,
5044 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5045 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5046 and f0 in 3rd location */
5047 for (i = 0, j = 0; j < *pBufLen; j += 2)
5048 {
Kiet Lambe150c22013-11-21 16:30:32 +05305049 if( j+1 == *pBufLen)
5050 {
5051 tempByte = hdd_parse_hex(inPtr[j]);
5052 }
5053 else
5054 {
5055 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5056 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005057 (*pBuf)[i++] = tempByte;
5058 }
5059 *pBufLen = i;
5060 return VOS_STATUS_SUCCESS;
5061}
5062
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005063/**---------------------------------------------------------------------------
5064
Srinivas Girigowdade697412013-02-14 16:31:48 -08005065 \brief hdd_parse_channellist() - HDD Parse channel list
5066
5067 This function parses the channel list passed in the format
5068 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005069 if the Number of channels (N) does not match with the actual number of channels passed
5070 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5071 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5072 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5073 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005074
5075 \param - pValue Pointer to input channel list
5076 \param - ChannelList Pointer to local output array to record channel list
5077 \param - pNumChannels Pointer to number of roam scan channels
5078
5079 \return - 0 for success non-zero for failure
5080
5081 --------------------------------------------------------------------------*/
5082VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5083{
5084 tANI_U8 *inPtr = pValue;
5085 int tempInt;
5086 int j = 0;
5087 int v = 0;
5088 char buf[32];
5089
5090 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5091 /*no argument after the command*/
5092 if (NULL == inPtr)
5093 {
5094 return -EINVAL;
5095 }
5096
5097 /*no space after the command*/
5098 else if (SPACE_ASCII_VALUE != *inPtr)
5099 {
5100 return -EINVAL;
5101 }
5102
5103 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005104 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005105
5106 /*no argument followed by spaces*/
5107 if ('\0' == *inPtr)
5108 {
5109 return -EINVAL;
5110 }
5111
5112 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005113 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005114 if (1 != v) return -EINVAL;
5115
Srinivas Girigowdade697412013-02-14 16:31:48 -08005116 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005117 if ((v < 0) ||
5118 (tempInt <= 0) ||
5119 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5120 {
5121 return -EINVAL;
5122 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005123
5124 *pNumChannels = tempInt;
5125
5126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5127 "Number of channels are: %d", *pNumChannels);
5128
5129 for (j = 0; j < (*pNumChannels); j++)
5130 {
5131 /*inPtr pointing to the beginning of first space after number of channels*/
5132 inPtr = strpbrk( inPtr, " " );
5133 /*no channel list after the number of channels argument*/
5134 if (NULL == inPtr)
5135 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005136 if (0 != j)
5137 {
5138 *pNumChannels = j;
5139 return VOS_STATUS_SUCCESS;
5140 }
5141 else
5142 {
5143 return -EINVAL;
5144 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005145 }
5146
5147 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005148 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005149
5150 /*no channel list after the number of channels argument and spaces*/
5151 if ( '\0' == *inPtr )
5152 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005153 if (0 != j)
5154 {
5155 *pNumChannels = j;
5156 return VOS_STATUS_SUCCESS;
5157 }
5158 else
5159 {
5160 return -EINVAL;
5161 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005162 }
5163
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005164 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005165 if (1 != v) return -EINVAL;
5166
Srinivas Girigowdade697412013-02-14 16:31:48 -08005167 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005168 if ((v < 0) ||
5169 (tempInt <= 0) ||
5170 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5171 {
5172 return -EINVAL;
5173 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005174 pChannelList[j] = tempInt;
5175
5176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5177 "Channel %d added to preferred channel list",
5178 pChannelList[j] );
5179 }
5180
Srinivas Girigowdade697412013-02-14 16:31:48 -08005181 return VOS_STATUS_SUCCESS;
5182}
5183
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005184
5185/**---------------------------------------------------------------------------
5186
5187 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5188
5189 This function parses the reasoc command data passed in the format
5190 REASSOC<space><bssid><space><channel>
5191
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005192 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005193 \param - pTargetApBssid Pointer to target Ap bssid
5194 \param - pChannel Pointer to the Target AP channel
5195
5196 \return - 0 for success non-zero for failure
5197
5198 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005199VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5200 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005201{
5202 tANI_U8 *inPtr = pValue;
5203 int tempInt;
5204 int v = 0;
5205 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005206 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005207 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005208
5209 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5210 /*no argument after the command*/
5211 if (NULL == inPtr)
5212 {
5213 return -EINVAL;
5214 }
5215
5216 /*no space after the command*/
5217 else if (SPACE_ASCII_VALUE != *inPtr)
5218 {
5219 return -EINVAL;
5220 }
5221
5222 /*removing empty spaces*/
5223 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5224
5225 /*no argument followed by spaces*/
5226 if ('\0' == *inPtr)
5227 {
5228 return -EINVAL;
5229 }
5230
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005231 v = sscanf(inPtr, "%17s", macAddress);
5232 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005233 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5235 "Invalid MAC address or All hex inputs are not read (%d)", v);
5236 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005237 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005238
5239 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5240 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5241 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5242 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5243 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5244 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005245
5246 /* point to the next argument */
5247 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5248 /*no argument after the command*/
5249 if (NULL == inPtr) return -EINVAL;
5250
5251 /*removing empty spaces*/
5252 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5253
5254 /*no argument followed by spaces*/
5255 if ('\0' == *inPtr)
5256 {
5257 return -EINVAL;
5258 }
5259
5260 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005261 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005262 if (1 != v) return -EINVAL;
5263
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005264 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005265 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305266 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005267 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5268 {
5269 return -EINVAL;
5270 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005271
5272 *pChannel = tempInt;
5273 return VOS_STATUS_SUCCESS;
5274}
5275
5276#endif
5277
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005278#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005279/**---------------------------------------------------------------------------
5280
5281 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5282
5283 This function parses the SETCCKM IE command
5284 SETCCKMIE<space><ie data>
5285
5286 \param - pValue Pointer to input data
5287 \param - pCckmIe Pointer to output cckm Ie
5288 \param - pCckmIeLen Pointer to output cckm ie length
5289
5290 \return - 0 for success non-zero for failure
5291
5292 --------------------------------------------------------------------------*/
5293VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5294 tANI_U8 *pCckmIeLen)
5295{
5296 tANI_U8 *inPtr = pValue;
5297 tANI_U8 *dataEnd;
5298 int j = 0;
5299 int i = 0;
5300 tANI_U8 tempByte = 0;
5301
5302 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5303 /*no argument after the command*/
5304 if (NULL == inPtr)
5305 {
5306 return -EINVAL;
5307 }
5308
5309 /*no space after the command*/
5310 else if (SPACE_ASCII_VALUE != *inPtr)
5311 {
5312 return -EINVAL;
5313 }
5314
5315 /*removing empty spaces*/
5316 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5317
5318 /*no argument followed by spaces*/
5319 if ('\0' == *inPtr)
5320 {
5321 return -EINVAL;
5322 }
5323
5324 /* find the length of data */
5325 dataEnd = inPtr;
5326 while(('\0' != *dataEnd) )
5327 {
5328 dataEnd++;
5329 ++(*pCckmIeLen);
5330 }
5331 if ( *pCckmIeLen <= 0) return -EINVAL;
5332
5333 /* Allocate the number of bytes based on the number of input characters
5334 whether it is even or odd.
5335 if the number of input characters are even, then we need N/2 byte.
5336 if the number of input characters are odd, then we need do (N+1)/2 to
5337 compensate rounding off.
5338 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5339 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5340 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5341 if (NULL == *pCckmIe)
5342 {
5343 hddLog(VOS_TRACE_LEVEL_FATAL,
5344 "%s: vos_mem_alloc failed ", __func__);
5345 return -EINVAL;
5346 }
5347 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5348 /* the buffer received from the upper layer is character buffer,
5349 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5350 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5351 and f0 in 3rd location */
5352 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5353 {
5354 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5355 (*pCckmIe)[i++] = tempByte;
5356 }
5357 *pCckmIeLen = i;
5358
5359 return VOS_STATUS_SUCCESS;
5360}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005361#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005362
Jeff Johnson295189b2012-06-20 16:38:30 -07005363/**---------------------------------------------------------------------------
5364
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005365 \brief hdd_is_valid_mac_address() - Validate MAC address
5366
5367 This function validates whether the given MAC address is valid or not
5368 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5369 where X is the hexa decimal digit character and separated by ':'
5370 This algorithm works even if MAC address is not separated by ':'
5371
5372 This code checks given input string mac contains exactly 12 hexadecimal digits.
5373 and a separator colon : appears in the input string only after
5374 an even number of hex digits.
5375
5376 \param - pMacAddr pointer to the input MAC address
5377 \return - 1 for valid and 0 for invalid
5378
5379 --------------------------------------------------------------------------*/
5380
5381v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5382{
5383 int xdigit = 0;
5384 int separator = 0;
5385 while (*pMacAddr)
5386 {
5387 if (isxdigit(*pMacAddr))
5388 {
5389 xdigit++;
5390 }
5391 else if (':' == *pMacAddr)
5392 {
5393 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5394 break;
5395
5396 ++separator;
5397 }
5398 else
5399 {
5400 separator = -1;
5401 /* Invalid MAC found */
5402 return 0;
5403 }
5404 ++pMacAddr;
5405 }
5406 return (xdigit == 12 && (separator == 5 || separator == 0));
5407}
5408
5409/**---------------------------------------------------------------------------
5410
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305411 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005412
5413 \param - dev Pointer to net_device structure
5414
5415 \return - 0 for success non-zero for failure
5416
5417 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305418int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005419{
5420 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5421 hdd_context_t *pHddCtx;
5422 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5423 VOS_STATUS status;
5424 v_BOOL_t in_standby = TRUE;
5425
5426 if (NULL == pAdapter)
5427 {
5428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305429 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005430 return -ENODEV;
5431 }
5432
5433 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305434 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5435 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005436 if (NULL == pHddCtx)
5437 {
5438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005439 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 return -ENODEV;
5441 }
5442
5443 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5444 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5445 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005446 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5447 {
5448 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305449 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005450 in_standby = FALSE;
5451 break;
5452 }
5453 else
5454 {
5455 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5456 pAdapterNode = pNext;
5457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005458 }
5459
5460 if (TRUE == in_standby)
5461 {
5462 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5463 {
5464 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5465 "wlan out of power save", __func__);
5466 return -EINVAL;
5467 }
5468 }
5469
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005470 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005471 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5472 {
5473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005474 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005475 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305476 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 netif_tx_start_all_queues(dev);
5478 }
5479
5480 return 0;
5481}
5482
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305483/**---------------------------------------------------------------------------
5484
5485 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5486
5487 This is called in response to ifconfig up
5488
5489 \param - dev Pointer to net_device structure
5490
5491 \return - 0 for success non-zero for failure
5492
5493 --------------------------------------------------------------------------*/
5494int hdd_open(struct net_device *dev)
5495{
5496 int ret;
5497
5498 vos_ssr_protect(__func__);
5499 ret = __hdd_open(dev);
5500 vos_ssr_unprotect(__func__);
5501
5502 return ret;
5503}
5504
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305505int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005506{
5507 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5508
5509 if(pAdapter == NULL) {
5510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005511 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005512 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 }
5514
Jeff Johnson295189b2012-06-20 16:38:30 -07005515 return 0;
5516}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305517
5518int hdd_mon_open (struct net_device *dev)
5519{
5520 int ret;
5521
5522 vos_ssr_protect(__func__);
5523 ret = __hdd_mon_open(dev);
5524 vos_ssr_unprotect(__func__);
5525
5526 return ret;
5527}
5528
Katya Nigame7b69a82015-04-28 15:24:06 +05305529int hdd_mon_stop(struct net_device *dev)
5530{
5531 return 0;
5532}
5533
Jeff Johnson295189b2012-06-20 16:38:30 -07005534/**---------------------------------------------------------------------------
5535
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305536 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005537
5538 \param - dev Pointer to net_device structure
5539
5540 \return - 0 for success non-zero for failure
5541
5542 --------------------------------------------------------------------------*/
5543
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305544int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005545{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305546 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005547 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5548 hdd_context_t *pHddCtx;
5549 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5550 VOS_STATUS status;
5551 v_BOOL_t enter_standby = TRUE;
5552
5553 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 if (NULL == pAdapter)
5555 {
5556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305557 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 return -ENODEV;
5559 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305560 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305561 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305562
5563 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5564 ret = wlan_hdd_validate_context(pHddCtx);
5565 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305567 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005568 }
5569
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305570 /* Nothing to be done if the interface is not opened */
5571 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5572 {
5573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5574 "%s: NETDEV Interface is not OPENED", __func__);
5575 return -ENODEV;
5576 }
5577
5578 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005579 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005580 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305581
5582 /* Disable TX on the interface, after this hard_start_xmit() will not
5583 * be called on that interface
5584 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305585 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305587
5588 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005589 netif_carrier_off(pAdapter->dev);
5590
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305591 /* The interface is marked as down for outside world (aka kernel)
5592 * But the driver is pretty much alive inside. The driver needs to
5593 * tear down the existing connection on the netdev (session)
5594 * cleanup the data pipes and wait until the control plane is stabilized
5595 * for this interface. The call also needs to wait until the above
5596 * mentioned actions are completed before returning to the caller.
5597 * Notice that the hdd_stop_adapter is requested not to close the session
5598 * That is intentional to be able to scan if it is a STA/P2P interface
5599 */
5600 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305601#ifdef FEATURE_WLAN_TDLS
5602 mutex_lock(&pHddCtx->tdls_lock);
5603#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305604 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305605 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305606#ifdef FEATURE_WLAN_TDLS
5607 mutex_unlock(&pHddCtx->tdls_lock);
5608#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 /* SoftAP ifaces should never go in power save mode
5610 making sure same here. */
5611 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5612 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005613 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 )
5615 {
5616 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5618 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 EXIT();
5620 return 0;
5621 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305622 /* Find if any iface is up. If any iface is up then can't put device to
5623 * sleep/power save mode
5624 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5626 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5627 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005628 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5629 {
5630 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305631 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005632 enter_standby = FALSE;
5633 break;
5634 }
5635 else
5636 {
5637 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5638 pAdapterNode = pNext;
5639 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 }
5641
5642 if (TRUE == enter_standby)
5643 {
5644 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5645 "entering standby", __func__);
5646 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5647 {
5648 /*log and return success*/
5649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5650 "wlan in power save", __func__);
5651 }
5652 }
5653
5654 EXIT();
5655 return 0;
5656}
5657
5658/**---------------------------------------------------------------------------
5659
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305660 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005661
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305662 This is called in response to ifconfig down
5663
5664 \param - dev Pointer to net_device structure
5665
5666 \return - 0 for success non-zero for failure
5667-----------------------------------------------------------------------------*/
5668int hdd_stop (struct net_device *dev)
5669{
5670 int ret;
5671
5672 vos_ssr_protect(__func__);
5673 ret = __hdd_stop(dev);
5674 vos_ssr_unprotect(__func__);
5675
5676 return ret;
5677}
5678
5679/**---------------------------------------------------------------------------
5680
5681 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005682
5683 \param - dev Pointer to net_device structure
5684
5685 \return - void
5686
5687 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305688static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005689{
5690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305691 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 ENTER();
5693
5694 do
5695 {
5696 if (NULL == pAdapter)
5697 {
5698 hddLog(VOS_TRACE_LEVEL_FATAL,
5699 "%s: NULL pAdapter", __func__);
5700 break;
5701 }
5702
5703 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5704 {
5705 hddLog(VOS_TRACE_LEVEL_FATAL,
5706 "%s: Invalid magic", __func__);
5707 break;
5708 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305709 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5710 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005711 {
5712 hddLog(VOS_TRACE_LEVEL_FATAL,
5713 "%s: NULL pHddCtx", __func__);
5714 break;
5715 }
5716
5717 if (dev != pAdapter->dev)
5718 {
5719 hddLog(VOS_TRACE_LEVEL_FATAL,
5720 "%s: Invalid device reference", __func__);
5721 /* we haven't validated all cases so let this go for now */
5722 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305723#ifdef FEATURE_WLAN_TDLS
5724 mutex_lock(&pHddCtx->tdls_lock);
5725#endif
c_hpothu002231a2015-02-05 14:58:51 +05305726 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305727#ifdef FEATURE_WLAN_TDLS
5728 mutex_unlock(&pHddCtx->tdls_lock);
5729#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005730
5731 /* after uninit our adapter structure will no longer be valid */
5732 pAdapter->dev = NULL;
5733 pAdapter->magic = 0;
5734 } while (0);
5735
5736 EXIT();
5737}
5738
5739/**---------------------------------------------------------------------------
5740
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305741 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5742
5743 This is called during the netdev unregister to uninitialize all data
5744associated with the device
5745
5746 \param - dev Pointer to net_device structure
5747
5748 \return - void
5749
5750 --------------------------------------------------------------------------*/
5751static void hdd_uninit (struct net_device *dev)
5752{
5753 vos_ssr_protect(__func__);
5754 __hdd_uninit(dev);
5755 vos_ssr_unprotect(__func__);
5756}
5757
5758/**---------------------------------------------------------------------------
5759
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 \brief hdd_release_firmware() -
5761
5762 This function calls the release firmware API to free the firmware buffer.
5763
5764 \param - pFileName Pointer to the File Name.
5765 pCtx - Pointer to the adapter .
5766
5767
5768 \return - 0 for success, non zero for failure
5769
5770 --------------------------------------------------------------------------*/
5771
5772VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5773{
5774 VOS_STATUS status = VOS_STATUS_SUCCESS;
5775 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5776 ENTER();
5777
5778
5779 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5780
5781 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5782
5783 if(pHddCtx->fw) {
5784 release_firmware(pHddCtx->fw);
5785 pHddCtx->fw = NULL;
5786 }
5787 else
5788 status = VOS_STATUS_E_FAILURE;
5789 }
5790 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5791 if(pHddCtx->nv) {
5792 release_firmware(pHddCtx->nv);
5793 pHddCtx->nv = NULL;
5794 }
5795 else
5796 status = VOS_STATUS_E_FAILURE;
5797
5798 }
5799
5800 EXIT();
5801 return status;
5802}
5803
5804/**---------------------------------------------------------------------------
5805
5806 \brief hdd_request_firmware() -
5807
5808 This function reads the firmware file using the request firmware
5809 API and returns the the firmware data and the firmware file size.
5810
5811 \param - pfileName - Pointer to the file name.
5812 - pCtx - Pointer to the adapter .
5813 - ppfw_data - Pointer to the pointer of the firmware data.
5814 - pSize - Pointer to the file size.
5815
5816 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5817
5818 --------------------------------------------------------------------------*/
5819
5820
5821VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5822{
5823 int status;
5824 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5825 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5826 ENTER();
5827
5828 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5829
5830 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5831
5832 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5833 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5834 __func__, pfileName);
5835 retval = VOS_STATUS_E_FAILURE;
5836 }
5837
5838 else {
5839 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5840 *pSize = pHddCtx->fw->size;
5841 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5842 __func__, *pSize);
5843 }
5844 }
5845 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5846
5847 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5848
5849 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5850 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5851 __func__, pfileName);
5852 retval = VOS_STATUS_E_FAILURE;
5853 }
5854
5855 else {
5856 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5857 *pSize = pHddCtx->nv->size;
5858 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5859 __func__, *pSize);
5860 }
5861 }
5862
5863 EXIT();
5864 return retval;
5865}
5866/**---------------------------------------------------------------------------
5867 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5868
5869 This is the function invoked by SME to inform the result of a full power
5870 request issued by HDD
5871
5872 \param - callbackcontext - Pointer to cookie
5873 status - result of request
5874
5875 \return - None
5876
5877--------------------------------------------------------------------------*/
5878void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5879{
5880 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5881
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005882 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005883 if(&pHddCtx->full_pwr_comp_var)
5884 {
5885 complete(&pHddCtx->full_pwr_comp_var);
5886 }
5887}
5888
5889/**---------------------------------------------------------------------------
5890
5891 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5892
5893 This is the function invoked by SME to inform the result of BMPS
5894 request issued by HDD
5895
5896 \param - callbackcontext - Pointer to cookie
5897 status - result of request
5898
5899 \return - None
5900
5901--------------------------------------------------------------------------*/
5902void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5903{
5904
5905 struct completion *completion_var = (struct completion*) callbackContext;
5906
Arif Hussain6d2a3322013-11-17 19:50:10 -08005907 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 if(completion_var != NULL)
5909 {
5910 complete(completion_var);
5911 }
5912}
5913
5914/**---------------------------------------------------------------------------
5915
5916 \brief hdd_get_cfg_file_size() -
5917
5918 This function reads the configuration file using the request firmware
5919 API and returns the configuration file size.
5920
5921 \param - pCtx - Pointer to the adapter .
5922 - pFileName - Pointer to the file name.
5923 - pBufSize - Pointer to the buffer size.
5924
5925 \return - 0 for success, non zero for failure
5926
5927 --------------------------------------------------------------------------*/
5928
5929VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5930{
5931 int status;
5932 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5933
5934 ENTER();
5935
5936 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5937
5938 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5939 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5940 status = VOS_STATUS_E_FAILURE;
5941 }
5942 else {
5943 *pBufSize = pHddCtx->fw->size;
5944 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5945 release_firmware(pHddCtx->fw);
5946 pHddCtx->fw = NULL;
5947 }
5948
5949 EXIT();
5950 return VOS_STATUS_SUCCESS;
5951}
5952
5953/**---------------------------------------------------------------------------
5954
5955 \brief hdd_read_cfg_file() -
5956
5957 This function reads the configuration file using the request firmware
5958 API and returns the cfg data and the buffer size of the configuration file.
5959
5960 \param - pCtx - Pointer to the adapter .
5961 - pFileName - Pointer to the file name.
5962 - pBuffer - Pointer to the data buffer.
5963 - pBufSize - Pointer to the buffer size.
5964
5965 \return - 0 for success, non zero for failure
5966
5967 --------------------------------------------------------------------------*/
5968
5969VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5970 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5971{
5972 int status;
5973 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5974
5975 ENTER();
5976
5977 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5978
5979 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5980 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5981 return VOS_STATUS_E_FAILURE;
5982 }
5983 else {
5984 if(*pBufSize != pHddCtx->fw->size) {
5985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5986 "file size", __func__);
5987 release_firmware(pHddCtx->fw);
5988 pHddCtx->fw = NULL;
5989 return VOS_STATUS_E_FAILURE;
5990 }
5991 else {
5992 if(pBuffer) {
5993 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5994 }
5995 release_firmware(pHddCtx->fw);
5996 pHddCtx->fw = NULL;
5997 }
5998 }
5999
6000 EXIT();
6001
6002 return VOS_STATUS_SUCCESS;
6003}
6004
6005/**---------------------------------------------------------------------------
6006
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306007 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006008
6009 This function sets the user specified mac address using
6010 the command ifconfig wlanX hw ether <mac adress>.
6011
6012 \param - dev - Pointer to the net device.
6013 - addr - Pointer to the sockaddr.
6014 \return - 0 for success, non zero for failure
6015
6016 --------------------------------------------------------------------------*/
6017
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306018static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006019{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306020 hdd_adapter_t *pAdapter;
6021 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006022 struct sockaddr *psta_mac_addr = addr;
6023 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306024 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006025
6026 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306027 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6028 if (NULL == pAdapter)
6029 {
6030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6031 "%s: Adapter is NULL",__func__);
6032 return -EINVAL;
6033 }
6034 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6035 ret = wlan_hdd_validate_context(pHddCtx);
6036 if (0 != ret)
6037 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306038 return ret;
6039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006040
6041 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6043
6044 EXIT();
6045 return halStatus;
6046}
6047
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306048/**---------------------------------------------------------------------------
6049
6050 \brief hdd_set_mac_address() -
6051
6052 Wrapper function to protect __hdd_set_mac_address() function from ssr
6053
6054 \param - dev - Pointer to the net device.
6055 - addr - Pointer to the sockaddr.
6056 \return - 0 for success, non zero for failure
6057
6058 --------------------------------------------------------------------------*/
6059static int hdd_set_mac_address(struct net_device *dev, void *addr)
6060{
6061 int ret;
6062
6063 vos_ssr_protect(__func__);
6064 ret = __hdd_set_mac_address(dev, addr);
6065 vos_ssr_unprotect(__func__);
6066
6067 return ret;
6068}
6069
Jeff Johnson295189b2012-06-20 16:38:30 -07006070tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6071{
6072 int i;
6073 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6074 {
Abhishek Singheb183782014-02-06 13:37:21 +05306075 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006076 break;
6077 }
6078
6079 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6080 return NULL;
6081
6082 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6083 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6084}
6085
6086void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6087{
6088 int i;
6089 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6090 {
6091 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6092 {
6093 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6094 break;
6095 }
6096 }
6097 return;
6098}
6099
6100#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6101 static struct net_device_ops wlan_drv_ops = {
6102 .ndo_open = hdd_open,
6103 .ndo_stop = hdd_stop,
6104 .ndo_uninit = hdd_uninit,
6105 .ndo_start_xmit = hdd_hard_start_xmit,
6106 .ndo_tx_timeout = hdd_tx_timeout,
6107 .ndo_get_stats = hdd_stats,
6108 .ndo_do_ioctl = hdd_ioctl,
6109 .ndo_set_mac_address = hdd_set_mac_address,
6110 .ndo_select_queue = hdd_select_queue,
6111#ifdef WLAN_FEATURE_PACKET_FILTERING
6112#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6113 .ndo_set_rx_mode = hdd_set_multicast_list,
6114#else
6115 .ndo_set_multicast_list = hdd_set_multicast_list,
6116#endif //LINUX_VERSION_CODE
6117#endif
6118 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 static struct net_device_ops wlan_mon_drv_ops = {
6120 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306121 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006122 .ndo_uninit = hdd_uninit,
6123 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6124 .ndo_tx_timeout = hdd_tx_timeout,
6125 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306126 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 .ndo_set_mac_address = hdd_set_mac_address,
6128 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306129
Jeff Johnson295189b2012-06-20 16:38:30 -07006130#endif
6131
6132void hdd_set_station_ops( struct net_device *pWlanDev )
6133{
6134#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006135 pWlanDev->netdev_ops = &wlan_drv_ops;
6136#else
6137 pWlanDev->open = hdd_open;
6138 pWlanDev->stop = hdd_stop;
6139 pWlanDev->uninit = hdd_uninit;
6140 pWlanDev->hard_start_xmit = NULL;
6141 pWlanDev->tx_timeout = hdd_tx_timeout;
6142 pWlanDev->get_stats = hdd_stats;
6143 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006144 pWlanDev->set_mac_address = hdd_set_mac_address;
6145#endif
6146}
6147
Katya Nigam1fd24402015-02-16 14:52:19 +05306148void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6149{
6150 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6151 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6152 #else
6153 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6154 #endif
6155}
6156
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006157static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006158{
6159 struct net_device *pWlanDev = NULL;
6160 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006161 /*
6162 * cfg80211 initialization and registration....
6163 */
6164 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6165
Jeff Johnson295189b2012-06-20 16:38:30 -07006166 if(pWlanDev != NULL)
6167 {
6168
6169 //Save the pointer to the net_device in the HDD adapter
6170 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6171
Jeff Johnson295189b2012-06-20 16:38:30 -07006172 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6173
6174 pAdapter->dev = pWlanDev;
6175 pAdapter->pHddCtx = pHddCtx;
6176 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306177 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006178
6179 init_completion(&pAdapter->session_open_comp_var);
6180 init_completion(&pAdapter->session_close_comp_var);
6181 init_completion(&pAdapter->disconnect_comp_var);
6182 init_completion(&pAdapter->linkup_event_var);
6183 init_completion(&pAdapter->cancel_rem_on_chan_var);
6184 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306185 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6187 init_completion(&pAdapter->offchannel_tx_event);
6188#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006189 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006190#ifdef FEATURE_WLAN_TDLS
6191 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006192 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006193 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306194 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006195#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006196 init_completion(&pHddCtx->mc_sus_event_var);
6197 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306198 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006199 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006200 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006201
Rajeev79dbe4c2013-10-05 11:03:42 +05306202#ifdef FEATURE_WLAN_BATCH_SCAN
6203 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6204 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6205 pAdapter->pBatchScanRsp = NULL;
6206 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006207 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006208 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306209 mutex_init(&pAdapter->hdd_batch_scan_lock);
6210#endif
6211
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 pAdapter->isLinkUpSvcNeeded = FALSE;
6213 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6214 //Init the net_device structure
6215 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6216
6217 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6218 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6219 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6220 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6221
6222 hdd_set_station_ops( pAdapter->dev );
6223
6224 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6226 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6227 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 /* set pWlanDev's parent to underlying device */
6229 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006230
6231 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 }
6233
6234 return pAdapter;
6235}
6236
6237VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6238{
6239 struct net_device *pWlanDev = pAdapter->dev;
6240 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6241 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6242 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6243
6244 if( rtnl_lock_held )
6245 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006246 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6248 {
6249 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6250 return VOS_STATUS_E_FAILURE;
6251 }
6252 }
6253 if (register_netdevice(pWlanDev))
6254 {
6255 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6256 return VOS_STATUS_E_FAILURE;
6257 }
6258 }
6259 else
6260 {
6261 if(register_netdev(pWlanDev))
6262 {
6263 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6264 return VOS_STATUS_E_FAILURE;
6265 }
6266 }
6267 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6268
6269 return VOS_STATUS_SUCCESS;
6270}
6271
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006272static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006273{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006274 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006275
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006276 if (NULL == pAdapter)
6277 {
6278 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6279 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006281
6282 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6283 {
6284 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6285 return eHAL_STATUS_NOT_INITIALIZED;
6286 }
6287
6288 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6289
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006290#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006291 /* need to make sure all of our scheduled work has completed.
6292 * This callback is called from MC thread context, so it is safe to
6293 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006294 *
6295 * Even though this is called from MC thread context, if there is a faulty
6296 * work item in the system, that can hang this call forever. So flushing
6297 * this global work queue is not safe; and now we make sure that
6298 * individual work queues are stopped correctly. But the cancel work queue
6299 * is a GPL only API, so the proprietary version of the driver would still
6300 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006301 */
6302 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006303#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006304
6305 /* We can be blocked while waiting for scheduled work to be
6306 * flushed, and the adapter structure can potentially be freed, in
6307 * which case the magic will have been reset. So make sure the
6308 * magic is still good, and hence the adapter structure is still
6309 * valid, before signaling completion */
6310 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6311 {
6312 complete(&pAdapter->session_close_comp_var);
6313 }
6314
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 return eHAL_STATUS_SUCCESS;
6316}
6317
6318VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6319{
6320 struct net_device *pWlanDev = pAdapter->dev;
6321 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6322 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6323 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6324 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306325 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006326
Nirav Shah7e3c8132015-06-22 23:51:42 +05306327 spin_lock_init( &pAdapter->sta_hash_lock);
6328 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6329
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006331 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006332 //Open a SME session for future operation
6333 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006334 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006335 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6336 {
6337 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006338 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006339 halStatus, halStatus );
6340 status = VOS_STATUS_E_FAILURE;
6341 goto error_sme_open;
6342 }
6343
6344 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306345 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 &pAdapter->session_open_comp_var,
6347 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306348 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 {
6350 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306351 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 status = VOS_STATUS_E_FAILURE;
6353 goto error_sme_open;
6354 }
6355
6356 // Register wireless extensions
6357 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6358 {
6359 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006360 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 halStatus, halStatus );
6362 status = VOS_STATUS_E_FAILURE;
6363 goto error_register_wext;
6364 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306365
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306367 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6368 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6369 #else
6370 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6371 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006372
6373 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306374 hddLog(VOS_TRACE_LEVEL_INFO,
6375 "%s: Set HDD connState to eConnectionState_NotConnected",
6376 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6378
6379 //Set the default operation channel
6380 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6381
6382 /* Make the default Auth Type as OPEN*/
6383 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6384
6385 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6386 {
6387 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006388 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 status, status );
6390 goto error_init_txrx;
6391 }
6392
6393 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6394
6395 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6396 {
6397 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006398 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006399 status, status );
6400 goto error_wmm_init;
6401 }
6402
6403 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6404
6405 return VOS_STATUS_SUCCESS;
6406
6407error_wmm_init:
6408 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6409 hdd_deinit_tx_rx(pAdapter);
6410error_init_txrx:
6411 hdd_UnregisterWext(pWlanDev);
6412error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006413 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 {
6415 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006416 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306417 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006418 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306420 unsigned long rc;
6421
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306423 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006425 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306426 if (rc <= 0)
6427 hddLog(VOS_TRACE_LEVEL_ERROR,
6428 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006429 }
6430}
6431error_sme_open:
6432 return status;
6433}
6434
Jeff Johnson295189b2012-06-20 16:38:30 -07006435void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6436{
6437 hdd_cfg80211_state_t *cfgState;
6438
6439 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6440
6441 if( NULL != cfgState->buf )
6442 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306443 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006444 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6445 rc = wait_for_completion_interruptible_timeout(
6446 &pAdapter->tx_action_cnf_event,
6447 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306448 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006449 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306451 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6452 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 }
6454 }
6455 return;
6456}
Jeff Johnson295189b2012-06-20 16:38:30 -07006457
c_hpothu002231a2015-02-05 14:58:51 +05306458void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006459{
6460 ENTER();
6461 switch ( pAdapter->device_mode )
6462 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306463 case WLAN_HDD_IBSS:
6464 {
6465 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6466 {
6467 hdd_ibss_deinit_tx_rx( pAdapter );
6468 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6469 }
6470 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 case WLAN_HDD_INFRA_STATION:
6472 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006473 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006474 {
6475 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6476 {
6477 hdd_deinit_tx_rx( pAdapter );
6478 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6479 }
6480
6481 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6482 {
6483 hdd_wmm_adapter_close( pAdapter );
6484 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6485 }
6486
Jeff Johnson295189b2012-06-20 16:38:30 -07006487 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006488 break;
6489 }
6490
6491 case WLAN_HDD_SOFTAP:
6492 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306494
6495 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6496 {
6497 hdd_wmm_adapter_close( pAdapter );
6498 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6499 }
6500
Jeff Johnson295189b2012-06-20 16:38:30 -07006501 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006502
c_hpothu002231a2015-02-05 14:58:51 +05306503 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 break;
6506 }
6507
6508 case WLAN_HDD_MONITOR:
6509 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006510 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6511 {
6512 hdd_deinit_tx_rx( pAdapter );
6513 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6514 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006515 break;
6516 }
6517
6518
6519 default:
6520 break;
6521 }
6522
6523 EXIT();
6524}
6525
6526void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6527{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006528 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306529
6530 ENTER();
6531 if (NULL == pAdapter)
6532 {
6533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6534 "%s: HDD adapter is Null", __func__);
6535 return;
6536 }
6537
6538 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006539
Rajeev79dbe4c2013-10-05 11:03:42 +05306540#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306541 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6542 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006543 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306544 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6545 )
6546 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006547 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306548 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006549 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6550 {
6551 hdd_deinit_batch_scan(pAdapter);
6552 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306553 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006554 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306555#endif
6556
Jeff Johnson295189b2012-06-20 16:38:30 -07006557 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6558 if( rtnl_held )
6559 {
6560 unregister_netdevice(pWlanDev);
6561 }
6562 else
6563 {
6564 unregister_netdev(pWlanDev);
6565 }
6566 // note that the pAdapter is no longer valid at this point
6567 // since the memory has been reclaimed
6568 }
6569
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306570 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006571}
6572
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006573void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6574{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306575 VOS_STATUS status;
6576 hdd_adapter_t *pAdapter = NULL;
6577 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006578
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306579 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006580
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306581 /*loop through all adapters.*/
6582 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006583 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306584 pAdapter = pAdapterNode->pAdapter;
6585 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6586 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006587
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306588 { // we skip this registration for modes other than STA and P2P client modes.
6589 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6590 pAdapterNode = pNext;
6591 continue;
6592 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006593
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306594 //Apply Dynamic DTIM For P2P
6595 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6596 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6597 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6598 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6599 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6600 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6601 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6602 (eConnectionState_Associated ==
6603 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6604 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6605 {
6606 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006607
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306608 powerRequest.uIgnoreDTIM = 1;
6609 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6610
6611 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6612 {
6613 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6614 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6615 }
6616 else
6617 {
6618 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6619 }
6620
6621 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6622 * specified during Enter/Exit BMPS when LCD off*/
6623 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6624 NULL, eANI_BOOLEAN_FALSE);
6625 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6626 NULL, eANI_BOOLEAN_FALSE);
6627
6628 /* switch to the DTIM specified in cfg.ini */
6629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6630 "Switch to DTIM %d", powerRequest.uListenInterval);
6631 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6632 break;
6633
6634 }
6635
6636 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6637 pAdapterNode = pNext;
6638 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006639}
6640
6641void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6642{
6643 /*Switch back to DTIM 1*/
6644 tSirSetPowerParamsReq powerRequest = { 0 };
6645
6646 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6647 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006648 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006649
6650 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6651 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6652 NULL, eANI_BOOLEAN_FALSE);
6653 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6654 NULL, eANI_BOOLEAN_FALSE);
6655
6656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6657 "Switch to DTIM%d",powerRequest.uListenInterval);
6658 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6659
6660}
6661
Jeff Johnson295189b2012-06-20 16:38:30 -07006662VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6663{
6664 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306665 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6666 {
6667 hddLog( LOGE, FL("Wlan Unload in progress"));
6668 return VOS_STATUS_E_PERM;
6669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006670 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6671 {
6672 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6673 }
6674
6675 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6676 {
6677 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6678 }
6679
6680 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6681 {
6682 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6683 }
6684
6685 return status;
6686}
6687
6688VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6689{
6690 hdd_adapter_t *pAdapter = NULL;
6691 eHalStatus halStatus;
6692 VOS_STATUS status = VOS_STATUS_E_INVAL;
6693 v_BOOL_t disableBmps = FALSE;
6694 v_BOOL_t disableImps = FALSE;
6695
6696 switch(session_type)
6697 {
6698 case WLAN_HDD_INFRA_STATION:
6699 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006700 case WLAN_HDD_P2P_CLIENT:
6701 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 //Exit BMPS -> Is Sta/P2P Client is already connected
6703 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6704 if((NULL != pAdapter)&&
6705 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6706 {
6707 disableBmps = TRUE;
6708 }
6709
6710 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6711 if((NULL != pAdapter)&&
6712 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6713 {
6714 disableBmps = TRUE;
6715 }
6716
6717 //Exit both Bmps and Imps incase of Go/SAP Mode
6718 if((WLAN_HDD_SOFTAP == session_type) ||
6719 (WLAN_HDD_P2P_GO == session_type))
6720 {
6721 disableBmps = TRUE;
6722 disableImps = TRUE;
6723 }
6724
6725 if(TRUE == disableImps)
6726 {
6727 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6728 {
6729 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6730 }
6731 }
6732
6733 if(TRUE == disableBmps)
6734 {
6735 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6736 {
6737 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6738
6739 if(eHAL_STATUS_SUCCESS != halStatus)
6740 {
6741 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006742 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 VOS_ASSERT(0);
6744 return status;
6745 }
6746 }
6747
6748 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6749 {
6750 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6751
6752 if(eHAL_STATUS_SUCCESS != halStatus)
6753 {
6754 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006755 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006756 VOS_ASSERT(0);
6757 return status;
6758 }
6759 }
6760 }
6761
6762 if((TRUE == disableBmps) ||
6763 (TRUE == disableImps))
6764 {
6765 /* Now, get the chip into Full Power now */
6766 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6767 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6768 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6769
6770 if(halStatus != eHAL_STATUS_SUCCESS)
6771 {
6772 if(halStatus == eHAL_STATUS_PMC_PENDING)
6773 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306774 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006775 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306776 ret = wait_for_completion_interruptible_timeout(
6777 &pHddCtx->full_pwr_comp_var,
6778 msecs_to_jiffies(1000));
6779 if (ret <= 0)
6780 {
6781 hddLog(VOS_TRACE_LEVEL_ERROR,
6782 "%s: wait on full_pwr_comp_var failed %ld",
6783 __func__, ret);
6784 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006785 }
6786 else
6787 {
6788 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006789 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 VOS_ASSERT(0);
6791 return status;
6792 }
6793 }
6794
6795 status = VOS_STATUS_SUCCESS;
6796 }
6797
6798 break;
6799 }
6800 return status;
6801}
Katya Nigame7b69a82015-04-28 15:24:06 +05306802void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6803 {
6804 hdd_mon_ctx_t *pMonCtx = NULL;
6805 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6806
6807 pMonCtx->state = 0;
6808 pMonCtx->ChannelNo = 1;
6809 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306810 pMonCtx->crcCheckEnabled = 1;
6811 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6812 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306813 pMonCtx->numOfMacFilters = 0;
6814 }
6815
Jeff Johnson295189b2012-06-20 16:38:30 -07006816
6817hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006818 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006819 tANI_U8 rtnl_held )
6820{
6821 hdd_adapter_t *pAdapter = NULL;
6822 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6823 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6824 VOS_STATUS exitbmpsStatus;
6825
Arif Hussain6d2a3322013-11-17 19:50:10 -08006826 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006827
Nirav Shah436658f2014-02-28 17:05:45 +05306828 if(macAddr == NULL)
6829 {
6830 /* Not received valid macAddr */
6831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6832 "%s:Unable to add virtual intf: Not able to get"
6833 "valid mac address",__func__);
6834 return NULL;
6835 }
6836
Jeff Johnson295189b2012-06-20 16:38:30 -07006837 //Disable BMPS incase of Concurrency
6838 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6839
6840 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6841 {
6842 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306843 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 VOS_ASSERT(0);
6845 return NULL;
6846 }
6847
6848 switch(session_type)
6849 {
6850 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006852 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 {
6854 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6855
6856 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306857 {
6858 hddLog(VOS_TRACE_LEVEL_FATAL,
6859 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006860 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306861 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006862
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306863#ifdef FEATURE_WLAN_TDLS
6864 /* A Mutex Lock is introduced while changing/initializing the mode to
6865 * protect the concurrent access for the Adapters by TDLS module.
6866 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306867 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306868#endif
6869
Jeff Johnsone7245742012-09-05 17:12:55 -07006870 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6871 NL80211_IFTYPE_P2P_CLIENT:
6872 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006873
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306875#ifdef FEATURE_WLAN_TDLS
6876 mutex_unlock(&pHddCtx->tdls_lock);
6877#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306878
6879 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006880 if( VOS_STATUS_SUCCESS != status )
6881 goto err_free_netdev;
6882
6883 status = hdd_register_interface( pAdapter, rtnl_held );
6884 if( VOS_STATUS_SUCCESS != status )
6885 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306886#ifdef FEATURE_WLAN_TDLS
6887 mutex_lock(&pHddCtx->tdls_lock);
6888#endif
c_hpothu002231a2015-02-05 14:58:51 +05306889 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306890#ifdef FEATURE_WLAN_TDLS
6891 mutex_unlock(&pHddCtx->tdls_lock);
6892#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 goto err_free_netdev;
6894 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306895
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306896 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306897 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306898
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306899#ifdef WLAN_NS_OFFLOAD
6900 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306901 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306902#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306904 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006905 netif_tx_disable(pAdapter->dev);
6906 //netif_tx_disable(pWlanDev);
6907 netif_carrier_off(pAdapter->dev);
6908
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306909 if (WLAN_HDD_P2P_CLIENT == session_type ||
6910 WLAN_HDD_P2P_DEVICE == session_type)
6911 {
6912 /* Initialize the work queue to defer the
6913 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306914 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306915 hdd_p2p_roc_work_queue);
6916 }
6917
Jeff Johnson295189b2012-06-20 16:38:30 -07006918 break;
6919 }
6920
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006922 case WLAN_HDD_SOFTAP:
6923 {
6924 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6925 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306926 {
6927 hddLog(VOS_TRACE_LEVEL_FATAL,
6928 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306930 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006931
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6933 NL80211_IFTYPE_AP:
6934 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006935 pAdapter->device_mode = session_type;
6936
6937 status = hdd_init_ap_mode(pAdapter);
6938 if( VOS_STATUS_SUCCESS != status )
6939 goto err_free_netdev;
6940
Nirav Shah7e3c8132015-06-22 23:51:42 +05306941 status = hdd_sta_id_hash_attach(pAdapter);
6942 if (VOS_STATUS_SUCCESS != status)
6943 {
6944 hddLog(VOS_TRACE_LEVEL_FATAL,
6945 FL("failed to attach hash for session %d"), session_type);
6946 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6947 goto err_free_netdev;
6948 }
6949
Jeff Johnson295189b2012-06-20 16:38:30 -07006950 status = hdd_register_hostapd( pAdapter, rtnl_held );
6951 if( VOS_STATUS_SUCCESS != status )
6952 {
c_hpothu002231a2015-02-05 14:58:51 +05306953 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 goto err_free_netdev;
6955 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306956 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 netif_tx_disable(pAdapter->dev);
6958 netif_carrier_off(pAdapter->dev);
6959
6960 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306961
6962 if (WLAN_HDD_P2P_GO == session_type)
6963 {
6964 /* Initialize the work queue to
6965 * defer the back to back RoC request */
6966 INIT_DELAYED_WORK(&pAdapter->roc_work,
6967 hdd_p2p_roc_work_queue);
6968 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006969 break;
6970 }
6971 case WLAN_HDD_MONITOR:
6972 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006973 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6974 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306975 {
6976 hddLog(VOS_TRACE_LEVEL_FATAL,
6977 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006978 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306979 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006980
Katya Nigame7b69a82015-04-28 15:24:06 +05306981 // Register wireless extensions
6982 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6983 {
6984 hddLog(VOS_TRACE_LEVEL_FATAL,
6985 "hdd_register_wext() failed with status code %08d [x%08x]",
6986 status, status );
6987 status = VOS_STATUS_E_FAILURE;
6988 }
6989
Jeff Johnson295189b2012-06-20 16:38:30 -07006990 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6991 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006992#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6993 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6994#else
6995 pAdapter->dev->open = hdd_mon_open;
6996 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05306997 pAdapter->dev->stop = hdd_mon_stop;
6998 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006999#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307000 status = hdd_register_interface( pAdapter, rtnl_held );
7001 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007002 hdd_init_tx_rx( pAdapter );
7003 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307004 //Stop the Interface TX queue.
7005 netif_tx_disable(pAdapter->dev);
7006 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007007 }
7008 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007009 case WLAN_HDD_FTM:
7010 {
7011 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7012
7013 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307014 {
7015 hddLog(VOS_TRACE_LEVEL_FATAL,
7016 FL("failed to allocate adapter for session %d"), session_type);
7017 return NULL;
7018 }
7019
Jeff Johnson295189b2012-06-20 16:38:30 -07007020 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7021 * message while loading driver in FTM mode. */
7022 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7023 pAdapter->device_mode = session_type;
7024 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307025
7026 hdd_init_tx_rx( pAdapter );
7027
7028 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307029 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307030 netif_tx_disable(pAdapter->dev);
7031 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 }
7033 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 default:
7035 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307036 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7037 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 VOS_ASSERT(0);
7039 return NULL;
7040 }
7041 }
7042
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 if( VOS_STATUS_SUCCESS == status )
7044 {
7045 //Add it to the hdd's session list.
7046 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7047 if( NULL == pHddAdapterNode )
7048 {
7049 status = VOS_STATUS_E_NOMEM;
7050 }
7051 else
7052 {
7053 pHddAdapterNode->pAdapter = pAdapter;
7054 status = hdd_add_adapter_back ( pHddCtx,
7055 pHddAdapterNode );
7056 }
7057 }
7058
7059 if( VOS_STATUS_SUCCESS != status )
7060 {
7061 if( NULL != pAdapter )
7062 {
7063 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7064 pAdapter = NULL;
7065 }
7066 if( NULL != pHddAdapterNode )
7067 {
7068 vos_mem_free( pHddAdapterNode );
7069 }
7070
7071 goto resume_bmps;
7072 }
7073
7074 if(VOS_STATUS_SUCCESS == status)
7075 {
7076 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7077
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007078 //Initialize the WoWL service
7079 if(!hdd_init_wowl(pAdapter))
7080 {
7081 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7082 goto err_free_netdev;
7083 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007084 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 return pAdapter;
7086
7087err_free_netdev:
7088 free_netdev(pAdapter->dev);
7089 wlan_hdd_release_intf_addr( pHddCtx,
7090 pAdapter->macAddressCurrent.bytes );
7091
7092resume_bmps:
7093 //If bmps disabled enable it
7094 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7095 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307096 if (pHddCtx->hdd_wlan_suspended)
7097 {
7098 hdd_set_pwrparams(pHddCtx);
7099 }
7100 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007101 }
7102 return NULL;
7103}
7104
7105VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7106 tANI_U8 rtnl_held )
7107{
7108 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7109 VOS_STATUS status;
7110
7111 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7112 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307113 {
7114 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7115 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307117 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007118
7119 while ( pCurrent->pAdapter != pAdapter )
7120 {
7121 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7122 if( VOS_STATUS_SUCCESS != status )
7123 break;
7124
7125 pCurrent = pNext;
7126 }
7127 pAdapterNode = pCurrent;
7128 if( VOS_STATUS_SUCCESS == status )
7129 {
7130 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7131 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307132
7133#ifdef FEATURE_WLAN_TDLS
7134
7135 /* A Mutex Lock is introduced while changing/initializing the mode to
7136 * protect the concurrent access for the Adapters by TDLS module.
7137 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307138 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307139#endif
7140
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 hdd_remove_adapter( pHddCtx, pAdapterNode );
7142 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007143 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007144
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307145#ifdef FEATURE_WLAN_TDLS
7146 mutex_unlock(&pHddCtx->tdls_lock);
7147#endif
7148
Jeff Johnson295189b2012-06-20 16:38:30 -07007149
7150 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307151 if ((!vos_concurrent_open_sessions_running()) &&
7152 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7153 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007154 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307155 if (pHddCtx->hdd_wlan_suspended)
7156 {
7157 hdd_set_pwrparams(pHddCtx);
7158 }
7159 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 }
7161
7162 return VOS_STATUS_SUCCESS;
7163 }
7164
7165 return VOS_STATUS_E_FAILURE;
7166}
7167
7168VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7169{
7170 hdd_adapter_list_node_t *pHddAdapterNode;
7171 VOS_STATUS status;
7172
7173 ENTER();
7174
7175 do
7176 {
7177 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7178 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7179 {
7180 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7181 vos_mem_free( pHddAdapterNode );
7182 }
7183 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7184
7185 EXIT();
7186
7187 return VOS_STATUS_SUCCESS;
7188}
7189
7190void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7191{
7192 v_U8_t addIE[1] = {0};
7193
7194 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7195 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7196 eANI_BOOLEAN_FALSE) )
7197 {
7198 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007199 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 }
7201
7202 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7203 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7204 eANI_BOOLEAN_FALSE) )
7205 {
7206 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007207 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007208 }
7209
7210 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7211 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7212 eANI_BOOLEAN_FALSE) )
7213 {
7214 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007215 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 }
7217}
7218
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307219VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7220 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007221{
7222 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7223 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307224 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007225 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307226 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307227 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307228 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007229
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307230 if (pHddCtx->isLogpInProgress) {
7231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7232 "%s:LOGP in Progress. Ignore!!!",__func__);
7233 return VOS_STATUS_E_FAILURE;
7234 }
7235
Jeff Johnson295189b2012-06-20 16:38:30 -07007236 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307237
Nirav Shah7e3c8132015-06-22 23:51:42 +05307238 status = hdd_sta_id_hash_detach(pAdapter);
7239 if (status != VOS_STATUS_SUCCESS)
7240 hddLog(VOS_TRACE_LEVEL_ERROR,
7241 FL("sta id hash detach failed"));
7242
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307243 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007244 switch(pAdapter->device_mode)
7245 {
7246 case WLAN_HDD_INFRA_STATION:
7247 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007248 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307249 {
7250 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307251#ifdef FEATURE_WLAN_TDLS
7252 mutex_lock(&pHddCtx->tdls_lock);
7253 wlan_hdd_tdls_exit(pAdapter, TRUE);
7254 mutex_unlock(&pHddCtx->tdls_lock);
7255#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307256 if( hdd_connIsConnected(pstation) ||
7257 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 {
7259 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7260 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7261 pAdapter->sessionId,
7262 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7263 else
7264 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7265 pAdapter->sessionId,
7266 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7267 //success implies disconnect command got queued up successfully
7268 if(halStatus == eHAL_STATUS_SUCCESS)
7269 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307270 ret = wait_for_completion_interruptible_timeout(
7271 &pAdapter->disconnect_comp_var,
7272 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7273 if (ret <= 0)
7274 {
7275 hddLog(VOS_TRACE_LEVEL_ERROR,
7276 "%s: wait on disconnect_comp_var failed %ld",
7277 __func__, ret);
7278 }
7279 }
7280 else
7281 {
7282 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7283 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 }
7285 memset(&wrqu, '\0', sizeof(wrqu));
7286 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7287 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7288 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7289 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307290 else if(pstation->conn_info.connState ==
7291 eConnectionState_Disconnecting)
7292 {
7293 ret = wait_for_completion_interruptible_timeout(
7294 &pAdapter->disconnect_comp_var,
7295 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7296 if (ret <= 0)
7297 {
7298 hddLog(VOS_TRACE_LEVEL_ERROR,
7299 FL("wait on disconnect_comp_var failed %ld"), ret);
7300 }
7301 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307302 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307304 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307305 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007306 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307307 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7308 {
7309 while (pAdapter->is_roc_inprogress)
7310 {
7311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7312 "%s: ROC in progress for session %d!!!",
7313 __func__, pAdapter->sessionId);
7314 // waiting for ROC to expire
7315 msleep(500);
7316 /* In GO present case , if retry exceeds 3,
7317 it means something went wrong. */
7318 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7319 {
7320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7321 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307322 if (eHAL_STATUS_SUCCESS !=
7323 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7324 pAdapter->sessionId ))
7325 {
7326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7327 FL("Failed to Cancel Remain on Channel"));
7328 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307329 wait_for_completion_interruptible_timeout(
7330 &pAdapter->cancel_rem_on_chan_var,
7331 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7332 break;
7333 }
7334 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307335 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307336 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307337#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307338 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307339#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307340
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307341 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307342
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307343 /* It is possible that the caller of this function does not
7344 * wish to close the session
7345 */
7346 if (VOS_TRUE == bCloseSession &&
7347 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 {
7349 INIT_COMPLETION(pAdapter->session_close_comp_var);
7350 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307351 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307352 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307354 unsigned long ret;
7355
Jeff Johnson295189b2012-06-20 16:38:30 -07007356 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307357 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307358 &pAdapter->session_close_comp_var,
7359 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307360 if ( 0 >= ret)
7361 {
7362 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307363 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307364 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007365 }
7366 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307367 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007368 break;
7369
7370 case WLAN_HDD_SOFTAP:
7371 case WLAN_HDD_P2P_GO:
7372 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307373 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7374 while (pAdapter->is_roc_inprogress) {
7375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7376 "%s: ROC in progress for session %d!!!",
7377 __func__, pAdapter->sessionId);
7378 msleep(500);
7379 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7381 "%s: ROC completion is not received.!!!", __func__);
7382 WLANSAP_CancelRemainOnChannel(
7383 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7384 wait_for_completion_interruptible_timeout(
7385 &pAdapter->cancel_rem_on_chan_var,
7386 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7387 break;
7388 }
7389 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307390
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307391 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307392 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007393 mutex_lock(&pHddCtx->sap_lock);
7394 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7395 {
7396 VOS_STATUS status;
7397 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7398
7399 //Stop Bss.
7400 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7401 if (VOS_IS_STATUS_SUCCESS(status))
7402 {
7403 hdd_hostapd_state_t *pHostapdState =
7404 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7405
7406 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7407
7408 if (!VOS_IS_STATUS_SUCCESS(status))
7409 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307410 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7411 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007412 }
7413 }
7414 else
7415 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007416 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007417 }
7418 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307419 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007420
7421 if (eHAL_STATUS_FAILURE ==
7422 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7423 0, NULL, eANI_BOOLEAN_FALSE))
7424 {
7425 hddLog(LOGE,
7426 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007427 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007428 }
7429
7430 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7431 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7432 eANI_BOOLEAN_FALSE) )
7433 {
7434 hddLog(LOGE,
7435 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7436 }
7437
7438 // Reset WNI_CFG_PROBE_RSP Flags
7439 wlan_hdd_reset_prob_rspies(pAdapter);
7440 kfree(pAdapter->sessionCtx.ap.beacon);
7441 pAdapter->sessionCtx.ap.beacon = NULL;
7442 }
7443 mutex_unlock(&pHddCtx->sap_lock);
7444 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007445
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 case WLAN_HDD_MONITOR:
7447 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007448
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 default:
7450 break;
7451 }
7452
7453 EXIT();
7454 return VOS_STATUS_SUCCESS;
7455}
7456
7457VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7458{
7459 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7460 VOS_STATUS status;
7461 hdd_adapter_t *pAdapter;
7462
7463 ENTER();
7464
7465 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7466
7467 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7468 {
7469 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007470
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307471 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007472
7473 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7474 pAdapterNode = pNext;
7475 }
7476
7477 EXIT();
7478
7479 return VOS_STATUS_SUCCESS;
7480}
7481
Rajeev Kumarf999e582014-01-09 17:33:29 -08007482
7483#ifdef FEATURE_WLAN_BATCH_SCAN
7484/**---------------------------------------------------------------------------
7485
7486 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7487 structures
7488
7489 \param - pAdapter Pointer to HDD adapter
7490
7491 \return - None
7492
7493 --------------------------------------------------------------------------*/
7494void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7495{
7496 tHddBatchScanRsp *pNode;
7497 tHddBatchScanRsp *pPrev;
7498
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307499 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007500 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307501 hddLog(VOS_TRACE_LEVEL_ERROR,
7502 "%s: Adapter context is Null", __func__);
7503 return;
7504 }
7505
7506 pNode = pAdapter->pBatchScanRsp;
7507 while (pNode)
7508 {
7509 pPrev = pNode;
7510 pNode = pNode->pNext;
7511 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007512 }
7513
7514 pAdapter->pBatchScanRsp = NULL;
7515 pAdapter->numScanList = 0;
7516 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7517 pAdapter->prev_batch_id = 0;
7518
7519 return;
7520}
7521#endif
7522
7523
Jeff Johnson295189b2012-06-20 16:38:30 -07007524VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7525{
7526 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7527 VOS_STATUS status;
7528 hdd_adapter_t *pAdapter;
7529
7530 ENTER();
7531
7532 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7533
7534 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7535 {
7536 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307537 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007538 netif_tx_disable(pAdapter->dev);
7539 netif_carrier_off(pAdapter->dev);
7540
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007541 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7542
Jeff Johnson295189b2012-06-20 16:38:30 -07007543 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307544
Katya Nigam1fd24402015-02-16 14:52:19 +05307545 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7546 hdd_ibss_deinit_tx_rx(pAdapter);
7547
Nirav Shah7e3c8132015-06-22 23:51:42 +05307548 status = hdd_sta_id_hash_detach(pAdapter);
7549 if (status != VOS_STATUS_SUCCESS)
7550 hddLog(VOS_TRACE_LEVEL_ERROR,
7551 FL("sta id hash detach failed for session id %d"),
7552 pAdapter->sessionId);
7553
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307554 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7555
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307556 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7557 {
7558 hdd_wmm_adapter_close( pAdapter );
7559 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7560 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007561
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307562 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7563 {
7564 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7565 }
7566
Rajeev Kumarf999e582014-01-09 17:33:29 -08007567#ifdef FEATURE_WLAN_BATCH_SCAN
7568 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7569 {
7570 hdd_deinit_batch_scan(pAdapter);
7571 }
7572#endif
7573
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307574#ifdef FEATURE_WLAN_TDLS
7575 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307576 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307577 mutex_unlock(&pHddCtx->tdls_lock);
7578#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007579 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7580 pAdapterNode = pNext;
7581 }
7582
7583 EXIT();
7584
7585 return VOS_STATUS_SUCCESS;
7586}
7587
7588VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7589{
7590 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7591 VOS_STATUS status;
7592 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307593 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007594
7595 ENTER();
7596
7597 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7598
7599 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7600 {
7601 pAdapter = pAdapterNode->pAdapter;
7602
Kumar Anand82c009f2014-05-29 00:29:42 -07007603 hdd_wmm_init( pAdapter );
7604
Jeff Johnson295189b2012-06-20 16:38:30 -07007605 switch(pAdapter->device_mode)
7606 {
7607 case WLAN_HDD_INFRA_STATION:
7608 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007609 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307610
7611 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7612
Jeff Johnson295189b2012-06-20 16:38:30 -07007613 hdd_init_station_mode(pAdapter);
7614 /* Open the gates for HDD to receive Wext commands */
7615 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007616 pHddCtx->scan_info.mScanPending = FALSE;
7617 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007618
7619 //Trigger the initial scan
7620 hdd_wlan_initial_scan(pAdapter);
7621
7622 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307623 if (eConnectionState_Associated == connState ||
7624 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 {
7626 union iwreq_data wrqu;
7627 memset(&wrqu, '\0', sizeof(wrqu));
7628 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7629 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7630 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007631 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007632
Jeff Johnson295189b2012-06-20 16:38:30 -07007633 /* indicate disconnected event to nl80211 */
7634 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7635 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007636 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307637 else if (eConnectionState_Connecting == connState)
7638 {
7639 /*
7640 * Indicate connect failure to supplicant if we were in the
7641 * process of connecting
7642 */
7643 cfg80211_connect_result(pAdapter->dev, NULL,
7644 NULL, 0, NULL, 0,
7645 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7646 GFP_KERNEL);
7647 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 break;
7649
7650 case WLAN_HDD_SOFTAP:
7651 /* softAP can handle SSR */
7652 break;
7653
7654 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007655 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007656 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007657 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007658 break;
7659
7660 case WLAN_HDD_MONITOR:
7661 /* monitor interface start */
7662 break;
7663 default:
7664 break;
7665 }
7666
7667 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7668 pAdapterNode = pNext;
7669 }
7670
7671 EXIT();
7672
7673 return VOS_STATUS_SUCCESS;
7674}
7675
7676VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7677{
7678 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7679 hdd_adapter_t *pAdapter;
7680 VOS_STATUS status;
7681 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307682 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007683
7684 ENTER();
7685
7686 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7687
7688 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7689 {
7690 pAdapter = pAdapterNode->pAdapter;
7691
7692 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7693 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7694 {
7695 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7696 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7697
Abhishek Singhf4669da2014-05-26 15:07:49 +05307698 hddLog(VOS_TRACE_LEVEL_INFO,
7699 "%s: Set HDD connState to eConnectionState_NotConnected",
7700 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7702 init_completion(&pAdapter->disconnect_comp_var);
7703 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7704 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7705
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307706 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007707 &pAdapter->disconnect_comp_var,
7708 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307709 if (0 >= ret)
7710 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7711 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007712
7713 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7714 pHddCtx->isAmpAllowed = VOS_FALSE;
7715 sme_RoamConnect(pHddCtx->hHal,
7716 pAdapter->sessionId, &(pWextState->roamProfile),
7717 &roamId);
7718 }
7719
7720 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7721 pAdapterNode = pNext;
7722 }
7723
7724 EXIT();
7725
7726 return VOS_STATUS_SUCCESS;
7727}
7728
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007729void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7730{
7731 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7732 VOS_STATUS status;
7733 hdd_adapter_t *pAdapter;
7734 hdd_station_ctx_t *pHddStaCtx;
7735 hdd_ap_ctx_t *pHddApCtx;
7736 hdd_hostapd_state_t * pHostapdState;
7737 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7738 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7739 const char *p2pMode = "DEV";
7740 const char *ccMode = "Standalone";
7741 int n;
7742
7743 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7744 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7745 {
7746 pAdapter = pAdapterNode->pAdapter;
7747 switch (pAdapter->device_mode) {
7748 case WLAN_HDD_INFRA_STATION:
7749 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7750 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7751 staChannel = pHddStaCtx->conn_info.operationChannel;
7752 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7753 }
7754 break;
7755 case WLAN_HDD_P2P_CLIENT:
7756 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7757 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7758 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7759 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7760 p2pMode = "CLI";
7761 }
7762 break;
7763 case WLAN_HDD_P2P_GO:
7764 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7765 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7766 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7767 p2pChannel = pHddApCtx->operatingChannel;
7768 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7769 }
7770 p2pMode = "GO";
7771 break;
7772 case WLAN_HDD_SOFTAP:
7773 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7774 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7775 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7776 apChannel = pHddApCtx->operatingChannel;
7777 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7778 }
7779 break;
7780 default:
7781 break;
7782 }
7783 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7784 pAdapterNode = pNext;
7785 }
7786 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7787 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7788 }
7789 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7790 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7791 if (p2pChannel > 0) {
7792 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7793 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7794 }
7795 if (apChannel > 0) {
7796 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7797 apChannel, MAC_ADDR_ARRAY(apBssid));
7798 }
7799
7800 if (p2pChannel > 0 && apChannel > 0) {
7801 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7802 }
7803}
7804
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007805bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007806{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007807 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007808}
7809
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007810/* Once SSR is disabled then it cannot be set. */
7811void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007812{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007813 if (HDD_SSR_DISABLED == isSsrRequired)
7814 return;
7815
Jeff Johnson295189b2012-06-20 16:38:30 -07007816 isSsrRequired = value;
7817}
7818
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307819void hdd_set_pre_close( hdd_context_t *pHddCtx)
7820{
7821 sme_PreClose(pHddCtx->hHal);
7822}
7823
Jeff Johnson295189b2012-06-20 16:38:30 -07007824VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7825 hdd_adapter_list_node_t** ppAdapterNode)
7826{
7827 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307828 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007829 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7830 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307831 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007832 return status;
7833}
7834
7835VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7836 hdd_adapter_list_node_t* pAdapterNode,
7837 hdd_adapter_list_node_t** pNextAdapterNode)
7838{
7839 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307840 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007841 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7842 (hdd_list_node_t*) pAdapterNode,
7843 (hdd_list_node_t**)pNextAdapterNode );
7844
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307845 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 return status;
7847}
7848
7849VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7850 hdd_adapter_list_node_t* pAdapterNode)
7851{
7852 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307853 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7855 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307856 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007857 return status;
7858}
7859
7860VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7861 hdd_adapter_list_node_t** ppAdapterNode)
7862{
7863 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307864 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007865 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7866 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307867 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007868 return status;
7869}
7870
7871VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7872 hdd_adapter_list_node_t* pAdapterNode)
7873{
7874 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307875 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7877 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307878 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007879 return status;
7880}
7881
7882VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7883 hdd_adapter_list_node_t* pAdapterNode)
7884{
7885 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307886 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007887 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7888 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307889 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 return status;
7891}
7892
7893hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7894 tSirMacAddr macAddr )
7895{
7896 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7897 hdd_adapter_t *pAdapter;
7898 VOS_STATUS status;
7899
7900 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7901
7902 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7903 {
7904 pAdapter = pAdapterNode->pAdapter;
7905
7906 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7907 macAddr, sizeof(tSirMacAddr) ) )
7908 {
7909 return pAdapter;
7910 }
7911 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7912 pAdapterNode = pNext;
7913 }
7914
7915 return NULL;
7916
7917}
7918
7919hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7920{
7921 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7922 hdd_adapter_t *pAdapter;
7923 VOS_STATUS status;
7924
7925 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7926
7927 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7928 {
7929 pAdapter = pAdapterNode->pAdapter;
7930
7931 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7932 IFNAMSIZ ) )
7933 {
7934 return pAdapter;
7935 }
7936 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7937 pAdapterNode = pNext;
7938 }
7939
7940 return NULL;
7941
7942}
7943
7944hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7945{
7946 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7947 hdd_adapter_t *pAdapter;
7948 VOS_STATUS status;
7949
7950 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7951
7952 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7953 {
7954 pAdapter = pAdapterNode->pAdapter;
7955
7956 if( pAdapter && (mode == pAdapter->device_mode) )
7957 {
7958 return pAdapter;
7959 }
7960 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7961 pAdapterNode = pNext;
7962 }
7963
7964 return NULL;
7965
7966}
7967
7968//Remove this function later
7969hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7970{
7971 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7972 hdd_adapter_t *pAdapter;
7973 VOS_STATUS status;
7974
7975 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7976
7977 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7978 {
7979 pAdapter = pAdapterNode->pAdapter;
7980
7981 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7982 {
7983 return pAdapter;
7984 }
7985
7986 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7987 pAdapterNode = pNext;
7988 }
7989
7990 return NULL;
7991
7992}
7993
Jeff Johnson295189b2012-06-20 16:38:30 -07007994/**---------------------------------------------------------------------------
7995
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307996 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007997
7998 This API returns the operating channel of the requested device mode
7999
8000 \param - pHddCtx - Pointer to the HDD context.
8001 - mode - Device mode for which operating channel is required
8002 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8003 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8004 \return - channel number. "0" id the requested device is not found OR it is not connected.
8005 --------------------------------------------------------------------------*/
8006v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8007{
8008 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8009 VOS_STATUS status;
8010 hdd_adapter_t *pAdapter;
8011 v_U8_t operatingChannel = 0;
8012
8013 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8014
8015 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8016 {
8017 pAdapter = pAdapterNode->pAdapter;
8018
8019 if( mode == pAdapter->device_mode )
8020 {
8021 switch(pAdapter->device_mode)
8022 {
8023 case WLAN_HDD_INFRA_STATION:
8024 case WLAN_HDD_P2P_CLIENT:
8025 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8026 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8027 break;
8028 case WLAN_HDD_SOFTAP:
8029 case WLAN_HDD_P2P_GO:
8030 /*softap connection info */
8031 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8032 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8033 break;
8034 default:
8035 break;
8036 }
8037
8038 break; //Found the device of interest. break the loop
8039 }
8040
8041 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8042 pAdapterNode = pNext;
8043 }
8044 return operatingChannel;
8045}
8046
8047#ifdef WLAN_FEATURE_PACKET_FILTERING
8048/**---------------------------------------------------------------------------
8049
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308050 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008051
8052 This used to set the multicast address list.
8053
8054 \param - dev - Pointer to the WLAN device.
8055 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308056 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008057
8058 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308059static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008060{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308061 hdd_adapter_t *pAdapter;
8062 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308064 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308066
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308067 ENTER();
8068
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308069 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308070 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 {
8072 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308073 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 return;
8075 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308076 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8077 ret = wlan_hdd_validate_context(pHddCtx);
8078 if (0 != ret)
8079 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308080 return;
8081 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008082 if (dev->flags & IFF_ALLMULTI)
8083 {
8084 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008085 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308086 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308088 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008089 {
8090 mc_count = netdev_mc_count(dev);
8091 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008092 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008093 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8094 {
8095 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008096 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308097 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 return;
8099 }
8100
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308101 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008102
8103 netdev_for_each_mc_addr(ha, dev) {
8104 if (i == mc_count)
8105 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308106 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8107 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008108 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308109 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308110 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008111 i++;
8112 }
8113 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308114
8115 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 return;
8117}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308118
8119static void hdd_set_multicast_list(struct net_device *dev)
8120{
8121 vos_ssr_protect(__func__);
8122 __hdd_set_multicast_list(dev);
8123 vos_ssr_unprotect(__func__);
8124}
Jeff Johnson295189b2012-06-20 16:38:30 -07008125#endif
8126
8127/**---------------------------------------------------------------------------
8128
8129 \brief hdd_select_queue() -
8130
8131 This function is registered with the Linux OS for network
8132 core to decide which queue to use first.
8133
8134 \param - dev - Pointer to the WLAN device.
8135 - skb - Pointer to OS packet (sk_buff).
8136 \return - ac, Queue Index/access category corresponding to UP in IP header
8137
8138 --------------------------------------------------------------------------*/
8139v_U16_t hdd_select_queue(struct net_device *dev,
8140 struct sk_buff *skb)
8141{
8142 return hdd_wmm_select_queue(dev, skb);
8143}
8144
8145
8146/**---------------------------------------------------------------------------
8147
8148 \brief hdd_wlan_initial_scan() -
8149
8150 This function triggers the initial scan
8151
8152 \param - pAdapter - Pointer to the HDD adapter.
8153
8154 --------------------------------------------------------------------------*/
8155void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8156{
8157 tCsrScanRequest scanReq;
8158 tCsrChannelInfo channelInfo;
8159 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008160 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008161 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8162
8163 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8164 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8165 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8166
8167 if(sme_Is11dSupported(pHddCtx->hHal))
8168 {
8169 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8170 if ( HAL_STATUS_SUCCESS( halStatus ) )
8171 {
8172 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8173 if( !scanReq.ChannelInfo.ChannelList )
8174 {
8175 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8176 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008177 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008178 return;
8179 }
8180 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8181 channelInfo.numOfChannels);
8182 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8183 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008184 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008185 }
8186
8187 scanReq.scanType = eSIR_PASSIVE_SCAN;
8188 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8189 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8190 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8191 }
8192 else
8193 {
8194 scanReq.scanType = eSIR_ACTIVE_SCAN;
8195 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8196 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8197 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8198 }
8199
8200 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8201 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8202 {
8203 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8204 __func__, halStatus );
8205 }
8206
8207 if(sme_Is11dSupported(pHddCtx->hHal))
8208 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8209}
8210
mukul sharmabab477d2015-06-11 17:14:55 +05308211void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8212{
8213 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8214 VOS_STATUS status;
8215 hdd_adapter_t *pAdapter;
8216
8217 ENTER();
8218
8219 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8220
8221 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8222 {
8223 pAdapter = pAdapterNode->pAdapter;
8224
8225 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8226 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8227 pAdapterNode = pNext;
8228 }
8229
8230 EXIT();
8231}
Jeff Johnson295189b2012-06-20 16:38:30 -07008232/**---------------------------------------------------------------------------
8233
8234 \brief hdd_full_power_callback() - HDD full power callback function
8235
8236 This is the function invoked by SME to inform the result of a full power
8237 request issued by HDD
8238
8239 \param - callbackcontext - Pointer to cookie
8240 \param - status - result of request
8241
8242 \return - None
8243
8244 --------------------------------------------------------------------------*/
8245static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8246{
Jeff Johnson72a40512013-12-19 10:14:15 -08008247 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008248
8249 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308250 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008251
8252 if (NULL == callbackContext)
8253 {
8254 hddLog(VOS_TRACE_LEVEL_ERROR,
8255 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008256 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008257 return;
8258 }
8259
Jeff Johnson72a40512013-12-19 10:14:15 -08008260 /* there is a race condition that exists between this callback
8261 function and the caller since the caller could time out either
8262 before or while this code is executing. we use a spinlock to
8263 serialize these actions */
8264 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008265
8266 if (POWER_CONTEXT_MAGIC != pContext->magic)
8267 {
8268 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008269 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 hddLog(VOS_TRACE_LEVEL_WARN,
8271 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008272 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 return;
8274 }
8275
Jeff Johnson72a40512013-12-19 10:14:15 -08008276 /* context is valid so caller is still waiting */
8277
8278 /* paranoia: invalidate the magic */
8279 pContext->magic = 0;
8280
8281 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008282 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008283
8284 /* serialization is complete */
8285 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008286}
8287
Katya Nigamf0511f62015-05-05 16:40:57 +05308288void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8289{
8290 pMonCtx->typeSubtypeBitmap = 0;
8291 if( type%10 ) /* Management Packets */
8292 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8293 type/=10;
8294 if( type%10 ) /* Control Packets */
8295 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8296 type/=10;
8297 if( type%10 ) /* Data Packets */
8298 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8299}
8300
8301VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8302{
8303 vos_msg_t monMsg;
8304
8305 monMsg.type = WDA_MON_START_REQ;
8306 monMsg.reserved = 0;
8307 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8308 monMsg.bodyval = 0;
8309
8310 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8311 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8312 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8313 return VOS_STATUS_E_FAILURE;
8314 }
8315
8316 return VOS_STATUS_SUCCESS;
8317}
8318
8319void wlan_hdd_mon_poststopmsg(void)
8320{
8321 vos_msg_t monMsg;
8322
8323 monMsg.type = WDA_MON_STOP_REQ;
8324 monMsg.reserved = 0;
8325 monMsg.bodyptr = NULL;
8326 monMsg.bodyval = 0;
8327
8328 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8329 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8330 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8331 }
8332}
8333
Katya Nigame7b69a82015-04-28 15:24:06 +05308334void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8335{
8336 VOS_STATUS vosStatus;
8337 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8338 struct wiphy *wiphy = pHddCtx->wiphy;
8339
8340 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8341 if(pAdapter == NULL || pVosContext == NULL)
8342 {
8343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8344 return ;
8345 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308346
8347 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308348 hdd_UnregisterWext(pAdapter->dev);
8349
8350 vos_mon_stop( pVosContext );
8351
8352 vosStatus = vos_sched_close( pVosContext );
8353 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8354 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8355 "%s: Failed to close VOSS Scheduler",__func__);
8356 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8357 }
8358
8359 vosStatus = vos_nv_close();
8360 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8361 {
8362 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8363 "%s: Failed to close NV", __func__);
8364 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8365 }
8366
8367 vos_close(pVosContext);
8368
8369 #ifdef WLAN_KD_READY_NOTIFIER
8370 nl_srv_exit(pHddCtx->ptt_pid);
8371 #else
8372 nl_srv_exit();
8373 #endif
8374
8375 if (pHddCtx->cfg_ini)
8376 {
8377 kfree(pHddCtx->cfg_ini);
8378 pHddCtx->cfg_ini= NULL;
8379 }
8380 hdd_close_all_adapters( pHddCtx );
8381
8382 wiphy_free(wiphy) ;
8383
8384}
Jeff Johnson295189b2012-06-20 16:38:30 -07008385/**---------------------------------------------------------------------------
8386
8387 \brief hdd_wlan_exit() - HDD WLAN exit function
8388
8389 This is the driver exit point (invoked during rmmod)
8390
8391 \param - pHddCtx - Pointer to the HDD Context
8392
8393 \return - None
8394
8395 --------------------------------------------------------------------------*/
8396void hdd_wlan_exit(hdd_context_t *pHddCtx)
8397{
8398 eHalStatus halStatus;
8399 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8400 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308401 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008402 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008403 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308405 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008406
8407 ENTER();
8408
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308409
Katya Nigame7b69a82015-04-28 15:24:06 +05308410 if (VOS_MONITOR_MODE == hdd_get_conparam())
8411 {
8412 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8413 wlan_hdd_mon_close(pHddCtx);
8414 return;
8415 }
8416 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008417 {
8418 // Unloading, restart logic is no more required.
8419 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008420
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308421#ifdef FEATURE_WLAN_TDLS
8422 /* At the time of driver unloading; if tdls connection is present;
8423 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8424 * wlan_hdd_tdls_find_peer always checks for valid context;
8425 * as load/unload in progress there can be a race condition.
8426 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8427 * when tdls state is enabled.
8428 * As soon as driver set load/unload flag; tdls flag also needs
8429 * to be disabled so that hdd_rx_packet_cbk won't call
8430 * wlan_hdd_tdls_find_peer.
8431 */
8432 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8433#endif
8434
c_hpothu5ab05e92014-06-13 17:34:05 +05308435 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8436 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008437 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308438 pAdapter = pAdapterNode->pAdapter;
8439 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308441 /* Disable TX on the interface, after this hard_start_xmit() will
8442 * not be called on that interface
8443 */
8444 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8445 netif_tx_disable(pAdapter->dev);
8446
8447 /* Mark the interface status as "down" for outside world */
8448 netif_carrier_off(pAdapter->dev);
8449
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308450 /* DeInit the adapter. This ensures that all data packets
8451 * are freed.
8452 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308453#ifdef FEATURE_WLAN_TDLS
8454 mutex_lock(&pHddCtx->tdls_lock);
8455#endif
c_hpothu002231a2015-02-05 14:58:51 +05308456 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308457#ifdef FEATURE_WLAN_TDLS
8458 mutex_unlock(&pHddCtx->tdls_lock);
8459#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308460
c_hpothu5ab05e92014-06-13 17:34:05 +05308461 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8462 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8463 {
8464 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8465 hdd_UnregisterWext(pAdapter->dev);
8466 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308467
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308469 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8470 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 }
mukul sharmabab477d2015-06-11 17:14:55 +05308472
8473 //Purge all sme cmd's for all interface
8474 hdd_purge_cmd_list_all_adapters(pHddCtx);
8475
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308476 // Cancel any outstanding scan requests. We are about to close all
8477 // of our adapters, but an adapter structure is what SME passes back
8478 // to our callback function. Hence if there are any outstanding scan
8479 // requests then there is a race condition between when the adapter
8480 // is closed and when the callback is invoked.We try to resolve that
8481 // race condition here by canceling any outstanding scans before we
8482 // close the adapters.
8483 // Note that the scans may be cancelled in an asynchronous manner,
8484 // so ideally there needs to be some kind of synchronization. Rather
8485 // than introduce a new synchronization here, we will utilize the
8486 // fact that we are about to Request Full Power, and since that is
8487 // synchronized, the expectation is that by the time Request Full
8488 // Power has completed all scans will be cancelled.
8489 if (pHddCtx->scan_info.mScanPending)
8490 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308491 if(NULL != pAdapter)
8492 {
8493 hddLog(VOS_TRACE_LEVEL_INFO,
8494 FL("abort scan mode: %d sessionId: %d"),
8495 pAdapter->device_mode,
8496 pAdapter->sessionId);
8497 }
8498 hdd_abort_mac_scan(pHddCtx,
8499 pHddCtx->scan_info.sessionId,
8500 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308501 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008502 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308503 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008504 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308505 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308506 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8507 {
8508 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8510 "%s: in middle of FTM START", __func__);
8511 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8512 msecs_to_jiffies(20000));
8513 if(!lrc)
8514 {
8515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8516 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8517 }
8518 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008519 wlan_hdd_ftm_close(pHddCtx);
8520 goto free_hdd_ctx;
8521 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308522
Jeff Johnson295189b2012-06-20 16:38:30 -07008523 /* DeRegister with platform driver as client for Suspend/Resume */
8524 vosStatus = hddDeregisterPmOps(pHddCtx);
8525 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8526 {
8527 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8528 VOS_ASSERT(0);
8529 }
8530
8531 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8532 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8533 {
8534 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008536
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008537 //Stop the traffic monitor timer
8538 if ( VOS_TIMER_STATE_RUNNING ==
8539 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8540 {
8541 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8542 }
8543
8544 // Destroy the traffic monitor timer
8545 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8546 &pHddCtx->tx_rx_trafficTmr)))
8547 {
8548 hddLog(VOS_TRACE_LEVEL_ERROR,
8549 "%s: Cannot deallocate Traffic monitor timer", __func__);
8550 }
8551
Jeff Johnson295189b2012-06-20 16:38:30 -07008552 //Disable IMPS/BMPS as we do not want the device to enter any power
8553 //save mode during shutdown
8554 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8555 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8556 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8557
8558 //Ensure that device is in full power as we will touch H/W during vos_Stop
8559 init_completion(&powerContext.completion);
8560 powerContext.magic = POWER_CONTEXT_MAGIC;
8561
8562 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8563 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8564
8565 if (eHAL_STATUS_SUCCESS != halStatus)
8566 {
8567 if (eHAL_STATUS_PMC_PENDING == halStatus)
8568 {
8569 /* request was sent -- wait for the response */
8570 lrc = wait_for_completion_interruptible_timeout(
8571 &powerContext.completion,
8572 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 if (lrc <= 0)
8574 {
8575 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008576 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 }
8578 }
8579 else
8580 {
8581 hddLog(VOS_TRACE_LEVEL_ERROR,
8582 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008583 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 /* continue -- need to clean up as much as possible */
8585 }
8586 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308587 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8588 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8589 {
8590 /* This will issue a dump command which will clean up
8591 BTQM queues and unblock MC thread */
8592 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8593 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008594
Jeff Johnson72a40512013-12-19 10:14:15 -08008595 /* either we never sent a request, we sent a request and received a
8596 response or we sent a request and timed out. if we never sent a
8597 request or if we sent a request and got a response, we want to
8598 clear the magic out of paranoia. if we timed out there is a
8599 race condition such that the callback function could be
8600 executing at the same time we are. of primary concern is if the
8601 callback function had already verified the "magic" but had not
8602 yet set the completion variable when a timeout occurred. we
8603 serialize these activities by invalidating the magic while
8604 holding a shared spinlock which will cause us to block if the
8605 callback is currently executing */
8606 spin_lock(&hdd_context_lock);
8607 powerContext.magic = 0;
8608 spin_unlock(&hdd_context_lock);
8609
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308610 /* If Device is shutdown, no point for SME to wait for responses
8611 from device. Pre Close SME */
8612 if(wcnss_device_is_shutdown())
8613 {
8614 sme_PreClose(pHddCtx->hHal);
8615 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008616 hdd_debugfs_exit(pHddCtx);
8617
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308618#ifdef WLAN_NS_OFFLOAD
8619 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8620 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8621#endif
8622 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8623 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8624
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 // Unregister the Net Device Notifier
8626 unregister_netdevice_notifier(&hdd_netdev_notifier);
8627
Jeff Johnson295189b2012-06-20 16:38:30 -07008628 hdd_stop_all_adapters( pHddCtx );
8629
Jeff Johnson295189b2012-06-20 16:38:30 -07008630#ifdef WLAN_BTAMP_FEATURE
8631 vosStatus = WLANBAP_Stop(pVosContext);
8632 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8633 {
8634 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8635 "%s: Failed to stop BAP",__func__);
8636 }
8637#endif //WLAN_BTAMP_FEATURE
8638
8639 //Stop all the modules
8640 vosStatus = vos_stop( pVosContext );
8641 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8642 {
8643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8644 "%s: Failed to stop VOSS",__func__);
8645 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8646 }
8647
Jeff Johnson295189b2012-06-20 16:38:30 -07008648 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008650
8651 //Close the scheduler before calling vos_close to make sure no thread is
8652 // scheduled after the each module close is called i.e after all the data
8653 // structures are freed.
8654 vosStatus = vos_sched_close( pVosContext );
8655 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8656 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8657 "%s: Failed to close VOSS Scheduler",__func__);
8658 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8659 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008660#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8661 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308662 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008663#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008664 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308665 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008666
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308667#ifdef CONFIG_ENABLE_LINUX_REG
8668 vosStatus = vos_nv_close();
8669 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8670 {
8671 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8672 "%s: Failed to close NV", __func__);
8673 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8674 }
8675#endif
8676
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 //Close VOSS
8678 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8679 vos_close(pVosContext);
8680
Jeff Johnson295189b2012-06-20 16:38:30 -07008681 //Close Watchdog
8682 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8683 vos_watchdog_close(pVosContext);
8684
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308685 //Clean up HDD Nlink Service
8686 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308687
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308688#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308689 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308690 {
8691 wlan_logging_sock_deactivate_svc();
8692 }
8693#endif
8694
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308695#ifdef WLAN_KD_READY_NOTIFIER
8696 nl_srv_exit(pHddCtx->ptt_pid);
8697#else
8698 nl_srv_exit();
8699#endif /* WLAN_KD_READY_NOTIFIER */
8700
8701
Jeff Johnson295189b2012-06-20 16:38:30 -07008702 hdd_close_all_adapters( pHddCtx );
8703
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 /* free the power on lock from platform driver */
8705 if (free_riva_power_on_lock("wlan"))
8706 {
8707 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8708 __func__);
8709 }
8710
Jeff Johnson88ba7742013-02-27 14:36:02 -08008711free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308712
8713 //Free up dynamically allocated members inside HDD Adapter
8714 if (pHddCtx->cfg_ini)
8715 {
8716 kfree(pHddCtx->cfg_ini);
8717 pHddCtx->cfg_ini= NULL;
8718 }
8719
Leo Changf04ddad2013-09-18 13:46:38 -07008720 /* FTM mode, WIPHY did not registered
8721 If un-register here, system crash will happen */
8722 if (VOS_FTM_MODE != hdd_get_conparam())
8723 {
8724 wiphy_unregister(wiphy) ;
8725 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008726 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008727 if (hdd_is_ssr_required())
8728 {
8729 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008730 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008731 msleep(5000);
8732 }
8733 hdd_set_ssr_required (VOS_FALSE);
8734}
8735
8736
8737/**---------------------------------------------------------------------------
8738
8739 \brief hdd_update_config_from_nv() - Function to update the contents of
8740 the running configuration with parameters taken from NV storage
8741
8742 \param - pHddCtx - Pointer to the HDD global context
8743
8744 \return - VOS_STATUS_SUCCESS if successful
8745
8746 --------------------------------------------------------------------------*/
8747static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8748{
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 v_BOOL_t itemIsValid = VOS_FALSE;
8750 VOS_STATUS status;
8751 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8752 v_U8_t macLoop;
8753
8754 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8755 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8756 if(status != VOS_STATUS_SUCCESS)
8757 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008758 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008759 return VOS_STATUS_E_FAILURE;
8760 }
8761
8762 if (itemIsValid == VOS_TRUE)
8763 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008764 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8766 VOS_MAX_CONCURRENCY_PERSONA);
8767 if(status != VOS_STATUS_SUCCESS)
8768 {
8769 /* Get MAC from NV fail, not update CFG info
8770 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008771 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008772 return VOS_STATUS_E_FAILURE;
8773 }
8774
8775 /* If first MAC is not valid, treat all others are not valid
8776 * Then all MACs will be got from ini file */
8777 if(vos_is_macaddr_zero(&macFromNV[0]))
8778 {
8779 /* MAC address in NV file is not configured yet */
8780 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8781 return VOS_STATUS_E_INVAL;
8782 }
8783
8784 /* Get MAC address from NV, update CFG info */
8785 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8786 {
8787 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8788 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308789 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008790 /* This MAC is not valid, skip it
8791 * This MAC will be got from ini file */
8792 }
8793 else
8794 {
8795 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8796 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8797 VOS_MAC_ADDR_SIZE);
8798 }
8799 }
8800 }
8801 else
8802 {
8803 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8804 return VOS_STATUS_E_FAILURE;
8805 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008806
Jeff Johnson295189b2012-06-20 16:38:30 -07008807
8808 return VOS_STATUS_SUCCESS;
8809}
8810
8811/**---------------------------------------------------------------------------
8812
8813 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8814
8815 \param - pAdapter - Pointer to the HDD
8816
8817 \return - None
8818
8819 --------------------------------------------------------------------------*/
8820VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8821{
8822 eHalStatus halStatus;
8823 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308824 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008825
Jeff Johnson295189b2012-06-20 16:38:30 -07008826
8827 // Send ready indication to the HDD. This will kick off the MAC
8828 // into a 'running' state and should kick off an initial scan.
8829 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8830 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8831 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308832 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 "code %08d [x%08x]",__func__, halStatus, halStatus );
8834 return VOS_STATUS_E_FAILURE;
8835 }
8836
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308837 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8839 // And RIVA will crash
8840 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8841 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308842 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8843 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8844
8845
Jeff Johnson295189b2012-06-20 16:38:30 -07008846 return VOS_STATUS_SUCCESS;
8847}
8848
Jeff Johnson295189b2012-06-20 16:38:30 -07008849/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308850void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008851{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308852
8853 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8854
Jeff Johnson295189b2012-06-20 16:38:30 -07008855}
8856
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308857void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008858{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308859
8860 vos_wake_lock_release(&wlan_wake_lock, reason);
8861
Jeff Johnson295189b2012-06-20 16:38:30 -07008862}
8863
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308864void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008865{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308866
8867 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8868 reason);
8869
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008870}
8871
Jeff Johnson295189b2012-06-20 16:38:30 -07008872/**---------------------------------------------------------------------------
8873
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008874 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8875 information between Host and Riva
8876
8877 This function gets reported version of FW
8878 It also finds the version of Riva headers used to compile the host
8879 It compares the above two and prints a warning if they are different
8880 It gets the SW and HW version string
8881 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8882 indicating the features they support through a bitmap
8883
8884 \param - pHddCtx - Pointer to HDD context
8885
8886 \return - void
8887
8888 --------------------------------------------------------------------------*/
8889
8890void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8891{
8892
8893 tSirVersionType versionCompiled;
8894 tSirVersionType versionReported;
8895 tSirVersionString versionString;
8896 tANI_U8 fwFeatCapsMsgSupported = 0;
8897 VOS_STATUS vstatus;
8898
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008899 memset(&versionCompiled, 0, sizeof(versionCompiled));
8900 memset(&versionReported, 0, sizeof(versionReported));
8901
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008902 /* retrieve and display WCNSS version information */
8903 do {
8904
8905 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8906 &versionCompiled);
8907 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8908 {
8909 hddLog(VOS_TRACE_LEVEL_FATAL,
8910 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008911 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008912 break;
8913 }
8914
8915 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8916 &versionReported);
8917 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8918 {
8919 hddLog(VOS_TRACE_LEVEL_FATAL,
8920 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008921 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008922 break;
8923 }
8924
8925 if ((versionCompiled.major != versionReported.major) ||
8926 (versionCompiled.minor != versionReported.minor) ||
8927 (versionCompiled.version != versionReported.version) ||
8928 (versionCompiled.revision != versionReported.revision))
8929 {
8930 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8931 "Host expected %u.%u.%u.%u\n",
8932 WLAN_MODULE_NAME,
8933 (int)versionReported.major,
8934 (int)versionReported.minor,
8935 (int)versionReported.version,
8936 (int)versionReported.revision,
8937 (int)versionCompiled.major,
8938 (int)versionCompiled.minor,
8939 (int)versionCompiled.version,
8940 (int)versionCompiled.revision);
8941 }
8942 else
8943 {
8944 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8945 WLAN_MODULE_NAME,
8946 (int)versionReported.major,
8947 (int)versionReported.minor,
8948 (int)versionReported.version,
8949 (int)versionReported.revision);
8950 }
8951
8952 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8953 versionString,
8954 sizeof(versionString));
8955 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8956 {
8957 hddLog(VOS_TRACE_LEVEL_FATAL,
8958 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008959 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008960 break;
8961 }
8962
8963 pr_info("%s: WCNSS software version %s\n",
8964 WLAN_MODULE_NAME, versionString);
8965
8966 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8967 versionString,
8968 sizeof(versionString));
8969 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8970 {
8971 hddLog(VOS_TRACE_LEVEL_FATAL,
8972 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008973 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008974 break;
8975 }
8976
8977 pr_info("%s: WCNSS hardware version %s\n",
8978 WLAN_MODULE_NAME, versionString);
8979
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008980 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8981 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008982 send the message only if it the riva is 1.1
8983 minor numbers for different riva branches:
8984 0 -> (1.0)Mainline Build
8985 1 -> (1.1)Mainline Build
8986 2->(1.04) Stability Build
8987 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008988 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008989 ((versionReported.minor>=1) && (versionReported.version>=1)))
8990 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8991 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008992
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008993 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008994 {
8995#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8996 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8997 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8998#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008999 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9000 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9001 {
9002 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9003 }
9004
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009005 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009006 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009007
9008 } while (0);
9009
9010}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309011void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9012{
9013 struct sk_buff *skb;
9014 struct nlmsghdr *nlh;
9015 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309016 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309017
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309018 if (in_interrupt() || irqs_disabled() || in_atomic())
9019 flags = GFP_ATOMIC;
9020
9021 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309022
9023 if(skb == NULL) {
9024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9025 "%s: alloc_skb failed", __func__);
9026 return;
9027 }
9028
9029 nlh = (struct nlmsghdr *)skb->data;
9030 nlh->nlmsg_pid = 0; /* from kernel */
9031 nlh->nlmsg_flags = 0;
9032 nlh->nlmsg_seq = 0;
9033 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9034
9035 ani_hdr = NLMSG_DATA(nlh);
9036 ani_hdr->type = type;
9037
9038 switch(type) {
9039 case WLAN_SVC_SAP_RESTART_IND:
9040 ani_hdr->length = 0;
9041 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9042 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9043 break;
9044 default:
9045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9046 "Attempt to send unknown nlink message %d", type);
9047 kfree_skb(skb);
9048 return;
9049 }
9050
9051 nl_srv_bcast(skb);
9052
9053 return;
9054}
9055
9056
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009057
9058/**---------------------------------------------------------------------------
9059
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309060 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9061
9062 \param - pHddCtx - Pointer to the hdd context
9063
9064 \return - true if hardware supports 5GHz
9065
9066 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309067boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309068{
9069 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9070 * then hardware support 5Ghz.
9071 */
9072 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9073 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309075 return true;
9076 }
9077 else
9078 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309079 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309080 __func__);
9081 return false;
9082 }
9083}
9084
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309085/**---------------------------------------------------------------------------
9086
9087 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9088 generate function
9089
9090 This is generate the random mac address for WLAN interface
9091
9092 \param - pHddCtx - Pointer to HDD context
9093 idx - Start interface index to get auto
9094 generated mac addr.
9095 mac_addr - Mac address
9096
9097 \return - 0 for success, < 0 for failure
9098
9099 --------------------------------------------------------------------------*/
9100
9101static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9102 int idx, v_MACADDR_t mac_addr)
9103{
9104 int i;
9105 unsigned int serialno;
9106 serialno = wcnss_get_serial_number();
9107
9108 if (0 != serialno)
9109 {
9110 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9111 bytes of the serial number that can be used to generate
9112 the other 3 bytes of the MAC address. Mask off all but
9113 the lower 3 bytes (this will also make sure we don't
9114 overflow in the next step) */
9115 serialno &= 0x00FFFFFF;
9116
9117 /* we need a unique address for each session */
9118 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9119
9120 /* autogen other Mac addresses */
9121 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9122 {
9123 /* start with the entire default address */
9124 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9125 /* then replace the lower 3 bytes */
9126 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9127 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9128 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9129
9130 serialno++;
9131 hddLog(VOS_TRACE_LEVEL_ERROR,
9132 "%s: Derived Mac Addr: "
9133 MAC_ADDRESS_STR, __func__,
9134 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9135 }
9136
9137 }
9138 else
9139 {
9140 hddLog(LOGE, FL("Failed to Get Serial NO"));
9141 return -1;
9142 }
9143 return 0;
9144}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309145
Katya Nigame7b69a82015-04-28 15:24:06 +05309146int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9147{
9148 VOS_STATUS status;
9149 v_CONTEXT_t pVosContext= NULL;
9150 hdd_adapter_t *pAdapter= NULL;
9151
9152 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9153
9154 if (NULL == pVosContext)
9155 {
9156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9157 "%s: Trying to open VOSS without a PreOpen", __func__);
9158 VOS_ASSERT(0);
9159 return VOS_STATUS_E_FAILURE;
9160 }
9161
9162 status = vos_nv_open();
9163 if (!VOS_IS_STATUS_SUCCESS(status))
9164 {
9165 /* NV module cannot be initialized */
9166 hddLog( VOS_TRACE_LEVEL_FATAL,
9167 "%s: vos_nv_open failed", __func__);
9168 return VOS_STATUS_E_FAILURE;
9169 }
9170
9171 status = vos_init_wiphy_from_nv_bin();
9172 if (!VOS_IS_STATUS_SUCCESS(status))
9173 {
9174 /* NV module cannot be initialized */
9175 hddLog( VOS_TRACE_LEVEL_FATAL,
9176 "%s: vos_init_wiphy failed", __func__);
9177 goto err_vos_nv_close;
9178 }
9179
9180 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9181 if ( !VOS_IS_STATUS_SUCCESS( status ))
9182 {
9183 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9184 goto err_vos_nv_close;
9185 }
9186
9187 status = vos_mon_start( pVosContext );
9188 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9189 {
9190 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9191 goto err_vosclose;
9192 }
9193
9194 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9195 WDA_featureCapsExchange(pVosContext);
9196 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9197
9198 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9199 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9200 if( pAdapter == NULL )
9201 {
9202 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9203 goto err_close_adapter;
9204 }
9205
9206 //Initialize the nlink service
9207 if(nl_srv_init() != 0)
9208 {
9209 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9210 goto err_close_adapter;
9211 }
9212 return VOS_STATUS_SUCCESS;
9213
9214err_close_adapter:
9215 hdd_close_all_adapters( pHddCtx );
9216 vos_mon_stop( pVosContext );
9217err_vosclose:
9218 status = vos_sched_close( pVosContext );
9219 if (!VOS_IS_STATUS_SUCCESS(status)) {
9220 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9221 "%s: Failed to close VOSS Scheduler", __func__);
9222 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9223 }
9224 vos_close(pVosContext );
9225
9226err_vos_nv_close:
9227 vos_nv_close();
9228
9229return status;
9230}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309231/**---------------------------------------------------------------------------
9232
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309233 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9234 completed to flush out the scan results
9235
9236 11d scan is done during driver load and is a passive scan on all
9237 channels supported by the device, 11d scans may find some APs on
9238 frequencies which are forbidden to be used in the regulatory domain
9239 the device is operating in. If these APs are notified to the supplicant
9240 it may try to connect to these APs, thus flush out all the scan results
9241 which are present in SME after 11d scan is done.
9242
9243 \return - eHalStatus
9244
9245 --------------------------------------------------------------------------*/
9246static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9247 tANI_U32 scanId, eCsrScanStatus status)
9248{
9249 ENTER();
9250
9251 sme_ScanFlushResult(halHandle, 0);
9252
9253 EXIT();
9254
9255 return eHAL_STATUS_SUCCESS;
9256}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309257/**---------------------------------------------------------------------------
9258
9259 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9260 logging is completed successfully.
9261
9262 \return - None
9263
9264 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309265void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309266{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309267 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309268
9269 if (NULL == pHddCtx)
9270 {
9271 hddLog(VOS_TRACE_LEVEL_ERROR,
9272 "%s: HDD context is NULL",__func__);
9273 return;
9274 }
9275
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309276 if ((VOS_STATUS_SUCCESS == status) &&
9277 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309278 {
9279 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9280 pHddCtx->mgmt_frame_logging = TRUE;
9281 }
9282 else
9283 {
9284 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9285 pHddCtx->mgmt_frame_logging = FALSE;
9286 }
9287
9288 return;
9289}
9290/**---------------------------------------------------------------------------
9291
9292 \brief hdd_init_frame_logging - function to initialize frame logging.
9293 Currently only Mgmt Frames are logged in both TX
9294 and Rx direction and are sent to userspace
9295 application using logger thread when queried.
9296
9297 \return - None
9298
9299 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309300void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309301{
9302 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309303 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309304
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309305 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9306 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309307 {
9308 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9309 return;
9310 }
9311
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309312 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9313 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309314 {
9315 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9316 return;
9317 }
9318
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309319 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309320
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309321 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9322 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9323 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9324 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309325
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309326 if (pHddCtx->cfg_ini->enableFWLogging ||
9327 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309328 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309329 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309330 }
9331
Sushant Kaushik46804902015-07-08 14:46:03 +05309332 if (pHddCtx->cfg_ini->enableMgmtLogging)
9333 {
9334 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9335 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309336 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9337 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309338 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309339 }
9340
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309341 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9342 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9343 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9344 wlanFWLoggingInitParam->continuousFrameLogging =
9345 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309346
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309347 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309348
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309349 wlanFWLoggingInitParam->minLogBufferSize =
9350 pHddCtx->cfg_ini->minLoggingBufferSize;
9351 wlanFWLoggingInitParam->maxLogBufferSize =
9352 pHddCtx->cfg_ini->maxLoggingBufferSize;
9353 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9354 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309355
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309356 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309357
9358 if (eHAL_STATUS_SUCCESS != halStatus)
9359 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309360 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309361 }
9362
9363 return;
9364}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309365
9366/**---------------------------------------------------------------------------
9367
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 \brief hdd_wlan_startup() - HDD init function
9369
9370 This is the driver startup code executed once a WLAN device has been detected
9371
9372 \param - dev - Pointer to the underlying device
9373
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009374 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009375
9376 --------------------------------------------------------------------------*/
9377
9378int hdd_wlan_startup(struct device *dev )
9379{
9380 VOS_STATUS status;
9381 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009382 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009383 hdd_context_t *pHddCtx = NULL;
9384 v_CONTEXT_t pVosContext= NULL;
9385#ifdef WLAN_BTAMP_FEATURE
9386 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9387 WLANBAP_ConfigType btAmpConfig;
9388 hdd_config_t *pConfig;
9389#endif
9390 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009391 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309392 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009393
9394 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 /*
9396 * cfg80211: wiphy allocation
9397 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309398 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009399
9400 if(wiphy == NULL)
9401 {
9402 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009403 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 pHddCtx = wiphy_priv(wiphy);
9406
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 //Initialize the adapter context to zeros.
9408 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9409
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309411 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309412 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009413
9414 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9415
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309416 /* register for riva power on lock to platform driver
9417 * Locking power early to ensure FW doesn't reset by kernel while
9418 * host driver is busy initializing itself */
9419 if (req_riva_power_on_lock("wlan"))
9420 {
9421 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9422 __func__);
9423 goto err_free_hdd_context;
9424 }
9425
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 /*Get vos context here bcoz vos_open requires it*/
9427 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9428
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009429 if(pVosContext == NULL)
9430 {
9431 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9432 goto err_free_hdd_context;
9433 }
9434
Jeff Johnson295189b2012-06-20 16:38:30 -07009435 //Save the Global VOSS context in adapter context for future.
9436 pHddCtx->pvosContext = pVosContext;
9437
9438 //Save the adapter context in global context for future.
9439 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9440
Jeff Johnson295189b2012-06-20 16:38:30 -07009441 pHddCtx->parent_dev = dev;
9442
9443 init_completion(&pHddCtx->full_pwr_comp_var);
9444 init_completion(&pHddCtx->standby_comp_var);
9445 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009446 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009447 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309448 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309449 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009450
9451#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009452 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009453#else
9454 init_completion(&pHddCtx->driver_crda_req);
9455#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009456
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309457 spin_lock_init(&pHddCtx->schedScan_lock);
9458
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9460
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309461#ifdef FEATURE_WLAN_TDLS
9462 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9463 * invoked by other instances also) to protect the concurrent
9464 * access for the Adapters by TDLS module.
9465 */
9466 mutex_init(&pHddCtx->tdls_lock);
9467#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309468 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309469 mutex_init(&pHddCtx->wmmLock);
9470
Agarwal Ashish1f422872014-07-22 00:11:55 +05309471 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309472
Agarwal Ashish1f422872014-07-22 00:11:55 +05309473 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 // Load all config first as TL config is needed during vos_open
9475 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9476 if(pHddCtx->cfg_ini == NULL)
9477 {
9478 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9479 goto err_free_hdd_context;
9480 }
9481
9482 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9483
9484 // Read and parse the qcom_cfg.ini file
9485 status = hdd_parse_config_ini( pHddCtx );
9486 if ( VOS_STATUS_SUCCESS != status )
9487 {
9488 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9489 __func__, WLAN_INI_FILE);
9490 goto err_config;
9491 }
Arif Hussaind5218912013-12-05 01:10:55 -08009492#ifdef MEMORY_DEBUG
9493 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9494 vos_mem_init();
9495
9496 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9497 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9498#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009499
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309500 /* INI has been read, initialise the configuredMcastBcastFilter with
9501 * INI value as this will serve as the default value
9502 */
9503 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9504 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9505 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309506
9507 if (false == hdd_is_5g_supported(pHddCtx))
9508 {
9509 //5Ghz is not supported.
9510 if (1 != pHddCtx->cfg_ini->nBandCapability)
9511 {
9512 hddLog(VOS_TRACE_LEVEL_INFO,
9513 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9514 pHddCtx->cfg_ini->nBandCapability = 1;
9515 }
9516 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309517
9518 /* If SNR Monitoring is enabled, FW has to parse all beacons
9519 * for calcaluting and storing the average SNR, so set Nth beacon
9520 * filter to 1 to enable FW to parse all the beaocons
9521 */
9522 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9523 {
9524 /* The log level is deliberately set to WARN as overriding
9525 * nthBeaconFilter to 1 will increase power cosumption and this
9526 * might just prove helpful to detect the power issue.
9527 */
9528 hddLog(VOS_TRACE_LEVEL_WARN,
9529 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9530 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309533 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009534 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009535 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009537 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9538 {
9539 hddLog(VOS_TRACE_LEVEL_FATAL,
9540 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9541 goto err_config;
9542 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009544
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009545 // Update VOS trace levels based upon the cfg.ini
9546 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9547 pHddCtx->cfg_ini->vosTraceEnableBAP);
9548 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9549 pHddCtx->cfg_ini->vosTraceEnableTL);
9550 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9551 pHddCtx->cfg_ini->vosTraceEnableWDI);
9552 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9553 pHddCtx->cfg_ini->vosTraceEnableHDD);
9554 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9555 pHddCtx->cfg_ini->vosTraceEnableSME);
9556 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9557 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309558 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9559 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009560 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9561 pHddCtx->cfg_ini->vosTraceEnableWDA);
9562 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9563 pHddCtx->cfg_ini->vosTraceEnableSYS);
9564 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9565 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009566 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9567 pHddCtx->cfg_ini->vosTraceEnableSAP);
9568 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9569 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009570
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 // Update WDI trace levels based upon the cfg.ini
9572 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9573 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9574 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9575 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9576 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9577 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9578 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9579 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009580
Jeff Johnson88ba7742013-02-27 14:36:02 -08009581 if (VOS_FTM_MODE == hdd_get_conparam())
9582 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9584 {
9585 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9586 goto err_free_hdd_context;
9587 }
9588 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309589 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309590 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009591 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009593
Katya Nigame7b69a82015-04-28 15:24:06 +05309594 if( VOS_MONITOR_MODE == hdd_get_conparam())
9595 {
9596 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9597 {
9598 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9599 goto err_free_hdd_context;
9600 }
9601 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9602 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9603 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9604 return VOS_STATUS_SUCCESS;
9605 }
9606
Jeff Johnson88ba7742013-02-27 14:36:02 -08009607 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9609 {
9610 status = vos_watchdog_open(pVosContext,
9611 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9612
9613 if(!VOS_IS_STATUS_SUCCESS( status ))
9614 {
9615 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309616 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009617 }
9618 }
9619
9620 pHddCtx->isLogpInProgress = FALSE;
9621 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9622
Amar Singhala49cbc52013-10-08 18:37:44 -07009623#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009624 /* initialize the NV module. This is required so that
9625 we can initialize the channel information in wiphy
9626 from the NV.bin data. The channel information in
9627 wiphy needs to be initialized before wiphy registration */
9628
9629 status = vos_nv_open();
9630 if (!VOS_IS_STATUS_SUCCESS(status))
9631 {
9632 /* NV module cannot be initialized */
9633 hddLog( VOS_TRACE_LEVEL_FATAL,
9634 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309635 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009636 }
9637
9638 status = vos_init_wiphy_from_nv_bin();
9639 if (!VOS_IS_STATUS_SUCCESS(status))
9640 {
9641 /* NV module cannot be initialized */
9642 hddLog( VOS_TRACE_LEVEL_FATAL,
9643 "%s: vos_init_wiphy failed", __func__);
9644 goto err_vos_nv_close;
9645 }
9646
Amar Singhala49cbc52013-10-08 18:37:44 -07009647#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309648 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309649 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 if ( !VOS_IS_STATUS_SUCCESS( status ))
9651 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009652 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309653 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 }
9655
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9657
9658 if ( NULL == pHddCtx->hHal )
9659 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009660 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 goto err_vosclose;
9662 }
9663
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009664 status = vos_preStart( pHddCtx->pvosContext );
9665 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9666 {
9667 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309668 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009669 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009670
Arif Hussaineaf68602013-12-30 23:10:44 -08009671 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9672 {
9673 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9674 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9675 __func__, enable_dfs_chan_scan);
9676 }
9677 if (0 == enable_11d || 1 == enable_11d)
9678 {
9679 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9680 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9681 __func__, enable_11d);
9682 }
9683
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009684 /* Note that the vos_preStart() sequence triggers the cfg download.
9685 The cfg download must occur before we update the SME config
9686 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 status = hdd_set_sme_config( pHddCtx );
9688
9689 if ( VOS_STATUS_SUCCESS != status )
9690 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009691 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309692 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009693 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009694
Jeff Johnson295189b2012-06-20 16:38:30 -07009695 /* In the integrated architecture we update the configuration from
9696 the INI file and from NV before vOSS has been started so that
9697 the final contents are available to send down to the cCPU */
9698
9699 // Apply the cfg.ini to cfg.dat
9700 if (FALSE == hdd_update_config_dat(pHddCtx))
9701 {
9702 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309703 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 }
9705
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309706 // Get mac addr from platform driver
9707 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9708
9709 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309711 /* Store the mac addr for first interface */
9712 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9713
9714 hddLog(VOS_TRACE_LEVEL_ERROR,
9715 "%s: WLAN Mac Addr: "
9716 MAC_ADDRESS_STR, __func__,
9717 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9718
9719 /* Here, passing Arg2 as 1 because we do not want to change the
9720 last 3 bytes (means non OUI bytes) of first interface mac
9721 addr.
9722 */
9723 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9724 {
9725 hddLog(VOS_TRACE_LEVEL_ERROR,
9726 "%s: Failed to generate wlan interface mac addr "
9727 "using MAC from ini file ", __func__);
9728 }
9729 }
9730 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9731 {
9732 // Apply the NV to cfg.dat
9733 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009734#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9735 /* There was not a valid set of MAC Addresses in NV. See if the
9736 default addresses were modified by the cfg.ini settings. If so,
9737 we'll use them, but if not, we'll autogenerate a set of MAC
9738 addresses based upon the device serial number */
9739
9740 static const v_MACADDR_t default_address =
9741 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009742
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309743 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9744 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 {
9746 /* cfg.ini has the default address, invoke autogen logic */
9747
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309748 /* Here, passing Arg2 as 0 because we want to change the
9749 last 3 bytes (means non OUI bytes) of all the interfaces
9750 mac addr.
9751 */
9752 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9753 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009754 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309755 hddLog(VOS_TRACE_LEVEL_ERROR,
9756 "%s: Failed to generate wlan interface mac addr "
9757 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9758 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009760 }
9761 else
9762#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9763 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009764 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 "%s: Invalid MAC address in NV, using MAC from ini file "
9766 MAC_ADDRESS_STR, __func__,
9767 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9768 }
9769 }
9770 {
9771 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309772
9773 /* Set the MAC Address Currently this is used by HAL to
9774 * add self sta. Remove this once self sta is added as
9775 * part of session open.
9776 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9778 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9779 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309780
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 if (!HAL_STATUS_SUCCESS( halStatus ))
9782 {
9783 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9784 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309785 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 }
9787 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009788
9789 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9790 Note: Firmware image will be read and downloaded inside vos_start API */
9791 status = vos_start( pHddCtx->pvosContext );
9792 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9793 {
9794 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309795 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009796 }
9797
Leo Chang6cec3e22014-01-21 15:33:49 -08009798#ifdef FEATURE_WLAN_CH_AVOID
9799 /* Plug in avoid channel notification callback
9800 * This should happen before ADD_SELF_STA
9801 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309802
9803 /* check the Channel Avoidance is enabled */
9804 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9805 {
9806 sme_AddChAvoidCallback(pHddCtx->hHal,
9807 hdd_hostapd_ch_avoid_cb);
9808 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009809#endif /* FEATURE_WLAN_CH_AVOID */
9810
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009811 /* Exchange capability info between Host and FW and also get versioning info from FW */
9812 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009813
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309814#ifdef CONFIG_ENABLE_LINUX_REG
9815 status = wlan_hdd_init_channels(pHddCtx);
9816 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9817 {
9818 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9819 __func__);
9820 goto err_vosstop;
9821 }
9822#endif
9823
Jeff Johnson295189b2012-06-20 16:38:30 -07009824 status = hdd_post_voss_start_config( pHddCtx );
9825 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9826 {
9827 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9828 __func__);
9829 goto err_vosstop;
9830 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009831
9832#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309833 wlan_hdd_cfg80211_update_reg_info( wiphy );
9834
9835 /* registration of wiphy dev with cfg80211 */
9836 if (0 > wlan_hdd_cfg80211_register(wiphy))
9837 {
9838 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9839 goto err_vosstop;
9840 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009841#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009842
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309843#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309844 /* registration of wiphy dev with cfg80211 */
9845 if (0 > wlan_hdd_cfg80211_register(wiphy))
9846 {
9847 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9848 goto err_vosstop;
9849 }
9850
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309851 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309852 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9853 {
9854 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9855 __func__);
9856 goto err_unregister_wiphy;
9857 }
9858#endif
9859
c_hpothu4a298be2014-12-22 21:12:51 +05309860 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9861
Jeff Johnson295189b2012-06-20 16:38:30 -07009862 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9863 {
9864 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9865 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9866 }
9867 else
9868 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009869 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9870 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9871 if (pAdapter != NULL)
9872 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309873 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309875 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9876 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9877 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009878
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309879 /* Generate the P2P Device Address. This consists of the device's
9880 * primary MAC address with the locally administered bit set.
9881 */
9882 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009883 }
9884 else
9885 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309886 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9887 if (p2p_dev_addr != NULL)
9888 {
9889 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9890 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9891 }
9892 else
9893 {
9894 hddLog(VOS_TRACE_LEVEL_FATAL,
9895 "%s: Failed to allocate mac_address for p2p_device",
9896 __func__);
9897 goto err_close_adapter;
9898 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009900
9901 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9902 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9903 if ( NULL == pP2pAdapter )
9904 {
9905 hddLog(VOS_TRACE_LEVEL_FATAL,
9906 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009907 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009908 goto err_close_adapter;
9909 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009912
9913 if( pAdapter == NULL )
9914 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9916 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009918
Arif Hussain66559122013-11-21 10:11:40 -08009919 if (country_code)
9920 {
9921 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009922 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009923 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9924#ifndef CONFIG_ENABLE_LINUX_REG
9925 hdd_checkandupdate_phymode(pAdapter, country_code);
9926#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009927 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9928 (void *)(tSmeChangeCountryCallback)
9929 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009930 country_code,
9931 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309932 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009933 if (eHAL_STATUS_SUCCESS == ret)
9934 {
Arif Hussaincb607082013-12-20 11:57:42 -08009935 ret = wait_for_completion_interruptible_timeout(
9936 &pAdapter->change_country_code,
9937 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9938
9939 if (0 >= ret)
9940 {
9941 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9942 "%s: SME while setting country code timed out", __func__);
9943 }
Arif Hussain66559122013-11-21 10:11:40 -08009944 }
9945 else
9946 {
Arif Hussaincb607082013-12-20 11:57:42 -08009947 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9948 "%s: SME Change Country code from module param fail ret=%d",
9949 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009950 }
9951 }
9952
Jeff Johnson295189b2012-06-20 16:38:30 -07009953#ifdef WLAN_BTAMP_FEATURE
9954 vStatus = WLANBAP_Open(pVosContext);
9955 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9956 {
9957 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9958 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009959 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 }
9961
9962 vStatus = BSL_Init(pVosContext);
9963 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9964 {
9965 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9966 "%s: Failed to Init BSL",__func__);
9967 goto err_bap_close;
9968 }
9969 vStatus = WLANBAP_Start(pVosContext);
9970 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9971 {
9972 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9973 "%s: Failed to start TL",__func__);
9974 goto err_bap_close;
9975 }
9976
9977 pConfig = pHddCtx->cfg_ini;
9978 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9979 status = WLANBAP_SetConfig(&btAmpConfig);
9980
9981#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009982
Mihir Shete9c238772014-10-15 14:35:16 +05309983 /*
9984 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9985 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9986 * which is greater than 0xf. So the below check is safe to make
9987 * sure that there is no entry for UapsdMask in the ini
9988 */
9989 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9990 {
9991 if(IS_DYNAMIC_WMM_PS_ENABLED)
9992 {
9993 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9994 __func__);
9995 pHddCtx->cfg_ini->UapsdMask =
9996 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9997 }
9998 else
9999 {
10000 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10001 __func__);
10002 pHddCtx->cfg_ini->UapsdMask =
10003 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10004 }
10005 }
10006
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010007#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10008 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10009 {
10010 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10011 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10012 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10013 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10014 }
10015#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010016
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010017 wlan_hdd_tdls_init(pHddCtx);
10018
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010019 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10020
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 /* Register with platform driver as client for Suspend/Resume */
10022 status = hddRegisterPmOps(pHddCtx);
10023 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10024 {
10025 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10026#ifdef WLAN_BTAMP_FEATURE
10027 goto err_bap_stop;
10028#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010029 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010030#endif //WLAN_BTAMP_FEATURE
10031 }
10032
Yue Ma0d4891e2013-08-06 17:01:45 -070010033 /* Open debugfs interface */
10034 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10035 {
10036 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10037 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010038 }
10039
Jeff Johnson295189b2012-06-20 16:38:30 -070010040 /* Register TM level change handler function to the platform */
10041 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10042 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10043 {
10044 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10045 goto err_unregister_pmops;
10046 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010047
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 // register net device notifier for device change notification
10049 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10050
10051 if(ret < 0)
10052 {
10053 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010054 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010055 }
10056
10057 //Initialize the nlink service
10058 if(nl_srv_init() != 0)
10059 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010060 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 goto err_reg_netdev;
10062 }
10063
Leo Chang4ce1cc52013-10-21 18:27:15 -070010064#ifdef WLAN_KD_READY_NOTIFIER
10065 pHddCtx->kd_nl_init = 1;
10066#endif /* WLAN_KD_READY_NOTIFIER */
10067
Jeff Johnson295189b2012-06-20 16:38:30 -070010068 //Initialize the BTC service
10069 if(btc_activate_service(pHddCtx) != 0)
10070 {
10071 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10072 goto err_nl_srv;
10073 }
10074
10075#ifdef PTT_SOCK_SVC_ENABLE
10076 //Initialize the PTT service
10077 if(ptt_sock_activate_svc(pHddCtx) != 0)
10078 {
10079 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10080 goto err_nl_srv;
10081 }
10082#endif
10083
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010084#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10085 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10086 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010087 if(wlan_logging_sock_activate_svc(
10088 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10089 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10090 {
10091 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10092 " failed", __func__);
10093 goto err_nl_srv;
10094 }
10095 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10096 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010097 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10098 pHddCtx->cfg_ini->gEnableDebugLog =
10099 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010100 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010101
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010102 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10103 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010104 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010105 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010106 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010107 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010108 }
10109 else
10110 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010111 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010112 }
10113
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010114#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010115
10116
Sushant Kaushik215778f2015-05-21 14:05:36 +053010117 if (vos_is_multicast_logging())
10118 wlan_logging_set_log_level();
10119
Jeff Johnson295189b2012-06-20 16:38:30 -070010120 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010121 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010123 /* Action frame registered in one adapter which will
10124 * applicable to all interfaces
10125 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010126 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010128
10129 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010130 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010131
Jeff Johnsone7245742012-09-05 17:12:55 -070010132#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10133 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010134 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010135 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010136
Jeff Johnsone7245742012-09-05 17:12:55 -070010137#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010138 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010139 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010140 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010141
Jeff Johnsone7245742012-09-05 17:12:55 -070010142
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010143 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10144 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010145
Katya Nigam5c306ea2014-06-19 15:39:54 +053010146 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010148 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010149
10150#ifdef FEATURE_WLAN_SCAN_PNO
10151 /*SME must send channel update configuration to RIVA*/
10152 sme_UpdateChannelConfig(pHddCtx->hHal);
10153#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010154 /* Send the update default channel list to the FW*/
10155 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010156
10157 /* Fwr capabilities received, Set the Dot11 mode */
10158 sme_SetDefDot11Mode(pHddCtx->hHal);
10159
Abhishek Singha306a442013-11-07 18:39:01 +053010160#ifndef CONFIG_ENABLE_LINUX_REG
10161 /*updating wiphy so that regulatory user hints can be processed*/
10162 if (wiphy)
10163 {
10164 regulatory_hint(wiphy, "00");
10165 }
10166#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010167 // Initialize the restart logic
10168 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010169
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010170 //Register the traffic monitor timer now
10171 if ( pHddCtx->cfg_ini->dynSplitscan)
10172 {
10173 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10174 VOS_TIMER_TYPE_SW,
10175 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10176 (void *)pHddCtx);
10177 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010178 wlan_hdd_cfg80211_nan_init(pHddCtx);
10179
Dino Mycle6fb96c12014-06-10 11:52:40 +053010180#ifdef WLAN_FEATURE_EXTSCAN
10181 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10182 wlan_hdd_cfg80211_extscan_callback,
10183 pHddCtx);
10184#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010185
10186#ifdef WLAN_NS_OFFLOAD
10187 // Register IPv6 notifier to notify if any change in IP
10188 // So that we can reconfigure the offload parameters
10189 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10190 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10191 if (ret)
10192 {
10193 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10194 }
10195 else
10196 {
10197 hddLog(LOGE, FL("Registered IPv6 notifier"));
10198 }
10199#endif
10200
10201 // Register IPv4 notifier to notify if any change in IP
10202 // So that we can reconfigure the offload parameters
10203 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10204 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10205 if (ret)
10206 {
10207 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10208 }
10209 else
10210 {
10211 hddLog(LOGE, FL("Registered IPv4 notifier"));
10212 }
10213
Jeff Johnson295189b2012-06-20 16:38:30 -070010214 goto success;
10215
10216err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010217#ifdef WLAN_KD_READY_NOTIFIER
10218 nl_srv_exit(pHddCtx->ptt_pid);
10219#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010221#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010222err_reg_netdev:
10223 unregister_netdevice_notifier(&hdd_netdev_notifier);
10224
Jeff Johnson295189b2012-06-20 16:38:30 -070010225err_unregister_pmops:
10226 hddDevTmUnregisterNotifyCallback(pHddCtx);
10227 hddDeregisterPmOps(pHddCtx);
10228
Yue Ma0d4891e2013-08-06 17:01:45 -070010229 hdd_debugfs_exit(pHddCtx);
10230
Jeff Johnson295189b2012-06-20 16:38:30 -070010231#ifdef WLAN_BTAMP_FEATURE
10232err_bap_stop:
10233 WLANBAP_Stop(pVosContext);
10234#endif
10235
10236#ifdef WLAN_BTAMP_FEATURE
10237err_bap_close:
10238 WLANBAP_Close(pVosContext);
10239#endif
10240
Jeff Johnson295189b2012-06-20 16:38:30 -070010241err_close_adapter:
10242 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010243#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010244err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010245#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010246 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010247err_vosstop:
10248 vos_stop(pVosContext);
10249
Amar Singhala49cbc52013-10-08 18:37:44 -070010250err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010251 status = vos_sched_close( pVosContext );
10252 if (!VOS_IS_STATUS_SUCCESS(status)) {
10253 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10254 "%s: Failed to close VOSS Scheduler", __func__);
10255 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10256 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010257 vos_close(pVosContext );
10258
Amar Singhal0a402232013-10-11 20:57:16 -070010259err_vos_nv_close:
10260
c_hpothue6a36282014-03-19 12:27:38 +053010261#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010262 vos_nv_close();
10263
c_hpothu70f8d812014-03-22 22:59:23 +053010264#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010265
10266err_wdclose:
10267 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10268 vos_watchdog_close(pVosContext);
10269
Jeff Johnson295189b2012-06-20 16:38:30 -070010270err_config:
10271 kfree(pHddCtx->cfg_ini);
10272 pHddCtx->cfg_ini= NULL;
10273
10274err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010275 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010276 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010277 wiphy_free(wiphy) ;
10278 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 VOS_BUG(1);
10280
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010281 if (hdd_is_ssr_required())
10282 {
10283 /* WDI timeout had happened during load, so SSR is needed here */
10284 subsystem_restart("wcnss");
10285 msleep(5000);
10286 }
10287 hdd_set_ssr_required (VOS_FALSE);
10288
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010289 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010290
10291success:
10292 EXIT();
10293 return 0;
10294}
10295
10296/**---------------------------------------------------------------------------
10297
Jeff Johnson32d95a32012-09-10 13:15:23 -070010298 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010299
Jeff Johnson32d95a32012-09-10 13:15:23 -070010300 This is the driver entry point - called in different timeline depending
10301 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010302
10303 \param - None
10304
10305 \return - 0 for success, non zero for failure
10306
10307 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010308static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010309{
10310 VOS_STATUS status;
10311 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010312 struct device *dev = NULL;
10313 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010314#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10315 int max_retries = 0;
10316#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010317#ifdef HAVE_CBC_DONE
10318 int max_cbc_retries = 0;
10319#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010320
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010321#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10322 wlan_logging_sock_init_svc();
10323#endif
10324
Jeff Johnson295189b2012-06-20 16:38:30 -070010325 ENTER();
10326
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010327 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010328
10329 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10330 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10331
Jeff Johnson295189b2012-06-20 16:38:30 -070010332#ifdef ANI_BUS_TYPE_PCI
10333
10334 dev = wcnss_wlan_get_device();
10335
10336#endif // ANI_BUS_TYPE_PCI
10337
10338#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010339
10340#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10341 /* wait until WCNSS driver downloads NV */
10342 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10343 msleep(1000);
10344 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010345
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010346 if (max_retries >= 5) {
10347 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010348 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010349#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10350 wlan_logging_sock_deinit_svc();
10351#endif
10352
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010353 return -ENODEV;
10354 }
10355#endif
10356
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010357#ifdef HAVE_CBC_DONE
10358 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10359 msleep(1000);
10360 }
10361 if (max_cbc_retries >= 10) {
10362 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10363 }
10364#endif
10365
Jeff Johnson295189b2012-06-20 16:38:30 -070010366 dev = wcnss_wlan_get_device();
10367#endif // ANI_BUS_TYPE_PLATFORM
10368
10369
10370 do {
10371 if (NULL == dev) {
10372 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10373 ret_status = -1;
10374 break;
10375 }
10376
Jeff Johnson295189b2012-06-20 16:38:30 -070010377#ifdef TIMER_MANAGER
10378 vos_timer_manager_init();
10379#endif
10380
10381 /* Preopen VOSS so that it is ready to start at least SAL */
10382 status = vos_preOpen(&pVosContext);
10383
10384 if (!VOS_IS_STATUS_SUCCESS(status))
10385 {
10386 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10387 ret_status = -1;
10388 break;
10389 }
10390
Sushant Kaushik02beb352015-06-04 15:15:01 +053010391 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010392#ifndef MODULE
10393 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10394 */
10395 hdd_set_conparam((v_UINT_t)con_mode);
10396#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010397
10398 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010399 if (hdd_wlan_startup(dev))
10400 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010402 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 vos_preClose( &pVosContext );
10404 ret_status = -1;
10405 break;
10406 }
10407
Jeff Johnson295189b2012-06-20 16:38:30 -070010408 } while (0);
10409
10410 if (0 != ret_status)
10411 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010412#ifdef TIMER_MANAGER
10413 vos_timer_exit();
10414#endif
10415#ifdef MEMORY_DEBUG
10416 vos_mem_exit();
10417#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010418 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010419#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10420 wlan_logging_sock_deinit_svc();
10421#endif
10422
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10424 }
10425 else
10426 {
10427 //Send WLAN UP indication to Nlink Service
10428 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10429
10430 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 }
10432
10433 EXIT();
10434
10435 return ret_status;
10436}
10437
Jeff Johnson32d95a32012-09-10 13:15:23 -070010438/**---------------------------------------------------------------------------
10439
10440 \brief hdd_module_init() - Init Function
10441
10442 This is the driver entry point (invoked when module is loaded using insmod)
10443
10444 \param - None
10445
10446 \return - 0 for success, non zero for failure
10447
10448 --------------------------------------------------------------------------*/
10449#ifdef MODULE
10450static int __init hdd_module_init ( void)
10451{
10452 return hdd_driver_init();
10453}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010454#else /* #ifdef MODULE */
10455static int __init hdd_module_init ( void)
10456{
10457 /* Driver initialization is delayed to fwpath_changed_handler */
10458 return 0;
10459}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010460#endif /* #ifdef MODULE */
10461
Jeff Johnson295189b2012-06-20 16:38:30 -070010462
10463/**---------------------------------------------------------------------------
10464
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010465 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010466
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010467 This is the driver exit point (invoked when module is unloaded using rmmod
10468 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010469
10470 \param - None
10471
10472 \return - None
10473
10474 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010475static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010476{
10477 hdd_context_t *pHddCtx = NULL;
10478 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010479 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010480 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010481
10482 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10483
10484 //Get the global vos context
10485 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10486
10487 if(!pVosContext)
10488 {
10489 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10490 goto done;
10491 }
10492
10493 //Get the HDD context.
10494 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10495
10496 if(!pHddCtx)
10497 {
10498 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10499 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010500 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10501 {
10502 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10503 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10504 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10505 hdd_wlan_exit(pHddCtx);
10506 vos_preClose( &pVosContext );
10507 goto done;
10508 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 else
10510 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010511 /* We wait for active entry threads to exit from driver
10512 * by waiting until rtnl_lock is available.
10513 */
10514 rtnl_lock();
10515 rtnl_unlock();
10516
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010517 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10518 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10519 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10520 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010522 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010523 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10524 msecs_to_jiffies(30000));
10525 if(!rc)
10526 {
10527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10528 "%s:SSR timedout, fatal error", __func__);
10529 VOS_BUG(0);
10530 }
10531 }
10532
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010533 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10534 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010535
c_hpothu8adb97b2014-12-08 19:38:20 +053010536 /* Driver Need to send country code 00 in below condition
10537 * 1) If gCountryCodePriority is set to 1; and last country
10538 * code set is through 11d. This needs to be done in case
10539 * when NV country code is 00.
10540 * This Needs to be done as when kernel store last country
10541 * code and if stored country code is not through 11d,
10542 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10543 * in next load/unload as soon as we get any country through
10544 * 11d. In sme_HandleChangeCountryCodeByUser
10545 * pMsg->countryCode will be last countryCode and
10546 * pMac->scan.countryCode11d will be country through 11d so
10547 * due to mismatch driver will disable 11d.
10548 *
10549 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010550
c_hpothu8adb97b2014-12-08 19:38:20 +053010551 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010552 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010553 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010554 {
10555 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010556 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010557 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10558 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010559
c_hpothu8adb97b2014-12-08 19:38:20 +053010560 //Do all the cleanup before deregistering the driver
10561 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 }
10563
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 vos_preClose( &pVosContext );
10565
10566#ifdef TIMER_MANAGER
10567 vos_timer_exit();
10568#endif
10569#ifdef MEMORY_DEBUG
10570 vos_mem_exit();
10571#endif
10572
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010573#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10574 wlan_logging_sock_deinit_svc();
10575#endif
10576
Jeff Johnson295189b2012-06-20 16:38:30 -070010577done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010578 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010579
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10581}
10582
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010583/**---------------------------------------------------------------------------
10584
10585 \brief hdd_module_exit() - Exit function
10586
10587 This is the driver exit point (invoked when module is unloaded using rmmod)
10588
10589 \param - None
10590
10591 \return - None
10592
10593 --------------------------------------------------------------------------*/
10594static void __exit hdd_module_exit(void)
10595{
10596 hdd_driver_exit();
10597}
10598
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010599#ifdef MODULE
10600static int fwpath_changed_handler(const char *kmessage,
10601 struct kernel_param *kp)
10602{
Jeff Johnson76052702013-04-16 13:55:05 -070010603 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010604}
10605
10606static int con_mode_handler(const char *kmessage,
10607 struct kernel_param *kp)
10608{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010609 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010610}
10611#else /* #ifdef MODULE */
10612/**---------------------------------------------------------------------------
10613
Jeff Johnson76052702013-04-16 13:55:05 -070010614 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010615
Jeff Johnson76052702013-04-16 13:55:05 -070010616 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010617 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010618 - invoked when module parameter fwpath is modified from userspace to signal
10619 initializing the WLAN driver or when con_mode is modified from userspace
10620 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010621
10622 \return - 0 for success, non zero for failure
10623
10624 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010625static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010626{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010627 int ret_status;
10628
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010629 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010630 ret_status = hdd_driver_init();
10631 wlan_hdd_inited = ret_status ? 0 : 1;
10632 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010633 }
10634
10635 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010636
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010637 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010638
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010639 ret_status = hdd_driver_init();
10640 wlan_hdd_inited = ret_status ? 0 : 1;
10641 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010642}
10643
Jeff Johnson295189b2012-06-20 16:38:30 -070010644/**---------------------------------------------------------------------------
10645
Jeff Johnson76052702013-04-16 13:55:05 -070010646 \brief fwpath_changed_handler() - Handler Function
10647
10648 Handle changes to the fwpath parameter
10649
10650 \return - 0 for success, non zero for failure
10651
10652 --------------------------------------------------------------------------*/
10653static int fwpath_changed_handler(const char *kmessage,
10654 struct kernel_param *kp)
10655{
10656 int ret;
10657
10658 ret = param_set_copystring(kmessage, kp);
10659 if (0 == ret)
10660 ret = kickstart_driver();
10661 return ret;
10662}
10663
10664/**---------------------------------------------------------------------------
10665
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010666 \brief con_mode_handler() -
10667
10668 Handler function for module param con_mode when it is changed by userspace
10669 Dynamically linked - do nothing
10670 Statically linked - exit and init driver, as in rmmod and insmod
10671
Jeff Johnson76052702013-04-16 13:55:05 -070010672 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010673
Jeff Johnson76052702013-04-16 13:55:05 -070010674 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010675
10676 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010677static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010678{
Jeff Johnson76052702013-04-16 13:55:05 -070010679 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010680
Jeff Johnson76052702013-04-16 13:55:05 -070010681 ret = param_set_int(kmessage, kp);
10682 if (0 == ret)
10683 ret = kickstart_driver();
10684 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010685}
10686#endif /* #ifdef MODULE */
10687
10688/**---------------------------------------------------------------------------
10689
Jeff Johnson295189b2012-06-20 16:38:30 -070010690 \brief hdd_get_conparam() -
10691
10692 This is the driver exit point (invoked when module is unloaded using rmmod)
10693
10694 \param - None
10695
10696 \return - tVOS_CON_MODE
10697
10698 --------------------------------------------------------------------------*/
10699tVOS_CON_MODE hdd_get_conparam ( void )
10700{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010701#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010702 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010703#else
10704 return (tVOS_CON_MODE)curr_con_mode;
10705#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010706}
10707void hdd_set_conparam ( v_UINT_t newParam )
10708{
10709 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010710#ifndef MODULE
10711 curr_con_mode = con_mode;
10712#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010713}
10714/**---------------------------------------------------------------------------
10715
10716 \brief hdd_softap_sta_deauth() - function
10717
10718 This to take counter measure to handle deauth req from HDD
10719
10720 \param - pAdapter - Pointer to the HDD
10721
10722 \param - enable - boolean value
10723
10724 \return - None
10725
10726 --------------------------------------------------------------------------*/
10727
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010728VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10729 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010730{
Jeff Johnson295189b2012-06-20 16:38:30 -070010731 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010732 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010733
10734 ENTER();
10735
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010736 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10737 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010738
10739 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010740 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010741 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010742
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010743 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010744
10745 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010746 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010747}
10748
10749/**---------------------------------------------------------------------------
10750
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010751 \brief hdd_del_all_sta() - function
10752
10753 This function removes all the stations associated on stopping AP/P2P GO.
10754
10755 \param - pAdapter - Pointer to the HDD
10756
10757 \return - None
10758
10759 --------------------------------------------------------------------------*/
10760
10761int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10762{
10763 v_U16_t i;
10764 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010765 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10766 ptSapContext pSapCtx = NULL;
10767 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10768 if(pSapCtx == NULL){
10769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10770 FL("psapCtx is NULL"));
10771 return 1;
10772 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010773 ENTER();
10774
10775 hddLog(VOS_TRACE_LEVEL_INFO,
10776 "%s: Delete all STAs associated.",__func__);
10777 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10778 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10779 )
10780 {
10781 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10782 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010783 if ((pSapCtx->aStaInfo[i].isUsed) &&
10784 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010785 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010786 struct tagCsrDelStaParams delStaParams;
10787
10788 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010789 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010790 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10791 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010792 &delStaParams);
10793 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010794 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010795 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010796 }
10797 }
10798 }
10799
10800 EXIT();
10801 return 0;
10802}
10803
10804/**---------------------------------------------------------------------------
10805
Jeff Johnson295189b2012-06-20 16:38:30 -070010806 \brief hdd_softap_sta_disassoc() - function
10807
10808 This to take counter measure to handle deauth req from HDD
10809
10810 \param - pAdapter - Pointer to the HDD
10811
10812 \param - enable - boolean value
10813
10814 \return - None
10815
10816 --------------------------------------------------------------------------*/
10817
10818void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10819{
10820 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10821
10822 ENTER();
10823
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010824 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010825
10826 //Ignore request to disassoc bcmc station
10827 if( pDestMacAddress[0] & 0x1 )
10828 return;
10829
10830 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10831}
10832
10833void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10834{
10835 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10836
10837 ENTER();
10838
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010839 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010840
10841 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10842}
10843
Jeff Johnson295189b2012-06-20 16:38:30 -070010844/**---------------------------------------------------------------------------
10845 *
10846 * \brief hdd_get__concurrency_mode() -
10847 *
10848 *
10849 * \param - None
10850 *
10851 * \return - CONCURRENCY MODE
10852 *
10853 * --------------------------------------------------------------------------*/
10854tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10855{
10856 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10857 hdd_context_t *pHddCtx;
10858
10859 if (NULL != pVosContext)
10860 {
10861 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10862 if (NULL != pHddCtx)
10863 {
10864 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10865 }
10866 }
10867
10868 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010869 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010870 return VOS_STA;
10871}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010872v_BOOL_t
10873wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10874{
10875 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010876
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010877 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10878 if (pAdapter == NULL)
10879 {
10880 hddLog(VOS_TRACE_LEVEL_INFO,
10881 FL("GO doesn't exist"));
10882 return TRUE;
10883 }
10884 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10885 {
10886 hddLog(VOS_TRACE_LEVEL_INFO,
10887 FL("GO started"));
10888 return TRUE;
10889 }
10890 else
10891 /* wait till GO changes its interface to p2p device */
10892 hddLog(VOS_TRACE_LEVEL_INFO,
10893 FL("Del_bss called, avoid apps suspend"));
10894 return FALSE;
10895
10896}
Jeff Johnson295189b2012-06-20 16:38:30 -070010897/* Decide whether to allow/not the apps power collapse.
10898 * Allow apps power collapse if we are in connected state.
10899 * if not, allow only if we are in IMPS */
10900v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10901{
10902 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010903 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010904 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10906 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10907 hdd_adapter_t *pAdapter = NULL;
10908 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010909 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010910
Jeff Johnson295189b2012-06-20 16:38:30 -070010911 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10912 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010913
Yathish9f22e662012-12-10 14:21:35 -080010914 concurrent_state = hdd_get_concurrency_mode();
10915
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010916 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10917 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10918 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010919#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010920
Yathish9f22e662012-12-10 14:21:35 -080010921 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010922 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010923 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10924 return TRUE;
10925#endif
10926
Jeff Johnson295189b2012-06-20 16:38:30 -070010927 /*loop through all adapters. TBD fix for Concurrency */
10928 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10929 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10930 {
10931 pAdapter = pAdapterNode->pAdapter;
10932 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10933 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10934 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010935 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010936 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010937 && pmcState != STOPPED && pmcState != STANDBY &&
10938 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010939 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10940 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010941 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010942 if(pmcState == FULL_POWER &&
10943 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10944 {
10945 /*
10946 * When SCO indication comes from Coex module , host will
10947 * enter in to full power mode, but this should not prevent
10948 * apps processor power collapse.
10949 */
10950 hddLog(LOG1,
10951 FL("Allow apps power collapse"
10952 "even when sco indication is set"));
10953 return TRUE;
10954 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010955 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010956 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10957 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 return FALSE;
10959 }
10960 }
10961 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10962 pAdapterNode = pNext;
10963 }
10964 return TRUE;
10965}
10966
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010967/* Decides whether to send suspend notification to Riva
10968 * if any adapter is in BMPS; then it is required */
10969v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10970{
10971 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10972 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10973
10974 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10975 {
10976 return TRUE;
10977 }
10978 return FALSE;
10979}
10980
Jeff Johnson295189b2012-06-20 16:38:30 -070010981void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10982{
10983 switch(mode)
10984 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010985 case VOS_STA_MODE:
10986 case VOS_P2P_CLIENT_MODE:
10987 case VOS_P2P_GO_MODE:
10988 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010989 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010990 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010991 break;
10992 default:
10993 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010994 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010995 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10996 "Number of open sessions for mode %d = %d"),
10997 pHddCtx->concurrency_mode, mode,
10998 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010999}
11000
11001
11002void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11003{
11004 switch(mode)
11005 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011006 case VOS_STA_MODE:
11007 case VOS_P2P_CLIENT_MODE:
11008 case VOS_P2P_GO_MODE:
11009 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011010 pHddCtx->no_of_open_sessions[mode]--;
11011 if (!(pHddCtx->no_of_open_sessions[mode]))
11012 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011013 break;
11014 default:
11015 break;
11016 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011017 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11018 "Number of open sessions for mode %d = %d"),
11019 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11020
11021}
11022/**---------------------------------------------------------------------------
11023 *
11024 * \brief wlan_hdd_incr_active_session()
11025 *
11026 * This function increments the number of active sessions
11027 * maintained per device mode
11028 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11029 * Incase of SAP/P2P GO upon bss start it is incremented
11030 *
11031 * \param pHddCtx - HDD Context
11032 * \param mode - device mode
11033 *
11034 * \return - None
11035 *
11036 * --------------------------------------------------------------------------*/
11037void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11038{
11039 switch (mode) {
11040 case VOS_STA_MODE:
11041 case VOS_P2P_CLIENT_MODE:
11042 case VOS_P2P_GO_MODE:
11043 case VOS_STA_SAP_MODE:
11044 pHddCtx->no_of_active_sessions[mode]++;
11045 break;
11046 default:
11047 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11048 break;
11049 }
11050 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11051 mode,
11052 pHddCtx->no_of_active_sessions[mode]);
11053}
11054
11055/**---------------------------------------------------------------------------
11056 *
11057 * \brief wlan_hdd_decr_active_session()
11058 *
11059 * This function decrements the number of active sessions
11060 * maintained per device mode
11061 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11062 * Incase of SAP/P2P GO upon bss stop it is decremented
11063 *
11064 * \param pHddCtx - HDD Context
11065 * \param mode - device mode
11066 *
11067 * \return - None
11068 *
11069 * --------------------------------------------------------------------------*/
11070void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11071{
11072 switch (mode) {
11073 case VOS_STA_MODE:
11074 case VOS_P2P_CLIENT_MODE:
11075 case VOS_P2P_GO_MODE:
11076 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011077 if (pHddCtx->no_of_active_sessions[mode] > 0)
11078 pHddCtx->no_of_active_sessions[mode]--;
11079 else
11080 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11081 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011082 break;
11083 default:
11084 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11085 break;
11086 }
11087 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11088 mode,
11089 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011090}
11091
Jeff Johnsone7245742012-09-05 17:12:55 -070011092/**---------------------------------------------------------------------------
11093 *
11094 * \brief wlan_hdd_restart_init
11095 *
11096 * This function initalizes restart timer/flag. An internal function.
11097 *
11098 * \param - pHddCtx
11099 *
11100 * \return - None
11101 *
11102 * --------------------------------------------------------------------------*/
11103
11104static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11105{
11106 /* Initialize */
11107 pHddCtx->hdd_restart_retries = 0;
11108 atomic_set(&pHddCtx->isRestartInProgress, 0);
11109 vos_timer_init(&pHddCtx->hdd_restart_timer,
11110 VOS_TIMER_TYPE_SW,
11111 wlan_hdd_restart_timer_cb,
11112 pHddCtx);
11113}
11114/**---------------------------------------------------------------------------
11115 *
11116 * \brief wlan_hdd_restart_deinit
11117 *
11118 * This function cleans up the resources used. An internal function.
11119 *
11120 * \param - pHddCtx
11121 *
11122 * \return - None
11123 *
11124 * --------------------------------------------------------------------------*/
11125
11126static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11127{
11128
11129 VOS_STATUS vos_status;
11130 /* Block any further calls */
11131 atomic_set(&pHddCtx->isRestartInProgress, 1);
11132 /* Cleanup */
11133 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11134 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011135 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011136 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11137 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011138 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011139
11140}
11141
11142/**---------------------------------------------------------------------------
11143 *
11144 * \brief wlan_hdd_framework_restart
11145 *
11146 * This function uses a cfg80211 API to start a framework initiated WLAN
11147 * driver module unload/load.
11148 *
11149 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11150 *
11151 *
11152 * \param - pHddCtx
11153 *
11154 * \return - VOS_STATUS_SUCCESS: Success
11155 * VOS_STATUS_E_EMPTY: Adapter is Empty
11156 * VOS_STATUS_E_NOMEM: No memory
11157
11158 * --------------------------------------------------------------------------*/
11159
11160static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11161{
11162 VOS_STATUS status = VOS_STATUS_SUCCESS;
11163 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011164 int len = (sizeof (struct ieee80211_mgmt));
11165 struct ieee80211_mgmt *mgmt = NULL;
11166
11167 /* Prepare the DEAUTH managment frame with reason code */
11168 mgmt = kzalloc(len, GFP_KERNEL);
11169 if(mgmt == NULL)
11170 {
11171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11172 "%s: memory allocation failed (%d bytes)", __func__, len);
11173 return VOS_STATUS_E_NOMEM;
11174 }
11175 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011176
11177 /* Iterate over all adapters/devices */
11178 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011179 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11180 {
11181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11182 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11183 goto end;
11184 }
11185
Jeff Johnsone7245742012-09-05 17:12:55 -070011186 do
11187 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011188 if(pAdapterNode->pAdapter &&
11189 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011190 {
11191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11192 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11193 pAdapterNode->pAdapter->dev->name,
11194 pAdapterNode->pAdapter->device_mode,
11195 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011196 /*
11197 * CFG80211 event to restart the driver
11198 *
11199 * 'cfg80211_send_unprot_deauth' sends a
11200 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11201 * of SME(Linux Kernel) state machine.
11202 *
11203 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11204 * the driver.
11205 *
11206 */
11207
11208 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011209 }
11210 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11211 pAdapterNode = pNext;
11212 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11213
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011214 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011215 /* Free the allocated management frame */
11216 kfree(mgmt);
11217
Jeff Johnsone7245742012-09-05 17:12:55 -070011218 /* Retry until we unload or reach max count */
11219 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11220 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11221
11222 return status;
11223
11224}
11225/**---------------------------------------------------------------------------
11226 *
11227 * \brief wlan_hdd_restart_timer_cb
11228 *
11229 * Restart timer callback. An internal function.
11230 *
11231 * \param - User data:
11232 *
11233 * \return - None
11234 *
11235 * --------------------------------------------------------------------------*/
11236
11237void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11238{
11239 hdd_context_t *pHddCtx = usrDataForCallback;
11240 wlan_hdd_framework_restart(pHddCtx);
11241 return;
11242
11243}
11244
11245
11246/**---------------------------------------------------------------------------
11247 *
11248 * \brief wlan_hdd_restart_driver
11249 *
11250 * This function sends an event to supplicant to restart the WLAN driver.
11251 *
11252 * This function is called from vos_wlanRestart.
11253 *
11254 * \param - pHddCtx
11255 *
11256 * \return - VOS_STATUS_SUCCESS: Success
11257 * VOS_STATUS_E_EMPTY: Adapter is Empty
11258 * VOS_STATUS_E_ALREADY: Request already in progress
11259
11260 * --------------------------------------------------------------------------*/
11261VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11262{
11263 VOS_STATUS status = VOS_STATUS_SUCCESS;
11264
11265 /* A tight check to make sure reentrancy */
11266 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11267 {
Mihir Shetefd528652014-06-23 19:07:50 +053011268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011269 "%s: WLAN restart is already in progress", __func__);
11270
11271 return VOS_STATUS_E_ALREADY;
11272 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011273 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011274#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011275 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011276#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011277
Jeff Johnsone7245742012-09-05 17:12:55 -070011278 return status;
11279}
11280
Mihir Shetee1093ba2014-01-21 20:13:32 +053011281/**---------------------------------------------------------------------------
11282 *
11283 * \brief wlan_hdd_init_channels
11284 *
11285 * This function is used to initialize the channel list in CSR
11286 *
11287 * This function is called from hdd_wlan_startup
11288 *
11289 * \param - pHddCtx: HDD context
11290 *
11291 * \return - VOS_STATUS_SUCCESS: Success
11292 * VOS_STATUS_E_FAULT: Failure reported by SME
11293
11294 * --------------------------------------------------------------------------*/
11295static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11296{
11297 eHalStatus status;
11298
11299 status = sme_InitChannels(pHddCtx->hHal);
11300 if (HAL_STATUS_SUCCESS(status))
11301 {
11302 return VOS_STATUS_SUCCESS;
11303 }
11304 else
11305 {
11306 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11307 __func__, status);
11308 return VOS_STATUS_E_FAULT;
11309 }
11310}
11311
Mihir Shete04206452014-11-20 17:50:58 +053011312#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011313VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011314{
11315 eHalStatus status;
11316
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011317 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011318 if (HAL_STATUS_SUCCESS(status))
11319 {
11320 return VOS_STATUS_SUCCESS;
11321 }
11322 else
11323 {
11324 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11325 __func__, status);
11326 return VOS_STATUS_E_FAULT;
11327 }
11328}
Mihir Shete04206452014-11-20 17:50:58 +053011329#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011330/*
11331 * API to find if there is any STA or P2P-Client is connected
11332 */
11333VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11334{
11335 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11336}
Jeff Johnsone7245742012-09-05 17:12:55 -070011337
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011338
11339/*
11340 * API to find if the firmware will send logs using DXE channel
11341 */
11342v_U8_t hdd_is_fw_logging_enabled(void)
11343{
11344 hdd_context_t *pHddCtx;
11345
11346 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11347 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11348
Sachin Ahuja084313e2015-05-21 17:57:10 +053011349 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011350}
11351
Agarwal Ashish57e84372014-12-05 18:26:53 +053011352/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011353 * API to find if the firmware will send trace logs using DXE channel
11354 */
11355v_U8_t hdd_is_fw_ev_logging_enabled(void)
11356{
11357 hdd_context_t *pHddCtx;
11358
11359 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11360 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11361
11362 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11363}
11364/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011365 * API to find if there is any session connected
11366 */
11367VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11368{
11369 return sme_is_any_session_connected(pHddCtx->hHal);
11370}
11371
11372
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011373int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11374{
11375 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11376 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011377 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011378 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011379
11380 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011381 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011382 if (pScanInfo->mScanPending)
11383 {
c_hpothua3d45d52015-01-05 14:11:17 +053011384 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11385 eCSR_SCAN_ABORT_DEFAULT);
11386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11387 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011388
c_hpothua3d45d52015-01-05 14:11:17 +053011389 /* If there is active scan command lets wait for the completion else
11390 * there is no need to wait as scan command might be in the SME pending
11391 * command list.
11392 */
11393 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11394 {
c_hpothua3d45d52015-01-05 14:11:17 +053011395 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011396 &pScanInfo->abortscan_event_var,
11397 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011398 if (0 >= status)
11399 {
11400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011401 "%s: Timeout or Interrupt occurred while waiting for abort"
11402 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011403 return -ETIMEDOUT;
11404 }
11405 }
11406 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11407 {
11408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11409 FL("hdd_abort_mac_scan failed"));
11410 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011411 }
11412 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011413 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011414}
11415
c_hpothu225aa7c2014-10-22 17:45:13 +053011416VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11417{
11418 hdd_adapter_t *pAdapter;
11419 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11420 VOS_STATUS vosStatus;
11421
11422 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11423 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11424 {
11425 pAdapter = pAdapterNode->pAdapter;
11426 if (NULL != pAdapter)
11427 {
11428 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11429 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11430 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11431 {
11432 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11433 pAdapter->device_mode);
11434 if (VOS_STATUS_SUCCESS !=
11435 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11436 {
11437 hddLog(LOGE, FL("failed to abort ROC"));
11438 return VOS_STATUS_E_FAILURE;
11439 }
11440 }
11441 }
11442 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11443 pAdapterNode = pNext;
11444 }
11445 return VOS_STATUS_SUCCESS;
11446}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011447
Mihir Shete0be28772015-02-17 18:42:14 +053011448hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11449{
11450 hdd_adapter_t *pAdapter;
11451 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11452 hdd_cfg80211_state_t *cfgState;
11453 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11454 VOS_STATUS vosStatus;
11455
11456 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11457 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11458 {
11459 pAdapter = pAdapterNode->pAdapter;
11460 if (NULL != pAdapter)
11461 {
11462 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11463 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11464 if (pRemainChanCtx)
11465 break;
11466 }
11467 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11468 pAdapterNode = pNext;
11469 }
11470 return pRemainChanCtx;
11471}
11472
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011473/**
11474 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11475 *
11476 * @pHddCtx: HDD context within host driver
11477 * @dfsScanMode: dfsScanMode passed from ioctl
11478 *
11479 */
11480
11481VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11482 tANI_U8 dfsScanMode)
11483{
11484 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11485 hdd_adapter_t *pAdapter;
11486 VOS_STATUS vosStatus;
11487 hdd_station_ctx_t *pHddStaCtx;
11488 eHalStatus status = eHAL_STATUS_SUCCESS;
11489
11490 if(!pHddCtx)
11491 {
11492 hddLog(LOGE, FL("HDD context is Null"));
11493 return eHAL_STATUS_FAILURE;
11494 }
11495
11496 if (pHddCtx->scan_info.mScanPending)
11497 {
11498 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11499 pHddCtx->scan_info.sessionId);
11500 hdd_abort_mac_scan(pHddCtx,
11501 pHddCtx->scan_info.sessionId,
11502 eCSR_SCAN_ABORT_DEFAULT);
11503 }
11504
11505 if (!dfsScanMode)
11506 {
11507 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11508 while ((NULL != pAdapterNode) &&
11509 (VOS_STATUS_SUCCESS == vosStatus))
11510 {
11511 pAdapter = pAdapterNode->pAdapter;
11512
11513 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11514 {
11515 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11516
11517 if(!pHddStaCtx)
11518 {
11519 hddLog(LOGE, FL("HDD STA context is Null"));
11520 return eHAL_STATUS_FAILURE;
11521 }
11522
11523 /* if STA is already connected on DFS channel,
11524 disconnect immediately*/
11525 if (hdd_connIsConnected(pHddStaCtx) &&
11526 (NV_CHANNEL_DFS ==
11527 vos_nv_getChannelEnabledState(
11528 pHddStaCtx->conn_info.operationChannel)))
11529 {
11530 status = sme_RoamDisconnect(pHddCtx->hHal,
11531 pAdapter->sessionId,
11532 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11533 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11534 "sme_RoamDisconnect returned with status: %d"
11535 "for sessionid: %d"), pHddStaCtx->conn_info.
11536 operationChannel, status, pAdapter->sessionId);
11537 }
11538 }
11539
11540 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11541 &pNext);
11542 pAdapterNode = pNext;
11543 }
11544 }
11545
11546 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11547 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11548 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11549
11550 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11551 if (!HAL_STATUS_SUCCESS(status))
11552 {
11553 hddLog(LOGE,
11554 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11555 return status;
11556 }
11557
11558 return status;
11559}
11560
Nirav Shah7e3c8132015-06-22 23:51:42 +053011561static int hdd_log2_ceil(unsigned value)
11562{
11563 /* need to switch to unsigned math so that negative values
11564 * will right-shift towards 0 instead of -1
11565 */
11566 unsigned tmp = value;
11567 int log2 = -1;
11568
11569 if (value == 0)
11570 return 0;
11571
11572 while (tmp) {
11573 log2++;
11574 tmp >>= 1;
11575 }
11576 if (1U << log2 != value)
11577 log2++;
11578
11579 return log2;
11580}
11581
11582/**
11583 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11584 * @pAdapter: adapter handle
11585 *
11586 * Return: vos status
11587 */
11588VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11589{
11590 int hash_elem, log2, i;
11591
11592 spin_lock_bh( &pAdapter->sta_hash_lock);
11593 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11594 spin_unlock_bh( &pAdapter->sta_hash_lock);
11595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11596 "%s: hash already attached for session id %d",
11597 __func__, pAdapter->sessionId);
11598 return VOS_STATUS_SUCCESS;
11599 }
11600 spin_unlock_bh( &pAdapter->sta_hash_lock);
11601
11602 hash_elem = WLAN_MAX_STA_COUNT;
11603 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11604 log2 = hdd_log2_ceil(hash_elem);
11605 hash_elem = 1 << log2;
11606
11607 pAdapter->sta_id_hash.mask = hash_elem - 1;
11608 pAdapter->sta_id_hash.idx_bits = log2;
11609 pAdapter->sta_id_hash.bins =
11610 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11611 if (!pAdapter->sta_id_hash.bins) {
11612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11613 "%s: malloc failed for session %d",
11614 __func__, pAdapter->sessionId);
11615 return VOS_STATUS_E_NOMEM;
11616 }
11617
11618 for (i = 0; i < hash_elem; i++)
11619 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11620
11621 spin_lock_bh( &pAdapter->sta_hash_lock);
11622 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11623 spin_unlock_bh( &pAdapter->sta_hash_lock);
11624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11625 "%s: Station ID Hash attached for session id %d",
11626 __func__, pAdapter->sessionId);
11627
11628 return VOS_STATUS_SUCCESS;
11629}
11630
11631/**
11632 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11633 * @pAdapter: adapter handle
11634 *
11635 * Return: vos status
11636 */
11637VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11638{
11639 int hash_elem, i;
11640 v_SIZE_t size;
11641
11642 spin_lock_bh( &pAdapter->sta_hash_lock);
11643 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11644 spin_unlock_bh( &pAdapter->sta_hash_lock);
11645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11646 "%s: hash not initialized for session id %d",
11647 __func__, pAdapter->sessionId);
11648 return VOS_STATUS_SUCCESS;
11649 }
11650
11651 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11652 spin_unlock_bh( &pAdapter->sta_hash_lock);
11653
11654 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11655
11656 /* free all station info*/
11657 for (i = 0; i < hash_elem; i++) {
11658 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11659 if (size != 0) {
11660 VOS_STATUS status;
11661 hdd_staid_hash_node_t *sta_info_node = NULL;
11662 hdd_staid_hash_node_t *next_node = NULL;
11663 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11664 (hdd_list_node_t**) &sta_info_node );
11665
11666 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11667 {
11668 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11669 &sta_info_node->node);
11670 vos_mem_free(sta_info_node);
11671
11672 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11673 (hdd_list_node_t*)sta_info_node,
11674 (hdd_list_node_t**)&next_node);
11675 sta_info_node = next_node;
11676 }
11677 }
11678 }
11679
11680 vos_mem_free(pAdapter->sta_id_hash.bins);
11681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11682 "%s: Station ID Hash detached for session id %d",
11683 __func__, pAdapter->sessionId);
11684 return VOS_STATUS_SUCCESS;
11685}
11686
11687/**
11688 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11689 * @pAdapter: adapter handle
11690 * @mac_addr_in: input mac address
11691 *
11692 * Return: index derived from mac address
11693 */
11694int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11695 v_MACADDR_t *mac_addr_in)
11696{
11697 uint16 index;
11698 struct hdd_align_mac_addr_t * mac_addr =
11699 (struct hdd_align_mac_addr_t *)mac_addr_in;
11700
11701 index = mac_addr->bytes_ab ^
11702 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11703 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11704 index &= pAdapter->sta_id_hash.mask;
11705 return index;
11706}
11707
11708/**
11709 * hdd_sta_id_hash_add_entry() - add entry in hash
11710 * @pAdapter: adapter handle
11711 * @sta_id: station id
11712 * @mac_addr: mac address
11713 *
11714 * Return: vos status
11715 */
11716VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11717 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11718{
11719 uint16 index;
11720 hdd_staid_hash_node_t *sta_info_node = NULL;
11721
11722 spin_lock_bh( &pAdapter->sta_hash_lock);
11723 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11724 spin_unlock_bh( &pAdapter->sta_hash_lock);
11725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11726 "%s: hash is not initialized for session id %d",
11727 __func__, pAdapter->sessionId);
11728 return VOS_STATUS_E_FAILURE;
11729 }
11730
11731 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11732 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11733 if (!sta_info_node) {
11734 spin_unlock_bh( &pAdapter->sta_hash_lock);
11735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11736 "%s: malloc failed", __func__);
11737 return VOS_STATUS_E_NOMEM;
11738 }
11739
11740 sta_info_node->sta_id = sta_id;
11741 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11742
11743 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11744 (hdd_list_node_t*) sta_info_node );
11745 spin_unlock_bh( &pAdapter->sta_hash_lock);
11746 return VOS_STATUS_SUCCESS;
11747}
11748
11749/**
11750 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11751 * @pAdapter: adapter handle
11752 * @sta_id: station id
11753 * @mac_addr: mac address
11754 *
11755 * Return: vos status
11756 */
11757VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11758 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11759{
11760 uint16 index;
11761 VOS_STATUS status;
11762 hdd_staid_hash_node_t *sta_info_node = NULL;
11763 hdd_staid_hash_node_t *next_node = NULL;
11764
11765 spin_lock_bh( &pAdapter->sta_hash_lock);
11766 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11767 spin_unlock_bh( &pAdapter->sta_hash_lock);
11768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11769 "%s: hash is not initialized for session id %d",
11770 __func__, pAdapter->sessionId);
11771 return VOS_STATUS_E_FAILURE;
11772 }
11773
11774 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11775 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11776 (hdd_list_node_t**) &sta_info_node );
11777
11778 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11779 {
11780 if (sta_info_node->sta_id == sta_id) {
11781 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11782 &sta_info_node->node);
11783 vos_mem_free(sta_info_node);
11784 break;
11785 }
11786 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11787 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11788 sta_info_node = next_node;
11789 }
11790 spin_unlock_bh( &pAdapter->sta_hash_lock);
11791 return status;
11792}
11793
11794/**
11795 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11796 * @pAdapter: adapter handle
11797 * @mac_addr_in: mac address
11798 *
11799 * Return: station id
11800 */
11801int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11802 v_MACADDR_t *mac_addr_in)
11803{
11804 uint8 is_found = 0;
11805 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11806 uint16 index;
11807 VOS_STATUS status;
11808 hdd_staid_hash_node_t *sta_info_node = NULL;
11809 hdd_staid_hash_node_t *next_node = NULL;
11810
11811 spin_lock_bh( &pAdapter->sta_hash_lock);
11812 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11813 spin_unlock_bh( &pAdapter->sta_hash_lock);
11814 hddLog(VOS_TRACE_LEVEL_ERROR,
11815 FL("hash is not initialized for session id %d"),
11816 pAdapter->sessionId);
11817 return HDD_WLAN_INVALID_STA_ID;
11818 }
11819
11820 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11821 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11822 (hdd_list_node_t**) &sta_info_node );
11823
11824 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11825 {
11826 if (vos_mem_compare(&sta_info_node->mac_addr,
11827 mac_addr_in, sizeof(v_MACADDR_t))) {
11828 is_found = 1;
11829 sta_id = sta_info_node->sta_id;
11830 break;
11831 }
11832 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11833 (hdd_list_node_t*)sta_info_node,
11834 (hdd_list_node_t**)&next_node);
11835 sta_info_node = next_node;
11836 }
11837 spin_unlock_bh( &pAdapter->sta_hash_lock);
11838 return sta_id;
11839}
11840
Jeff Johnson295189b2012-06-20 16:38:30 -070011841//Register the module init/exit functions
11842module_init(hdd_module_init);
11843module_exit(hdd_module_exit);
11844
11845MODULE_LICENSE("Dual BSD/GPL");
11846MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11847MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11848
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011849module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11850 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011851
Jeff Johnson76052702013-04-16 13:55:05 -070011852module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011853 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011854
11855module_param(enable_dfs_chan_scan, int,
11856 S_IRUSR | S_IRGRP | S_IROTH);
11857
11858module_param(enable_11d, int,
11859 S_IRUSR | S_IRGRP | S_IROTH);
11860
11861module_param(country_code, charp,
11862 S_IRUSR | S_IRGRP | S_IROTH);