blob: 98ba4c4103249b0568fa199f21c048d6b40cb959 [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);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002915 if (copy_to_user(priv_data.buf, &extra, len + 1))
2916 {
2917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2918 "%s: failed to copy data to user buffer", __func__);
2919 ret = -EFAULT;
2920 goto exit;
2921 }
2922 }
2923 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2924 {
2925 tANI_U8 *value = command;
2926 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2927
2928 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2929 value = value + 26;
2930 /* Convert the value from ascii to integer */
2931 ret = kstrtou8(value, 10, &minTime);
2932 if (ret < 0)
2933 {
2934 /* If the input value is greater than max value of datatype, then also
2935 kstrtou8 fails */
2936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2937 "%s: kstrtou8 failed range [%d - %d]", __func__,
2938 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2939 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2940 ret = -EINVAL;
2941 goto exit;
2942 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002943 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2944 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2945 {
2946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2947 "scan min channel time value %d is out of range"
2948 " (Min: %d Max: %d)", minTime,
2949 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2950 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2951 ret = -EINVAL;
2952 goto exit;
2953 }
2954
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302955 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2956 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2957 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2959 "%s: Received Command to change channel min time = %d", __func__, minTime);
2960
2961 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2962 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2963 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002964 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2965 {
2966 tANI_U8 *value = command;
2967 tANI_U8 channel = 0;
2968 tANI_U8 dwellTime = 0;
2969 tANI_U8 bufLen = 0;
2970 tANI_U8 *buf = NULL;
2971 tSirMacAddr targetApBssid;
2972 eHalStatus status = eHAL_STATUS_SUCCESS;
2973 struct ieee80211_channel chan;
2974 tANI_U8 finalLen = 0;
2975 tANI_U8 *finalBuf = NULL;
2976 tANI_U8 temp = 0;
2977 u64 cookie;
2978 hdd_station_ctx_t *pHddStaCtx = NULL;
2979 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2980
2981 /* if not associated, no need to send action frame */
2982 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2983 {
2984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2985 ret = -EINVAL;
2986 goto exit;
2987 }
2988
2989 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2990 &dwellTime, &buf, &bufLen);
2991 if (eHAL_STATUS_SUCCESS != status)
2992 {
2993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2994 "%s: Failed to parse send action frame data", __func__);
2995 ret = -EINVAL;
2996 goto exit;
2997 }
2998
2999 /* if the target bssid is different from currently associated AP,
3000 then no need to send action frame */
3001 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3002 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3003 {
3004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3005 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003006 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003007 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003008 goto exit;
3009 }
3010
3011 /* if the channel number is different from operating channel then
3012 no need to send action frame */
3013 if (channel != pHddStaCtx->conn_info.operationChannel)
3014 {
3015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3016 "%s: channel(%d) is different from operating channel(%d)",
3017 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3018 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003019 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003020 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003021 goto exit;
3022 }
3023 chan.center_freq = sme_ChnToFreq(channel);
3024
3025 finalLen = bufLen + 24;
3026 finalBuf = vos_mem_malloc(finalLen);
3027 if (NULL == finalBuf)
3028 {
3029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3030 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003031 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003032 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003033 goto exit;
3034 }
3035 vos_mem_zero(finalBuf, finalLen);
3036
3037 /* Fill subtype */
3038 temp = SIR_MAC_MGMT_ACTION << 4;
3039 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3040
3041 /* Fill type */
3042 temp = SIR_MAC_MGMT_FRAME;
3043 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3044
3045 /* Fill destination address (bssid of the AP) */
3046 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3047
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003048 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003049 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3050
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003051 /* Fill BSSID (AP mac address) */
3052 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003053
3054 /* Fill received buffer from 24th address */
3055 vos_mem_copy(finalBuf + 24, buf, bufLen);
3056
Jeff Johnson11c33152013-04-16 17:52:40 -07003057 /* done with the parsed buffer */
3058 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003059 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003060
DARAM SUDHA39eede62014-02-12 11:16:40 +05303061 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3063 &(pAdapter->wdev),
3064#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003065 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003066#endif
3067 &chan, 0,
3068#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3069 NL80211_CHAN_HT20, 1,
3070#endif
3071 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003072 1, &cookie );
3073 vos_mem_free(finalBuf);
3074 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003075 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3076 {
3077 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3078 char extra[32];
3079 tANI_U8 len = 0;
3080
3081 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003082 len = scnprintf(extra, sizeof(extra), "%s %d",
3083 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303084 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3085 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3086 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003087 if (copy_to_user(priv_data.buf, &extra, len + 1))
3088 {
3089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3090 "%s: failed to copy data to user buffer", __func__);
3091 ret = -EFAULT;
3092 goto exit;
3093 }
3094 }
3095 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3096 {
3097 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003098 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003099
3100 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3101 value = value + 19;
3102 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003103 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003104 if (ret < 0)
3105 {
3106 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003107 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003109 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003110 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3111 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3112 ret = -EINVAL;
3113 goto exit;
3114 }
3115
3116 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3117 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3118 {
3119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3120 "lfr mode value %d is out of range"
3121 " (Min: %d Max: %d)", maxTime,
3122 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3123 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3124 ret = -EINVAL;
3125 goto exit;
3126 }
3127
3128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3129 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3130
3131 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3132 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3133 }
3134 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3135 {
3136 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3137 char extra[32];
3138 tANI_U8 len = 0;
3139
3140 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003141 len = scnprintf(extra, sizeof(extra), "%s %d",
3142 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003143 if (copy_to_user(priv_data.buf, &extra, len + 1))
3144 {
3145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3146 "%s: failed to copy data to user buffer", __func__);
3147 ret = -EFAULT;
3148 goto exit;
3149 }
3150 }
3151 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3152 {
3153 tANI_U8 *value = command;
3154 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3155
3156 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3157 value = value + 16;
3158 /* Convert the value from ascii to integer */
3159 ret = kstrtou16(value, 10, &val);
3160 if (ret < 0)
3161 {
3162 /* If the input value is greater than max value of datatype, then also
3163 kstrtou16 fails */
3164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3165 "%s: kstrtou16 failed range [%d - %d]", __func__,
3166 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3167 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3168 ret = -EINVAL;
3169 goto exit;
3170 }
3171
3172 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3173 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3174 {
3175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3176 "scan home time value %d is out of range"
3177 " (Min: %d Max: %d)", val,
3178 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3179 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3180 ret = -EINVAL;
3181 goto exit;
3182 }
3183
3184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3185 "%s: Received Command to change scan home time = %d", __func__, val);
3186
3187 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3188 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3189 }
3190 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3191 {
3192 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3193 char extra[32];
3194 tANI_U8 len = 0;
3195
3196 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003197 len = scnprintf(extra, sizeof(extra), "%s %d",
3198 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003199 if (copy_to_user(priv_data.buf, &extra, len + 1))
3200 {
3201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3202 "%s: failed to copy data to user buffer", __func__);
3203 ret = -EFAULT;
3204 goto exit;
3205 }
3206 }
3207 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3208 {
3209 tANI_U8 *value = command;
3210 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3211
3212 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3213 value = value + 17;
3214 /* Convert the value from ascii to integer */
3215 ret = kstrtou8(value, 10, &val);
3216 if (ret < 0)
3217 {
3218 /* If the input value is greater than max value of datatype, then also
3219 kstrtou8 fails */
3220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3221 "%s: kstrtou8 failed range [%d - %d]", __func__,
3222 CFG_ROAM_INTRA_BAND_MIN,
3223 CFG_ROAM_INTRA_BAND_MAX);
3224 ret = -EINVAL;
3225 goto exit;
3226 }
3227
3228 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3229 (val > CFG_ROAM_INTRA_BAND_MAX))
3230 {
3231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3232 "intra band mode value %d is out of range"
3233 " (Min: %d Max: %d)", val,
3234 CFG_ROAM_INTRA_BAND_MIN,
3235 CFG_ROAM_INTRA_BAND_MAX);
3236 ret = -EINVAL;
3237 goto exit;
3238 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3240 "%s: Received Command to change intra band = %d", __func__, val);
3241
3242 pHddCtx->cfg_ini->nRoamIntraBand = val;
3243 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3244 }
3245 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3246 {
3247 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3248 char extra[32];
3249 tANI_U8 len = 0;
3250
3251 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003252 len = scnprintf(extra, sizeof(extra), "%s %d",
3253 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003254 if (copy_to_user(priv_data.buf, &extra, len + 1))
3255 {
3256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3257 "%s: failed to copy data to user buffer", __func__);
3258 ret = -EFAULT;
3259 goto exit;
3260 }
3261 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003262 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3263 {
3264 tANI_U8 *value = command;
3265 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3266
3267 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3268 value = value + 15;
3269 /* Convert the value from ascii to integer */
3270 ret = kstrtou8(value, 10, &nProbes);
3271 if (ret < 0)
3272 {
3273 /* If the input value is greater than max value of datatype, then also
3274 kstrtou8 fails */
3275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3276 "%s: kstrtou8 failed range [%d - %d]", __func__,
3277 CFG_ROAM_SCAN_N_PROBES_MIN,
3278 CFG_ROAM_SCAN_N_PROBES_MAX);
3279 ret = -EINVAL;
3280 goto exit;
3281 }
3282
3283 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3284 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3285 {
3286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3287 "NProbes value %d is out of range"
3288 " (Min: %d Max: %d)", nProbes,
3289 CFG_ROAM_SCAN_N_PROBES_MIN,
3290 CFG_ROAM_SCAN_N_PROBES_MAX);
3291 ret = -EINVAL;
3292 goto exit;
3293 }
3294
3295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3296 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3297
3298 pHddCtx->cfg_ini->nProbes = nProbes;
3299 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3300 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303301 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003302 {
3303 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3304 char extra[32];
3305 tANI_U8 len = 0;
3306
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003307 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003308 if (copy_to_user(priv_data.buf, &extra, len + 1))
3309 {
3310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3311 "%s: failed to copy data to user buffer", __func__);
3312 ret = -EFAULT;
3313 goto exit;
3314 }
3315 }
3316 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3317 {
3318 tANI_U8 *value = command;
3319 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3320
3321 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3322 /* input value is in units of msec */
3323 value = value + 20;
3324 /* Convert the value from ascii to integer */
3325 ret = kstrtou16(value, 10, &homeAwayTime);
3326 if (ret < 0)
3327 {
3328 /* If the input value is greater than max value of datatype, then also
3329 kstrtou8 fails */
3330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3331 "%s: kstrtou8 failed range [%d - %d]", __func__,
3332 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3333 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3334 ret = -EINVAL;
3335 goto exit;
3336 }
3337
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003338 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3339 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3340 {
3341 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3342 "homeAwayTime value %d is out of range"
3343 " (Min: %d Max: %d)", homeAwayTime,
3344 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3345 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3346 ret = -EINVAL;
3347 goto exit;
3348 }
3349
3350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3351 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003352 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3353 {
3354 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3355 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3356 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003357 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303358 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003359 {
3360 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3361 char extra[32];
3362 tANI_U8 len = 0;
3363
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003364 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003365 if (copy_to_user(priv_data.buf, &extra, len + 1))
3366 {
3367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3368 "%s: failed to copy data to user buffer", __func__);
3369 ret = -EFAULT;
3370 goto exit;
3371 }
3372 }
3373 else if (strncmp(command, "REASSOC", 7) == 0)
3374 {
3375 tANI_U8 *value = command;
3376 tANI_U8 channel = 0;
3377 tSirMacAddr targetApBssid;
3378 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003379#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3380 tCsrHandoffRequest handoffInfo;
3381#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003382 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003383 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3384
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003385 /* if not associated, no need to proceed with reassoc */
3386 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3387 {
3388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3389 ret = -EINVAL;
3390 goto exit;
3391 }
3392
3393 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3394 if (eHAL_STATUS_SUCCESS != status)
3395 {
3396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3397 "%s: Failed to parse reassoc command data", __func__);
3398 ret = -EINVAL;
3399 goto exit;
3400 }
3401
3402 /* if the target bssid is same as currently associated AP,
3403 then no need to proceed with reassoc */
3404 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3405 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3406 {
3407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3408 ret = -EINVAL;
3409 goto exit;
3410 }
3411
3412 /* Check channel number is a valid channel number */
3413 if(VOS_STATUS_SUCCESS !=
3414 wlan_hdd_validate_operation_channel(pAdapter, channel))
3415 {
3416 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003417 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003418 return -EINVAL;
3419 }
3420
3421 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003422#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3423 handoffInfo.channel = channel;
3424 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3425 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3426#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003427 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003428 else if (strncmp(command, "SETWESMODE", 10) == 0)
3429 {
3430 tANI_U8 *value = command;
3431 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3432
3433 /* Move pointer to ahead of SETWESMODE<delimiter> */
3434 value = value + 11;
3435 /* Convert the value from ascii to integer */
3436 ret = kstrtou8(value, 10, &wesMode);
3437 if (ret < 0)
3438 {
3439 /* If the input value is greater than max value of datatype, then also
3440 kstrtou8 fails */
3441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3442 "%s: kstrtou8 failed range [%d - %d]", __func__,
3443 CFG_ENABLE_WES_MODE_NAME_MIN,
3444 CFG_ENABLE_WES_MODE_NAME_MAX);
3445 ret = -EINVAL;
3446 goto exit;
3447 }
3448
3449 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3450 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3451 {
3452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3453 "WES Mode value %d is out of range"
3454 " (Min: %d Max: %d)", wesMode,
3455 CFG_ENABLE_WES_MODE_NAME_MIN,
3456 CFG_ENABLE_WES_MODE_NAME_MAX);
3457 ret = -EINVAL;
3458 goto exit;
3459 }
3460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3461 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3462
3463 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3464 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3465 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303466 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003467 {
3468 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3469 char extra[32];
3470 tANI_U8 len = 0;
3471
Arif Hussain826d9412013-11-12 16:44:54 -08003472 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003473 if (copy_to_user(priv_data.buf, &extra, len + 1))
3474 {
3475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3476 "%s: failed to copy data to user buffer", __func__);
3477 ret = -EFAULT;
3478 goto exit;
3479 }
3480 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003481#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003482#ifdef FEATURE_WLAN_LFR
3483 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3484 {
3485 tANI_U8 *value = command;
3486 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3487
3488 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3489 value = value + 12;
3490 /* Convert the value from ascii to integer */
3491 ret = kstrtou8(value, 10, &lfrMode);
3492 if (ret < 0)
3493 {
3494 /* If the input value is greater than max value of datatype, then also
3495 kstrtou8 fails */
3496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3497 "%s: kstrtou8 failed range [%d - %d]", __func__,
3498 CFG_LFR_FEATURE_ENABLED_MIN,
3499 CFG_LFR_FEATURE_ENABLED_MAX);
3500 ret = -EINVAL;
3501 goto exit;
3502 }
3503
3504 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3505 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3506 {
3507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3508 "lfr mode value %d is out of range"
3509 " (Min: %d Max: %d)", lfrMode,
3510 CFG_LFR_FEATURE_ENABLED_MIN,
3511 CFG_LFR_FEATURE_ENABLED_MAX);
3512 ret = -EINVAL;
3513 goto exit;
3514 }
3515
3516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3517 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3518
3519 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3520 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3521 }
3522#endif
3523#ifdef WLAN_FEATURE_VOWIFI_11R
3524 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3525 {
3526 tANI_U8 *value = command;
3527 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3528
3529 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3530 value = value + 18;
3531 /* Convert the value from ascii to integer */
3532 ret = kstrtou8(value, 10, &ft);
3533 if (ret < 0)
3534 {
3535 /* If the input value is greater than max value of datatype, then also
3536 kstrtou8 fails */
3537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3538 "%s: kstrtou8 failed range [%d - %d]", __func__,
3539 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3540 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3541 ret = -EINVAL;
3542 goto exit;
3543 }
3544
3545 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3546 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3547 {
3548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3549 "ft mode value %d is out of range"
3550 " (Min: %d Max: %d)", ft,
3551 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3552 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3553 ret = -EINVAL;
3554 goto exit;
3555 }
3556
3557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3558 "%s: Received Command to change ft mode = %d", __func__, ft);
3559
3560 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3561 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3562 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303563 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3564 {
3565 tANI_U8 *value = command;
3566 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303567
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303568 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3569 value = value + 15;
3570 /* Convert the value from ascii to integer */
3571 ret = kstrtou8(value, 10, &dfsScanMode);
3572 if (ret < 0)
3573 {
3574 /* If the input value is greater than max value of
3575 datatype, then also kstrtou8 fails
3576 */
3577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3578 "%s: kstrtou8 failed range [%d - %d]", __func__,
3579 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3580 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3581 ret = -EINVAL;
3582 goto exit;
3583 }
3584
3585 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3586 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3587 {
3588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3589 "dfsScanMode value %d is out of range"
3590 " (Min: %d Max: %d)", dfsScanMode,
3591 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3592 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3593 ret = -EINVAL;
3594 goto exit;
3595 }
3596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3597 "%s: Received Command to Set DFS Scan Mode = %d",
3598 __func__, dfsScanMode);
3599
3600 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3601 }
3602 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3603 {
3604 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3605 char extra[32];
3606 tANI_U8 len = 0;
3607
3608 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3609 if (copy_to_user(priv_data.buf, &extra, len + 1))
3610 {
3611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3612 "%s: failed to copy data to user buffer", __func__);
3613 ret = -EFAULT;
3614 goto exit;
3615 }
3616 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303617 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3618 {
3619 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303620 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303621 tSirMacAddr targetApBssid;
3622 tANI_U8 trigger = 0;
3623 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303624 tHalHandle hHal;
3625 v_U32_t roamId = 0;
3626 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303627 hdd_station_ctx_t *pHddStaCtx = NULL;
3628 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303629 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303630
3631 /* if not associated, no need to proceed with reassoc */
3632 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3633 {
3634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3635 ret = -EINVAL;
3636 goto exit;
3637 }
3638
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303639 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303640 if (eHAL_STATUS_SUCCESS != status)
3641 {
3642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3643 "%s: Failed to parse reassoc command data", __func__);
3644 ret = -EINVAL;
3645 goto exit;
3646 }
3647
3648 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303649 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303650 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3651 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3652 {
3653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3654 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3655 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303656 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3657 &modProfileFields);
3658 sme_RoamReassoc(hHal, pAdapter->sessionId,
3659 NULL, modProfileFields, &roamId, 1);
3660 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303661 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303662
3663 /* Check channel number is a valid channel number */
3664 if(VOS_STATUS_SUCCESS !=
3665 wlan_hdd_validate_operation_channel(pAdapter, channel))
3666 {
3667 hddLog(VOS_TRACE_LEVEL_ERROR,
3668 "%s: Invalid Channel [%d]", __func__, channel);
3669 return -EINVAL;
3670 }
3671
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303672 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303673
3674 /* Proceed with scan/roam */
3675 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3676 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303677 (tSmeFastRoamTrigger)(trigger),
3678 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303679 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003680#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003681#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003682 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3683 {
3684 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003685 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003686
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003687 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003688 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003689 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003690 hdd_is_okc_mode_enabled(pHddCtx) &&
3691 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3692 {
3693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003694 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003695 " hence this operation is not permitted!", __func__);
3696 ret = -EPERM;
3697 goto exit;
3698 }
3699
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003700 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3701 value = value + 11;
3702 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003703 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003704 if (ret < 0)
3705 {
3706 /* If the input value is greater than max value of datatype, then also
3707 kstrtou8 fails */
3708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3709 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003710 CFG_ESE_FEATURE_ENABLED_MIN,
3711 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003712 ret = -EINVAL;
3713 goto exit;
3714 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003715 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3716 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003717 {
3718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003719 "Ese mode value %d is out of range"
3720 " (Min: %d Max: %d)", eseMode,
3721 CFG_ESE_FEATURE_ENABLED_MIN,
3722 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003723 ret = -EINVAL;
3724 goto exit;
3725 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003727 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003728
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003729 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3730 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003731 }
3732#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003733 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3734 {
3735 tANI_U8 *value = command;
3736 tANI_BOOLEAN roamScanControl = 0;
3737
3738 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3739 value = value + 19;
3740 /* Convert the value from ascii to integer */
3741 ret = kstrtou8(value, 10, &roamScanControl);
3742 if (ret < 0)
3743 {
3744 /* If the input value is greater than max value of datatype, then also
3745 kstrtou8 fails */
3746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3747 "%s: kstrtou8 failed ", __func__);
3748 ret = -EINVAL;
3749 goto exit;
3750 }
3751
3752 if (0 != roamScanControl)
3753 {
3754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3755 "roam scan control invalid value = %d",
3756 roamScanControl);
3757 ret = -EINVAL;
3758 goto exit;
3759 }
3760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3761 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3762
3763 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3764 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003765#ifdef FEATURE_WLAN_OKC
3766 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3767 {
3768 tANI_U8 *value = command;
3769 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3770
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003771 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003772 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003773 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003774 hdd_is_okc_mode_enabled(pHddCtx) &&
3775 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3776 {
3777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003778 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003779 " hence this operation is not permitted!", __func__);
3780 ret = -EPERM;
3781 goto exit;
3782 }
3783
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003784 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3785 value = value + 11;
3786 /* Convert the value from ascii to integer */
3787 ret = kstrtou8(value, 10, &okcMode);
3788 if (ret < 0)
3789 {
3790 /* If the input value is greater than max value of datatype, then also
3791 kstrtou8 fails */
3792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3793 "%s: kstrtou8 failed range [%d - %d]", __func__,
3794 CFG_OKC_FEATURE_ENABLED_MIN,
3795 CFG_OKC_FEATURE_ENABLED_MAX);
3796 ret = -EINVAL;
3797 goto exit;
3798 }
3799
3800 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3801 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3802 {
3803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3804 "Okc mode value %d is out of range"
3805 " (Min: %d Max: %d)", okcMode,
3806 CFG_OKC_FEATURE_ENABLED_MIN,
3807 CFG_OKC_FEATURE_ENABLED_MAX);
3808 ret = -EINVAL;
3809 goto exit;
3810 }
3811
3812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3813 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3814
3815 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3816 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003817#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303818 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003819 {
3820 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3821 char extra[32];
3822 tANI_U8 len = 0;
3823
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003824 len = scnprintf(extra, sizeof(extra), "%s %d",
3825 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003826 if (copy_to_user(priv_data.buf, &extra, len + 1))
3827 {
3828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3829 "%s: failed to copy data to user buffer", __func__);
3830 ret = -EFAULT;
3831 goto exit;
3832 }
3833 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303834#ifdef WLAN_FEATURE_PACKET_FILTERING
3835 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3836 {
3837 tANI_U8 filterType = 0;
3838 tANI_U8 *value = command;
3839
3840 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3841 value = value + 22;
3842
3843 /* Convert the value from ascii to integer */
3844 ret = kstrtou8(value, 10, &filterType);
3845 if (ret < 0)
3846 {
3847 /* If the input value is greater than max value of datatype,
3848 * then also kstrtou8 fails
3849 */
3850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3851 "%s: kstrtou8 failed range ", __func__);
3852 ret = -EINVAL;
3853 goto exit;
3854 }
3855
3856 if (filterType != 0 && filterType != 1)
3857 {
3858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3859 "%s: Accepted Values are 0 and 1 ", __func__);
3860 ret = -EINVAL;
3861 goto exit;
3862 }
3863 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3864 pAdapter->sessionId);
3865 }
3866#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303867 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3868 {
Kiet Lamad161252014-07-22 11:23:32 -07003869 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303870 int ret;
3871
Kiet Lamad161252014-07-22 11:23:32 -07003872 dhcpPhase = command + 11;
3873 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303874 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003876 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303877
3878 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003879
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303880 ret = wlan_hdd_scan_abort(pAdapter);
3881 if (ret < 0)
3882 {
3883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3884 FL("failed to abort existing scan %d"), ret);
3885 }
3886
Kiet Lamad161252014-07-22 11:23:32 -07003887 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3888 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303889 }
Kiet Lamad161252014-07-22 11:23:32 -07003890 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303891 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003893 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303894
3895 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003896
3897 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3898 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303899 }
3900 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003901 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3902 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3904 FL("making default scan to ACTIVE"));
3905 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003906 }
3907 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3908 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3910 FL("making default scan to PASSIVE"));
3911 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003912 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303913 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3914 {
3915 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3916 char extra[32];
3917 tANI_U8 len = 0;
3918
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303919 memset(extra, 0, sizeof(extra));
3920 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3921 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303922 {
3923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3924 "%s: failed to copy data to user buffer", __func__);
3925 ret = -EFAULT;
3926 goto exit;
3927 }
3928 ret = len;
3929 }
3930 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3931 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303932 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303933 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003934 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3935 {
3936 tANI_U8 filterType = 0;
3937 tANI_U8 *value;
3938 value = command + 9;
3939
3940 /* Convert the value from ascii to integer */
3941 ret = kstrtou8(value, 10, &filterType);
3942 if (ret < 0)
3943 {
3944 /* If the input value is greater than max value of datatype,
3945 * then also kstrtou8 fails
3946 */
3947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3948 "%s: kstrtou8 failed range ", __func__);
3949 ret = -EINVAL;
3950 goto exit;
3951 }
3952 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3953 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3954 {
3955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3956 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3957 " 2-Sink ", __func__);
3958 ret = -EINVAL;
3959 goto exit;
3960 }
3961 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3962 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303963 pScanInfo = &pHddCtx->scan_info;
3964 if (filterType && pScanInfo != NULL &&
3965 pHddCtx->scan_info.mScanPending)
3966 {
3967 /*Miracast Session started. Abort Scan */
3968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3969 "%s, Aborting Scan For Miracast",__func__);
3970 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3971 eCSR_SCAN_ABORT_DEFAULT);
3972 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003973 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303974 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003975 }
Leo Chang614d2072013-08-22 14:59:44 -07003976 else if (strncmp(command, "SETMCRATE", 9) == 0)
3977 {
Leo Chang614d2072013-08-22 14:59:44 -07003978 tANI_U8 *value = command;
3979 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003980 tSirRateUpdateInd *rateUpdate;
3981 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003982
3983 /* Only valid for SAP mode */
3984 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3985 {
3986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3987 "%s: SAP mode is not running", __func__);
3988 ret = -EFAULT;
3989 goto exit;
3990 }
3991
3992 /* Move pointer to ahead of SETMCRATE<delimiter> */
3993 /* input value is in units of hundred kbps */
3994 value = value + 10;
3995 /* Convert the value from ascii to integer, decimal base */
3996 ret = kstrtouint(value, 10, &targetRate);
3997
Leo Chang1f98cbd2013-10-17 15:03:52 -07003998 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3999 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004000 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004001 hddLog(VOS_TRACE_LEVEL_ERROR,
4002 "%s: SETMCRATE indication alloc fail", __func__);
4003 ret = -EFAULT;
4004 goto exit;
4005 }
4006 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4007
4008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4009 "MC Target rate %d", targetRate);
4010 /* Ignore unicast */
4011 rateUpdate->ucastDataRate = -1;
4012 rateUpdate->mcastDataRate24GHz = targetRate;
4013 rateUpdate->mcastDataRate5GHz = targetRate;
4014 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4015 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4016 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4017 if (eHAL_STATUS_SUCCESS != status)
4018 {
4019 hddLog(VOS_TRACE_LEVEL_ERROR,
4020 "%s: SET_MC_RATE failed", __func__);
4021 vos_mem_free(rateUpdate);
4022 ret = -EFAULT;
4023 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004024 }
4025 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304026#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004027 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304028 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004029 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304030 }
4031#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004032#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004033 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4034 {
4035 tANI_U8 *value = command;
4036 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4037 tANI_U8 numChannels = 0;
4038 eHalStatus status = eHAL_STATUS_SUCCESS;
4039
4040 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4041 if (eHAL_STATUS_SUCCESS != status)
4042 {
4043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4044 "%s: Failed to parse channel list information", __func__);
4045 ret = -EINVAL;
4046 goto exit;
4047 }
4048
4049 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4050 {
4051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4052 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4053 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4054 ret = -EINVAL;
4055 goto exit;
4056 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004057 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004058 ChannelList,
4059 numChannels);
4060 if (eHAL_STATUS_SUCCESS != status)
4061 {
4062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4063 "%s: Failed to update channel list information", __func__);
4064 ret = -EINVAL;
4065 goto exit;
4066 }
4067 }
4068 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4069 {
4070 tANI_U8 *value = command;
4071 char extra[128] = {0};
4072 int len = 0;
4073 tANI_U8 tid = 0;
4074 hdd_station_ctx_t *pHddStaCtx = NULL;
4075 tAniTrafStrmMetrics tsmMetrics;
4076 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4077
4078 /* if not associated, return error */
4079 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4080 {
4081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4082 ret = -EINVAL;
4083 goto exit;
4084 }
4085
4086 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4087 value = value + 12;
4088 /* Convert the value from ascii to integer */
4089 ret = kstrtou8(value, 10, &tid);
4090 if (ret < 0)
4091 {
4092 /* If the input value is greater than max value of datatype, then also
4093 kstrtou8 fails */
4094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4095 "%s: kstrtou8 failed range [%d - %d]", __func__,
4096 TID_MIN_VALUE,
4097 TID_MAX_VALUE);
4098 ret = -EINVAL;
4099 goto exit;
4100 }
4101
4102 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4103 {
4104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4105 "tid value %d is out of range"
4106 " (Min: %d Max: %d)", tid,
4107 TID_MIN_VALUE,
4108 TID_MAX_VALUE);
4109 ret = -EINVAL;
4110 goto exit;
4111 }
4112
4113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4114 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4115
4116 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4117 {
4118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4119 "%s: failed to get tsm stats", __func__);
4120 ret = -EFAULT;
4121 goto exit;
4122 }
4123
4124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4125 "UplinkPktQueueDly(%d)\n"
4126 "UplinkPktQueueDlyHist[0](%d)\n"
4127 "UplinkPktQueueDlyHist[1](%d)\n"
4128 "UplinkPktQueueDlyHist[2](%d)\n"
4129 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304130 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004131 "UplinkPktLoss(%d)\n"
4132 "UplinkPktCount(%d)\n"
4133 "RoamingCount(%d)\n"
4134 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4135 tsmMetrics.UplinkPktQueueDlyHist[0],
4136 tsmMetrics.UplinkPktQueueDlyHist[1],
4137 tsmMetrics.UplinkPktQueueDlyHist[2],
4138 tsmMetrics.UplinkPktQueueDlyHist[3],
4139 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4140 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4141
4142 /* Output TSM stats is of the format
4143 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4144 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004145 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004146 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4147 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4148 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4149 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4150 tsmMetrics.RoamingDly);
4151
4152 if (copy_to_user(priv_data.buf, &extra, len + 1))
4153 {
4154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4155 "%s: failed to copy data to user buffer", __func__);
4156 ret = -EFAULT;
4157 goto exit;
4158 }
4159 }
4160 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4161 {
4162 tANI_U8 *value = command;
4163 tANI_U8 *cckmIe = NULL;
4164 tANI_U8 cckmIeLen = 0;
4165 eHalStatus status = eHAL_STATUS_SUCCESS;
4166
4167 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4168 if (eHAL_STATUS_SUCCESS != status)
4169 {
4170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4171 "%s: Failed to parse cckm ie data", __func__);
4172 ret = -EINVAL;
4173 goto exit;
4174 }
4175
4176 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4177 {
4178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4179 "%s: CCKM Ie input length is more than max[%d]", __func__,
4180 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004181 vos_mem_free(cckmIe);
4182 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004183 ret = -EINVAL;
4184 goto exit;
4185 }
4186 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004187 vos_mem_free(cckmIe);
4188 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004189 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004190 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4191 {
4192 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004193 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004194 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004195
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004196 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004197 if (eHAL_STATUS_SUCCESS != status)
4198 {
4199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004200 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004201 ret = -EINVAL;
4202 goto exit;
4203 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004204 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4205 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4206 hdd_indicateEseBcnReportNoResults (pAdapter,
4207 eseBcnReq.bcnReq[0].measurementToken,
4208 0x02, //BIT(1) set for measurement done
4209 0); // no BSS
4210 goto exit;
4211 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004212
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004213 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4214 if (eHAL_STATUS_SUCCESS != status)
4215 {
4216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4217 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4218 ret = -EINVAL;
4219 goto exit;
4220 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004221 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004222#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304223 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4224 {
4225 eHalStatus status;
4226 char buf[32], len;
4227 long waitRet;
4228 bcnMissRateContext_t getBcnMissRateCtx;
4229
4230 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4231
4232 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4233 {
4234 hddLog(VOS_TRACE_LEVEL_WARN,
4235 FL("GETBCNMISSRATE: STA is not in connected state"));
4236 ret = -1;
4237 goto exit;
4238 }
4239
4240 init_completion(&(getBcnMissRateCtx.completion));
4241 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4242
4243 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4244 pAdapter->sessionId,
4245 (void *)getBcnMissRateCB,
4246 (void *)(&getBcnMissRateCtx));
4247 if( eHAL_STATUS_SUCCESS != status)
4248 {
4249 hddLog(VOS_TRACE_LEVEL_INFO,
4250 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4251 ret = -EINVAL;
4252 goto exit;
4253 }
4254
4255 waitRet = wait_for_completion_interruptible_timeout
4256 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4257 if(waitRet <= 0)
4258 {
4259 hddLog(VOS_TRACE_LEVEL_ERROR,
4260 FL("failed to wait on bcnMissRateComp %d"), ret);
4261
4262 //Make magic number to zero so that callback is not called.
4263 spin_lock(&hdd_context_lock);
4264 getBcnMissRateCtx.magic = 0x0;
4265 spin_unlock(&hdd_context_lock);
4266 ret = -EINVAL;
4267 goto exit;
4268 }
4269
4270 hddLog(VOS_TRACE_LEVEL_INFO,
4271 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4272
4273 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4274 if (copy_to_user(priv_data.buf, &buf, len + 1))
4275 {
4276 hddLog(VOS_TRACE_LEVEL_ERROR,
4277 "%s: failed to copy data to user buffer", __func__);
4278 ret = -EFAULT;
4279 goto exit;
4280 }
4281 ret = len;
4282 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304283#ifdef FEATURE_WLAN_TDLS
4284 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4285 tANI_U8 *value = command;
4286 int set_value;
4287 /* Move pointer to ahead of TDLSOFFCH*/
4288 value += 26;
4289 sscanf(value, "%d", &set_value);
4290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4291 "%s: Tdls offchannel offset:%d",
4292 __func__, set_value);
4293 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4294 if (ret < 0)
4295 {
4296 ret = -EINVAL;
4297 goto exit;
4298 }
4299
4300 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4301 tANI_U8 *value = command;
4302 int set_value;
4303 /* Move pointer to ahead of tdlsoffchnmode*/
4304 value += 18;
4305 sscanf(value, "%d", &set_value);
4306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4307 "%s: Tdls offchannel mode:%d",
4308 __func__, set_value);
4309 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4310 if (ret < 0)
4311 {
4312 ret = -EINVAL;
4313 goto exit;
4314 }
4315 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4316 tANI_U8 *value = command;
4317 int set_value;
4318 /* Move pointer to ahead of TDLSOFFCH*/
4319 value += 14;
4320 sscanf(value, "%d", &set_value);
4321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4322 "%s: Tdls offchannel num: %d",
4323 __func__, set_value);
4324 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4325 if (ret < 0)
4326 {
4327 ret = -EINVAL;
4328 goto exit;
4329 }
4330 }
4331#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304332 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4333 {
4334 eHalStatus status;
4335 char *buf = NULL;
4336 char len;
4337 long waitRet;
4338 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304339 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304340 tANI_U8 *ptr = command;
4341 int stats = *(ptr + 11) - '0';
4342
4343 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4344 if (!IS_FEATURE_FW_STATS_ENABLE)
4345 {
4346 hddLog(VOS_TRACE_LEVEL_INFO,
4347 FL("Get Firmware stats feature not supported"));
4348 ret = -EINVAL;
4349 goto exit;
4350 }
4351
4352 if (FW_STATS_MAX <= stats || 0 >= stats)
4353 {
4354 hddLog(VOS_TRACE_LEVEL_INFO,
4355 FL(" stats %d not supported"),stats);
4356 ret = -EINVAL;
4357 goto exit;
4358 }
4359
4360 init_completion(&(fwStatsCtx.completion));
4361 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4362 fwStatsCtx.pAdapter = pAdapter;
4363 fwStatsRsp->type = 0;
4364 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304365 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304366 if (eHAL_STATUS_SUCCESS != status)
4367 {
4368 hddLog(VOS_TRACE_LEVEL_ERROR,
4369 FL(" fail to post WDA cmd status = %d"), status);
4370 ret = -EINVAL;
4371 goto exit;
4372 }
4373 waitRet = wait_for_completion_timeout
4374 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4375 if (waitRet <= 0)
4376 {
4377 hddLog(VOS_TRACE_LEVEL_ERROR,
4378 FL("failed to wait on GwtFwstats"));
4379 //Make magic number to zero so that callback is not executed.
4380 spin_lock(&hdd_context_lock);
4381 fwStatsCtx.magic = 0x0;
4382 spin_unlock(&hdd_context_lock);
4383 ret = -EINVAL;
4384 goto exit;
4385 }
4386 if (fwStatsRsp->type)
4387 {
4388 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4389 if (!buf)
4390 {
4391 hddLog(VOS_TRACE_LEVEL_ERROR,
4392 FL(" failed to allocate memory"));
4393 ret = -ENOMEM;
4394 goto exit;
4395 }
4396 switch( fwStatsRsp->type )
4397 {
4398 case FW_UBSP_STATS:
4399 {
4400 len = snprintf(buf, FW_STATE_RSP_LEN,
4401 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304402 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4403 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304404 }
4405 break;
4406 default:
4407 {
4408 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4409 ret = -EFAULT;
4410 kfree(buf);
4411 goto exit;
4412 }
4413 }
4414 if (copy_to_user(priv_data.buf, buf, len + 1))
4415 {
4416 hddLog(VOS_TRACE_LEVEL_ERROR,
4417 FL(" failed to copy data to user buffer"));
4418 ret = -EFAULT;
4419 kfree(buf);
4420 goto exit;
4421 }
4422 ret = len;
4423 kfree(buf);
4424 }
4425 else
4426 {
4427 hddLog(VOS_TRACE_LEVEL_ERROR,
4428 FL("failed to fetch the stats"));
4429 ret = -EFAULT;
4430 goto exit;
4431 }
4432
4433 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304434 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4435 {
4436 /*
4437 * this command wld be called by user-space when it detects WLAN
4438 * ON after airplane mode is set. When APM is set, WLAN turns off.
4439 * But it can be turned back on. Otherwise; when APM is turned back
4440 * off, WLAN wld turn back on. So at that point the command is
4441 * expected to come down. 0 means disable, 1 means enable. The
4442 * constraint is removed when parameter 1 is set or different
4443 * country code is set
4444 */
4445 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4446 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004447 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304448 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4449 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4450 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304451 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4452 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004453 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004454 }
4455exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304456 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004457 if (command)
4458 {
4459 kfree(command);
4460 }
4461 return ret;
4462}
4463
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004464#ifdef CONFIG_COMPAT
4465static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4466{
4467 struct {
4468 compat_uptr_t buf;
4469 int used_len;
4470 int total_len;
4471 } compat_priv_data;
4472 hdd_priv_data_t priv_data;
4473 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004474
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004475 /*
4476 * Note that pAdapter and ifr have already been verified by caller,
4477 * and HDD context has also been validated
4478 */
4479 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4480 sizeof(compat_priv_data))) {
4481 ret = -EFAULT;
4482 goto exit;
4483 }
4484 priv_data.buf = compat_ptr(compat_priv_data.buf);
4485 priv_data.used_len = compat_priv_data.used_len;
4486 priv_data.total_len = compat_priv_data.total_len;
4487 ret = hdd_driver_command(pAdapter, &priv_data);
4488 exit:
4489 return ret;
4490}
4491#else /* CONFIG_COMPAT */
4492static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4493{
4494 /* will never be invoked */
4495 return 0;
4496}
4497#endif /* CONFIG_COMPAT */
4498
4499static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4500{
4501 hdd_priv_data_t priv_data;
4502 int ret = 0;
4503
4504 /*
4505 * Note that pAdapter and ifr have already been verified by caller,
4506 * and HDD context has also been validated
4507 */
4508 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4509 ret = -EFAULT;
4510 } else {
4511 ret = hdd_driver_command(pAdapter, &priv_data);
4512 }
4513 return ret;
4514}
4515
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304516int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004517{
4518 hdd_adapter_t *pAdapter;
4519 hdd_context_t *pHddCtx;
4520 int ret;
4521
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304522 ENTER();
4523
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004524 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4525 if (NULL == pAdapter) {
4526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4527 "%s: HDD adapter context is Null", __func__);
4528 ret = -ENODEV;
4529 goto exit;
4530 }
4531 if (dev != pAdapter->dev) {
4532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4533 "%s: HDD adapter/dev inconsistency", __func__);
4534 ret = -ENODEV;
4535 goto exit;
4536 }
4537
4538 if ((!ifr) || (!ifr->ifr_data)) {
4539 ret = -EINVAL;
4540 goto exit;
4541 }
4542
4543 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4544 ret = wlan_hdd_validate_context(pHddCtx);
4545 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004546 ret = -EBUSY;
4547 goto exit;
4548 }
4549
4550 switch (cmd) {
4551 case (SIOCDEVPRIVATE + 1):
4552 if (is_compat_task())
4553 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4554 else
4555 ret = hdd_driver_ioctl(pAdapter, ifr);
4556 break;
4557 default:
4558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4559 __func__, cmd);
4560 ret = -EINVAL;
4561 break;
4562 }
4563 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304564 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004565 return ret;
4566}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004567
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304568int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4569{
4570 int ret;
4571
4572 vos_ssr_protect(__func__);
4573 ret = __hdd_ioctl(dev, ifr, cmd);
4574 vos_ssr_unprotect(__func__);
4575
4576 return ret;
4577}
4578
Katya Nigame7b69a82015-04-28 15:24:06 +05304579int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4580{
4581 return 0;
4582}
4583
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004584#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004585/**---------------------------------------------------------------------------
4586
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004587 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004588
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004589 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004590 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4591 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4592 <space>Scan Mode N<space>Meas Duration N
4593 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4594 then take N.
4595 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4596 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4597 This function does not take care of removing duplicate channels from the list
4598
4599 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004600 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004601
4602 \return - 0 for success non-zero for failure
4603
4604 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004605static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4606 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004607{
4608 tANI_U8 *inPtr = pValue;
4609 int tempInt = 0;
4610 int j = 0, i = 0, v = 0;
4611 char buf[32];
4612
4613 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4614 /*no argument after the command*/
4615 if (NULL == inPtr)
4616 {
4617 return -EINVAL;
4618 }
4619 /*no space after the command*/
4620 else if (SPACE_ASCII_VALUE != *inPtr)
4621 {
4622 return -EINVAL;
4623 }
4624
4625 /*removing empty spaces*/
4626 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4627
4628 /*no argument followed by spaces*/
4629 if ('\0' == *inPtr) return -EINVAL;
4630
4631 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004632 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004633 if (1 != v) return -EINVAL;
4634
4635 v = kstrtos32(buf, 10, &tempInt);
4636 if ( v < 0) return -EINVAL;
4637
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004638 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004639
4640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004641 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004642
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004643 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004644 {
4645 for (i = 0; i < 4; i++)
4646 {
4647 /*inPtr pointing to the beginning of first space after number of ie fields*/
4648 inPtr = strpbrk( inPtr, " " );
4649 /*no ie data after the number of ie fields argument*/
4650 if (NULL == inPtr) return -EINVAL;
4651
4652 /*removing empty space*/
4653 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4654
4655 /*no ie data after the number of ie fields argument and spaces*/
4656 if ( '\0' == *inPtr ) return -EINVAL;
4657
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004658 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004659 if (1 != v) return -EINVAL;
4660
4661 v = kstrtos32(buf, 10, &tempInt);
4662 if (v < 0) return -EINVAL;
4663
4664 switch (i)
4665 {
4666 case 0: /* Measurement token */
4667 if (tempInt <= 0)
4668 {
4669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4670 "Invalid Measurement Token(%d)", tempInt);
4671 return -EINVAL;
4672 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004673 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004674 break;
4675
4676 case 1: /* Channel number */
4677 if ((tempInt <= 0) ||
4678 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4679 {
4680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4681 "Invalid Channel Number(%d)", tempInt);
4682 return -EINVAL;
4683 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004684 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004685 break;
4686
4687 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004688 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004689 {
4690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4691 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4692 return -EINVAL;
4693 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004694 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004695 break;
4696
4697 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004698 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4699 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004700 {
4701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4702 "Invalid Measurement Duration(%d)", tempInt);
4703 return -EINVAL;
4704 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004705 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004706 break;
4707 }
4708 }
4709 }
4710
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004711 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004712 {
4713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304714 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004715 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004716 pEseBcnReq->bcnReq[j].measurementToken,
4717 pEseBcnReq->bcnReq[j].channel,
4718 pEseBcnReq->bcnReq[j].scanMode,
4719 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004720 }
4721
4722 return VOS_STATUS_SUCCESS;
4723}
4724
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004725static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4726{
4727 struct statsContext *pStatsContext = NULL;
4728 hdd_adapter_t *pAdapter = NULL;
4729
4730 if (NULL == pContext)
4731 {
4732 hddLog(VOS_TRACE_LEVEL_ERROR,
4733 "%s: Bad param, pContext [%p]",
4734 __func__, pContext);
4735 return;
4736 }
4737
Jeff Johnson72a40512013-12-19 10:14:15 -08004738 /* there is a race condition that exists between this callback
4739 function and the caller since the caller could time out either
4740 before or while this code is executing. we use a spinlock to
4741 serialize these actions */
4742 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004743
4744 pStatsContext = pContext;
4745 pAdapter = pStatsContext->pAdapter;
4746 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4747 {
4748 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004749 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004750 hddLog(VOS_TRACE_LEVEL_WARN,
4751 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4752 __func__, pAdapter, pStatsContext->magic);
4753 return;
4754 }
4755
Jeff Johnson72a40512013-12-19 10:14:15 -08004756 /* context is valid so caller is still waiting */
4757
4758 /* paranoia: invalidate the magic */
4759 pStatsContext->magic = 0;
4760
4761 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004762 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4763 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4764 tsmMetrics.UplinkPktQueueDlyHist,
4765 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4766 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4767 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4768 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4769 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4770 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4771 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4772
Jeff Johnson72a40512013-12-19 10:14:15 -08004773 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004774 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004775
4776 /* serialization is complete */
4777 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004778}
4779
4780
4781
4782static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4783 tAniTrafStrmMetrics* pTsmMetrics)
4784{
4785 hdd_station_ctx_t *pHddStaCtx = NULL;
4786 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004787 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004788 long lrc;
4789 struct statsContext context;
4790 hdd_context_t *pHddCtx = NULL;
4791
4792 if (NULL == pAdapter)
4793 {
4794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4795 return VOS_STATUS_E_FAULT;
4796 }
4797
4798 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4799 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4800
4801 /* we are connected prepare our callback context */
4802 init_completion(&context.completion);
4803 context.pAdapter = pAdapter;
4804 context.magic = STATS_CONTEXT_MAGIC;
4805
4806 /* query tsm stats */
4807 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4808 pHddStaCtx->conn_info.staId[ 0 ],
4809 pHddStaCtx->conn_info.bssId,
4810 &context, pHddCtx->pvosContext, tid);
4811
4812 if (eHAL_STATUS_SUCCESS != hstatus)
4813 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004814 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4815 __func__);
4816 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004817 }
4818 else
4819 {
4820 /* request was sent -- wait for the response */
4821 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4822 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004823 if (lrc <= 0)
4824 {
4825 hddLog(VOS_TRACE_LEVEL_ERROR,
4826 "%s: SME %s while retrieving statistics",
4827 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004828 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004829 }
4830 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004831
Jeff Johnson72a40512013-12-19 10:14:15 -08004832 /* either we never sent a request, we sent a request and received a
4833 response or we sent a request and timed out. if we never sent a
4834 request or if we sent a request and got a response, we want to
4835 clear the magic out of paranoia. if we timed out there is a
4836 race condition such that the callback function could be
4837 executing at the same time we are. of primary concern is if the
4838 callback function had already verified the "magic" but had not
4839 yet set the completion variable when a timeout occurred. we
4840 serialize these activities by invalidating the magic while
4841 holding a shared spinlock which will cause us to block if the
4842 callback is currently executing */
4843 spin_lock(&hdd_context_lock);
4844 context.magic = 0;
4845 spin_unlock(&hdd_context_lock);
4846
4847 if (VOS_STATUS_SUCCESS == vstatus)
4848 {
4849 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4850 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4851 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4852 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4853 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4854 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4855 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4856 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4857 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4858 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4859 }
4860 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004861}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004862#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004863
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004864#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004865void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4866{
4867 eCsrBand band = -1;
4868 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4869 switch (band)
4870 {
4871 case eCSR_BAND_ALL:
4872 *pBand = WLAN_HDD_UI_BAND_AUTO;
4873 break;
4874
4875 case eCSR_BAND_24:
4876 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4877 break;
4878
4879 case eCSR_BAND_5G:
4880 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4881 break;
4882
4883 default:
4884 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4885 *pBand = -1;
4886 break;
4887 }
4888}
4889
4890/**---------------------------------------------------------------------------
4891
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004892 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4893
4894 This function parses the send action frame data passed in the format
4895 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4896
Srinivas Girigowda56076852013-08-20 14:00:50 -07004897 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004898 \param - pTargetApBssid Pointer to target Ap bssid
4899 \param - pChannel Pointer to the Target AP channel
4900 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4901 \param - pBuf Pointer to data
4902 \param - pBufLen Pointer to data length
4903
4904 \return - 0 for success non-zero for failure
4905
4906 --------------------------------------------------------------------------*/
4907VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4908 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4909{
4910 tANI_U8 *inPtr = pValue;
4911 tANI_U8 *dataEnd;
4912 int tempInt;
4913 int j = 0;
4914 int i = 0;
4915 int v = 0;
4916 tANI_U8 tempBuf[32];
4917 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004918 /* 12 hexa decimal digits, 5 ':' and '\0' */
4919 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004920
4921 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4922 /*no argument after the command*/
4923 if (NULL == inPtr)
4924 {
4925 return -EINVAL;
4926 }
4927
4928 /*no space after the command*/
4929 else if (SPACE_ASCII_VALUE != *inPtr)
4930 {
4931 return -EINVAL;
4932 }
4933
4934 /*removing empty spaces*/
4935 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4936
4937 /*no argument followed by spaces*/
4938 if ('\0' == *inPtr)
4939 {
4940 return -EINVAL;
4941 }
4942
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004943 v = sscanf(inPtr, "%17s", macAddress);
4944 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004945 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4947 "Invalid MAC address or All hex inputs are not read (%d)", v);
4948 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004949 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004950
4951 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4952 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4953 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4954 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4955 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4956 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004957
4958 /* point to the next argument */
4959 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4960 /*no argument after the command*/
4961 if (NULL == inPtr) return -EINVAL;
4962
4963 /*removing empty spaces*/
4964 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4965
4966 /*no argument followed by spaces*/
4967 if ('\0' == *inPtr)
4968 {
4969 return -EINVAL;
4970 }
4971
4972 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004973 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004974 if (1 != v) return -EINVAL;
4975
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004976 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304977 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304978 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004979
4980 *pChannel = tempInt;
4981
4982 /* point to the next argument */
4983 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4984 /*no argument after the command*/
4985 if (NULL == inPtr) return -EINVAL;
4986 /*removing empty spaces*/
4987 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4988
4989 /*no argument followed by spaces*/
4990 if ('\0' == *inPtr)
4991 {
4992 return -EINVAL;
4993 }
4994
4995 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004996 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004997 if (1 != v) return -EINVAL;
4998
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004999 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005000 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005001
5002 *pDwellTime = tempInt;
5003
5004 /* point to the next argument */
5005 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5006 /*no argument after the command*/
5007 if (NULL == inPtr) return -EINVAL;
5008 /*removing empty spaces*/
5009 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5010
5011 /*no argument followed by spaces*/
5012 if ('\0' == *inPtr)
5013 {
5014 return -EINVAL;
5015 }
5016
5017 /* find the length of data */
5018 dataEnd = inPtr;
5019 while(('\0' != *dataEnd) )
5020 {
5021 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005022 }
Kiet Lambe150c22013-11-21 16:30:32 +05305023 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005024 if ( *pBufLen <= 0) return -EINVAL;
5025
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005026 /* Allocate the number of bytes based on the number of input characters
5027 whether it is even or odd.
5028 if the number of input characters are even, then we need N/2 byte.
5029 if the number of input characters are odd, then we need do (N+1)/2 to
5030 compensate rounding off.
5031 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5032 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5033 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005034 if (NULL == *pBuf)
5035 {
5036 hddLog(VOS_TRACE_LEVEL_FATAL,
5037 "%s: vos_mem_alloc failed ", __func__);
5038 return -EINVAL;
5039 }
5040
5041 /* the buffer received from the upper layer is character buffer,
5042 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5043 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5044 and f0 in 3rd location */
5045 for (i = 0, j = 0; j < *pBufLen; j += 2)
5046 {
Kiet Lambe150c22013-11-21 16:30:32 +05305047 if( j+1 == *pBufLen)
5048 {
5049 tempByte = hdd_parse_hex(inPtr[j]);
5050 }
5051 else
5052 {
5053 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5054 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005055 (*pBuf)[i++] = tempByte;
5056 }
5057 *pBufLen = i;
5058 return VOS_STATUS_SUCCESS;
5059}
5060
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005061/**---------------------------------------------------------------------------
5062
Srinivas Girigowdade697412013-02-14 16:31:48 -08005063 \brief hdd_parse_channellist() - HDD Parse channel list
5064
5065 This function parses the channel list passed in the format
5066 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005067 if the Number of channels (N) does not match with the actual number of channels passed
5068 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5069 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5070 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5071 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005072
5073 \param - pValue Pointer to input channel list
5074 \param - ChannelList Pointer to local output array to record channel list
5075 \param - pNumChannels Pointer to number of roam scan channels
5076
5077 \return - 0 for success non-zero for failure
5078
5079 --------------------------------------------------------------------------*/
5080VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5081{
5082 tANI_U8 *inPtr = pValue;
5083 int tempInt;
5084 int j = 0;
5085 int v = 0;
5086 char buf[32];
5087
5088 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5089 /*no argument after the command*/
5090 if (NULL == inPtr)
5091 {
5092 return -EINVAL;
5093 }
5094
5095 /*no space after the command*/
5096 else if (SPACE_ASCII_VALUE != *inPtr)
5097 {
5098 return -EINVAL;
5099 }
5100
5101 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005102 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005103
5104 /*no argument followed by spaces*/
5105 if ('\0' == *inPtr)
5106 {
5107 return -EINVAL;
5108 }
5109
5110 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005111 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005112 if (1 != v) return -EINVAL;
5113
Srinivas Girigowdade697412013-02-14 16:31:48 -08005114 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005115 if ((v < 0) ||
5116 (tempInt <= 0) ||
5117 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5118 {
5119 return -EINVAL;
5120 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005121
5122 *pNumChannels = tempInt;
5123
5124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5125 "Number of channels are: %d", *pNumChannels);
5126
5127 for (j = 0; j < (*pNumChannels); j++)
5128 {
5129 /*inPtr pointing to the beginning of first space after number of channels*/
5130 inPtr = strpbrk( inPtr, " " );
5131 /*no channel list after the number of channels argument*/
5132 if (NULL == inPtr)
5133 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005134 if (0 != j)
5135 {
5136 *pNumChannels = j;
5137 return VOS_STATUS_SUCCESS;
5138 }
5139 else
5140 {
5141 return -EINVAL;
5142 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005143 }
5144
5145 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005146 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005147
5148 /*no channel list after the number of channels argument and spaces*/
5149 if ( '\0' == *inPtr )
5150 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005151 if (0 != j)
5152 {
5153 *pNumChannels = j;
5154 return VOS_STATUS_SUCCESS;
5155 }
5156 else
5157 {
5158 return -EINVAL;
5159 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005160 }
5161
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005162 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005163 if (1 != v) return -EINVAL;
5164
Srinivas Girigowdade697412013-02-14 16:31:48 -08005165 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005166 if ((v < 0) ||
5167 (tempInt <= 0) ||
5168 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5169 {
5170 return -EINVAL;
5171 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005172 pChannelList[j] = tempInt;
5173
5174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5175 "Channel %d added to preferred channel list",
5176 pChannelList[j] );
5177 }
5178
Srinivas Girigowdade697412013-02-14 16:31:48 -08005179 return VOS_STATUS_SUCCESS;
5180}
5181
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005182
5183/**---------------------------------------------------------------------------
5184
5185 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5186
5187 This function parses the reasoc command data passed in the format
5188 REASSOC<space><bssid><space><channel>
5189
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005190 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005191 \param - pTargetApBssid Pointer to target Ap bssid
5192 \param - pChannel Pointer to the Target AP channel
5193
5194 \return - 0 for success non-zero for failure
5195
5196 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005197VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5198 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005199{
5200 tANI_U8 *inPtr = pValue;
5201 int tempInt;
5202 int v = 0;
5203 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005204 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005205 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005206
5207 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5208 /*no argument after the command*/
5209 if (NULL == inPtr)
5210 {
5211 return -EINVAL;
5212 }
5213
5214 /*no space after the command*/
5215 else if (SPACE_ASCII_VALUE != *inPtr)
5216 {
5217 return -EINVAL;
5218 }
5219
5220 /*removing empty spaces*/
5221 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5222
5223 /*no argument followed by spaces*/
5224 if ('\0' == *inPtr)
5225 {
5226 return -EINVAL;
5227 }
5228
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005229 v = sscanf(inPtr, "%17s", macAddress);
5230 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005231 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5233 "Invalid MAC address or All hex inputs are not read (%d)", v);
5234 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005235 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005236
5237 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5238 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5239 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5240 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5241 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5242 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005243
5244 /* point to the next argument */
5245 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5246 /*no argument after the command*/
5247 if (NULL == inPtr) return -EINVAL;
5248
5249 /*removing empty spaces*/
5250 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5251
5252 /*no argument followed by spaces*/
5253 if ('\0' == *inPtr)
5254 {
5255 return -EINVAL;
5256 }
5257
5258 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005259 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005260 if (1 != v) return -EINVAL;
5261
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005262 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005263 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305264 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005265 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5266 {
5267 return -EINVAL;
5268 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005269
5270 *pChannel = tempInt;
5271 return VOS_STATUS_SUCCESS;
5272}
5273
5274#endif
5275
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005276#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005277/**---------------------------------------------------------------------------
5278
5279 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5280
5281 This function parses the SETCCKM IE command
5282 SETCCKMIE<space><ie data>
5283
5284 \param - pValue Pointer to input data
5285 \param - pCckmIe Pointer to output cckm Ie
5286 \param - pCckmIeLen Pointer to output cckm ie length
5287
5288 \return - 0 for success non-zero for failure
5289
5290 --------------------------------------------------------------------------*/
5291VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5292 tANI_U8 *pCckmIeLen)
5293{
5294 tANI_U8 *inPtr = pValue;
5295 tANI_U8 *dataEnd;
5296 int j = 0;
5297 int i = 0;
5298 tANI_U8 tempByte = 0;
5299
5300 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5301 /*no argument after the command*/
5302 if (NULL == inPtr)
5303 {
5304 return -EINVAL;
5305 }
5306
5307 /*no space after the command*/
5308 else if (SPACE_ASCII_VALUE != *inPtr)
5309 {
5310 return -EINVAL;
5311 }
5312
5313 /*removing empty spaces*/
5314 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5315
5316 /*no argument followed by spaces*/
5317 if ('\0' == *inPtr)
5318 {
5319 return -EINVAL;
5320 }
5321
5322 /* find the length of data */
5323 dataEnd = inPtr;
5324 while(('\0' != *dataEnd) )
5325 {
5326 dataEnd++;
5327 ++(*pCckmIeLen);
5328 }
5329 if ( *pCckmIeLen <= 0) return -EINVAL;
5330
5331 /* Allocate the number of bytes based on the number of input characters
5332 whether it is even or odd.
5333 if the number of input characters are even, then we need N/2 byte.
5334 if the number of input characters are odd, then we need do (N+1)/2 to
5335 compensate rounding off.
5336 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5337 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5338 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5339 if (NULL == *pCckmIe)
5340 {
5341 hddLog(VOS_TRACE_LEVEL_FATAL,
5342 "%s: vos_mem_alloc failed ", __func__);
5343 return -EINVAL;
5344 }
5345 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5346 /* the buffer received from the upper layer is character buffer,
5347 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5348 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5349 and f0 in 3rd location */
5350 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5351 {
5352 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5353 (*pCckmIe)[i++] = tempByte;
5354 }
5355 *pCckmIeLen = i;
5356
5357 return VOS_STATUS_SUCCESS;
5358}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005359#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005360
Jeff Johnson295189b2012-06-20 16:38:30 -07005361/**---------------------------------------------------------------------------
5362
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005363 \brief hdd_is_valid_mac_address() - Validate MAC address
5364
5365 This function validates whether the given MAC address is valid or not
5366 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5367 where X is the hexa decimal digit character and separated by ':'
5368 This algorithm works even if MAC address is not separated by ':'
5369
5370 This code checks given input string mac contains exactly 12 hexadecimal digits.
5371 and a separator colon : appears in the input string only after
5372 an even number of hex digits.
5373
5374 \param - pMacAddr pointer to the input MAC address
5375 \return - 1 for valid and 0 for invalid
5376
5377 --------------------------------------------------------------------------*/
5378
5379v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5380{
5381 int xdigit = 0;
5382 int separator = 0;
5383 while (*pMacAddr)
5384 {
5385 if (isxdigit(*pMacAddr))
5386 {
5387 xdigit++;
5388 }
5389 else if (':' == *pMacAddr)
5390 {
5391 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5392 break;
5393
5394 ++separator;
5395 }
5396 else
5397 {
5398 separator = -1;
5399 /* Invalid MAC found */
5400 return 0;
5401 }
5402 ++pMacAddr;
5403 }
5404 return (xdigit == 12 && (separator == 5 || separator == 0));
5405}
5406
5407/**---------------------------------------------------------------------------
5408
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305409 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005410
5411 \param - dev Pointer to net_device structure
5412
5413 \return - 0 for success non-zero for failure
5414
5415 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305416int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005417{
5418 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5419 hdd_context_t *pHddCtx;
5420 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5421 VOS_STATUS status;
5422 v_BOOL_t in_standby = TRUE;
5423
5424 if (NULL == pAdapter)
5425 {
5426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305427 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 return -ENODEV;
5429 }
5430
5431 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305432 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5433 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 if (NULL == pHddCtx)
5435 {
5436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005437 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 return -ENODEV;
5439 }
5440
5441 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5442 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5443 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005444 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5445 {
5446 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305447 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005448 in_standby = FALSE;
5449 break;
5450 }
5451 else
5452 {
5453 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5454 pAdapterNode = pNext;
5455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005456 }
5457
5458 if (TRUE == in_standby)
5459 {
5460 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5461 {
5462 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5463 "wlan out of power save", __func__);
5464 return -EINVAL;
5465 }
5466 }
5467
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005468 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005469 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5470 {
5471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005472 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305474 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005475 netif_tx_start_all_queues(dev);
5476 }
5477
5478 return 0;
5479}
5480
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305481/**---------------------------------------------------------------------------
5482
5483 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5484
5485 This is called in response to ifconfig up
5486
5487 \param - dev Pointer to net_device structure
5488
5489 \return - 0 for success non-zero for failure
5490
5491 --------------------------------------------------------------------------*/
5492int hdd_open(struct net_device *dev)
5493{
5494 int ret;
5495
5496 vos_ssr_protect(__func__);
5497 ret = __hdd_open(dev);
5498 vos_ssr_unprotect(__func__);
5499
5500 return ret;
5501}
5502
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305503int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005504{
5505 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5506
5507 if(pAdapter == NULL) {
5508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005509 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005510 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 }
5512
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 return 0;
5514}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305515
5516int hdd_mon_open (struct net_device *dev)
5517{
5518 int ret;
5519
5520 vos_ssr_protect(__func__);
5521 ret = __hdd_mon_open(dev);
5522 vos_ssr_unprotect(__func__);
5523
5524 return ret;
5525}
5526
Katya Nigame7b69a82015-04-28 15:24:06 +05305527int hdd_mon_stop(struct net_device *dev)
5528{
5529 return 0;
5530}
5531
Jeff Johnson295189b2012-06-20 16:38:30 -07005532/**---------------------------------------------------------------------------
5533
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305534 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005535
5536 \param - dev Pointer to net_device structure
5537
5538 \return - 0 for success non-zero for failure
5539
5540 --------------------------------------------------------------------------*/
5541
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305542int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005543{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305544 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005545 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5546 hdd_context_t *pHddCtx;
5547 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5548 VOS_STATUS status;
5549 v_BOOL_t enter_standby = TRUE;
5550
5551 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005552 if (NULL == pAdapter)
5553 {
5554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305555 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 return -ENODEV;
5557 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305558 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305559 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305560
5561 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5562 ret = wlan_hdd_validate_context(pHddCtx);
5563 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005564 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305565 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 }
5567
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305568 /* Nothing to be done if the interface is not opened */
5569 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5570 {
5571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5572 "%s: NETDEV Interface is not OPENED", __func__);
5573 return -ENODEV;
5574 }
5575
5576 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005577 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005578 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305579
5580 /* Disable TX on the interface, after this hard_start_xmit() will not
5581 * be called on that interface
5582 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305583 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305585
5586 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005587 netif_carrier_off(pAdapter->dev);
5588
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305589 /* The interface is marked as down for outside world (aka kernel)
5590 * But the driver is pretty much alive inside. The driver needs to
5591 * tear down the existing connection on the netdev (session)
5592 * cleanup the data pipes and wait until the control plane is stabilized
5593 * for this interface. The call also needs to wait until the above
5594 * mentioned actions are completed before returning to the caller.
5595 * Notice that the hdd_stop_adapter is requested not to close the session
5596 * That is intentional to be able to scan if it is a STA/P2P interface
5597 */
5598 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305599#ifdef FEATURE_WLAN_TDLS
5600 mutex_lock(&pHddCtx->tdls_lock);
5601#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305602 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305603 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305604#ifdef FEATURE_WLAN_TDLS
5605 mutex_unlock(&pHddCtx->tdls_lock);
5606#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 /* SoftAP ifaces should never go in power save mode
5608 making sure same here. */
5609 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5610 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005612 )
5613 {
5614 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5616 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 EXIT();
5618 return 0;
5619 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305620 /* Find if any iface is up. If any iface is up then can't put device to
5621 * sleep/power save mode
5622 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5624 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5625 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005626 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5627 {
5628 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305629 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005630 enter_standby = FALSE;
5631 break;
5632 }
5633 else
5634 {
5635 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5636 pAdapterNode = pNext;
5637 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 }
5639
5640 if (TRUE == enter_standby)
5641 {
5642 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5643 "entering standby", __func__);
5644 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5645 {
5646 /*log and return success*/
5647 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5648 "wlan in power save", __func__);
5649 }
5650 }
5651
5652 EXIT();
5653 return 0;
5654}
5655
5656/**---------------------------------------------------------------------------
5657
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305658 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005659
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305660 This is called in response to ifconfig down
5661
5662 \param - dev Pointer to net_device structure
5663
5664 \return - 0 for success non-zero for failure
5665-----------------------------------------------------------------------------*/
5666int hdd_stop (struct net_device *dev)
5667{
5668 int ret;
5669
5670 vos_ssr_protect(__func__);
5671 ret = __hdd_stop(dev);
5672 vos_ssr_unprotect(__func__);
5673
5674 return ret;
5675}
5676
5677/**---------------------------------------------------------------------------
5678
5679 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005680
5681 \param - dev Pointer to net_device structure
5682
5683 \return - void
5684
5685 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305686static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005687{
5688 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305689 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005690 ENTER();
5691
5692 do
5693 {
5694 if (NULL == pAdapter)
5695 {
5696 hddLog(VOS_TRACE_LEVEL_FATAL,
5697 "%s: NULL pAdapter", __func__);
5698 break;
5699 }
5700
5701 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5702 {
5703 hddLog(VOS_TRACE_LEVEL_FATAL,
5704 "%s: Invalid magic", __func__);
5705 break;
5706 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305707 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5708 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005709 {
5710 hddLog(VOS_TRACE_LEVEL_FATAL,
5711 "%s: NULL pHddCtx", __func__);
5712 break;
5713 }
5714
5715 if (dev != pAdapter->dev)
5716 {
5717 hddLog(VOS_TRACE_LEVEL_FATAL,
5718 "%s: Invalid device reference", __func__);
5719 /* we haven't validated all cases so let this go for now */
5720 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305721#ifdef FEATURE_WLAN_TDLS
5722 mutex_lock(&pHddCtx->tdls_lock);
5723#endif
c_hpothu002231a2015-02-05 14:58:51 +05305724 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305725#ifdef FEATURE_WLAN_TDLS
5726 mutex_unlock(&pHddCtx->tdls_lock);
5727#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005728
5729 /* after uninit our adapter structure will no longer be valid */
5730 pAdapter->dev = NULL;
5731 pAdapter->magic = 0;
5732 } while (0);
5733
5734 EXIT();
5735}
5736
5737/**---------------------------------------------------------------------------
5738
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305739 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5740
5741 This is called during the netdev unregister to uninitialize all data
5742associated with the device
5743
5744 \param - dev Pointer to net_device structure
5745
5746 \return - void
5747
5748 --------------------------------------------------------------------------*/
5749static void hdd_uninit (struct net_device *dev)
5750{
5751 vos_ssr_protect(__func__);
5752 __hdd_uninit(dev);
5753 vos_ssr_unprotect(__func__);
5754}
5755
5756/**---------------------------------------------------------------------------
5757
Jeff Johnson295189b2012-06-20 16:38:30 -07005758 \brief hdd_release_firmware() -
5759
5760 This function calls the release firmware API to free the firmware buffer.
5761
5762 \param - pFileName Pointer to the File Name.
5763 pCtx - Pointer to the adapter .
5764
5765
5766 \return - 0 for success, non zero for failure
5767
5768 --------------------------------------------------------------------------*/
5769
5770VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5771{
5772 VOS_STATUS status = VOS_STATUS_SUCCESS;
5773 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5774 ENTER();
5775
5776
5777 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5778
5779 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5780
5781 if(pHddCtx->fw) {
5782 release_firmware(pHddCtx->fw);
5783 pHddCtx->fw = NULL;
5784 }
5785 else
5786 status = VOS_STATUS_E_FAILURE;
5787 }
5788 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5789 if(pHddCtx->nv) {
5790 release_firmware(pHddCtx->nv);
5791 pHddCtx->nv = NULL;
5792 }
5793 else
5794 status = VOS_STATUS_E_FAILURE;
5795
5796 }
5797
5798 EXIT();
5799 return status;
5800}
5801
5802/**---------------------------------------------------------------------------
5803
5804 \brief hdd_request_firmware() -
5805
5806 This function reads the firmware file using the request firmware
5807 API and returns the the firmware data and the firmware file size.
5808
5809 \param - pfileName - Pointer to the file name.
5810 - pCtx - Pointer to the adapter .
5811 - ppfw_data - Pointer to the pointer of the firmware data.
5812 - pSize - Pointer to the file size.
5813
5814 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5815
5816 --------------------------------------------------------------------------*/
5817
5818
5819VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5820{
5821 int status;
5822 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5823 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5824 ENTER();
5825
5826 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5827
5828 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5829
5830 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5831 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5832 __func__, pfileName);
5833 retval = VOS_STATUS_E_FAILURE;
5834 }
5835
5836 else {
5837 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5838 *pSize = pHddCtx->fw->size;
5839 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5840 __func__, *pSize);
5841 }
5842 }
5843 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5844
5845 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5846
5847 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5848 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5849 __func__, pfileName);
5850 retval = VOS_STATUS_E_FAILURE;
5851 }
5852
5853 else {
5854 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5855 *pSize = pHddCtx->nv->size;
5856 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5857 __func__, *pSize);
5858 }
5859 }
5860
5861 EXIT();
5862 return retval;
5863}
5864/**---------------------------------------------------------------------------
5865 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5866
5867 This is the function invoked by SME to inform the result of a full power
5868 request issued by HDD
5869
5870 \param - callbackcontext - Pointer to cookie
5871 status - result of request
5872
5873 \return - None
5874
5875--------------------------------------------------------------------------*/
5876void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5877{
5878 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5879
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005880 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 if(&pHddCtx->full_pwr_comp_var)
5882 {
5883 complete(&pHddCtx->full_pwr_comp_var);
5884 }
5885}
5886
5887/**---------------------------------------------------------------------------
5888
5889 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5890
5891 This is the function invoked by SME to inform the result of BMPS
5892 request issued by HDD
5893
5894 \param - callbackcontext - Pointer to cookie
5895 status - result of request
5896
5897 \return - None
5898
5899--------------------------------------------------------------------------*/
5900void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5901{
5902
5903 struct completion *completion_var = (struct completion*) callbackContext;
5904
Arif Hussain6d2a3322013-11-17 19:50:10 -08005905 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005906 if(completion_var != NULL)
5907 {
5908 complete(completion_var);
5909 }
5910}
5911
5912/**---------------------------------------------------------------------------
5913
5914 \brief hdd_get_cfg_file_size() -
5915
5916 This function reads the configuration file using the request firmware
5917 API and returns the configuration file size.
5918
5919 \param - pCtx - Pointer to the adapter .
5920 - pFileName - Pointer to the file name.
5921 - pBufSize - Pointer to the buffer size.
5922
5923 \return - 0 for success, non zero for failure
5924
5925 --------------------------------------------------------------------------*/
5926
5927VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5928{
5929 int status;
5930 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5931
5932 ENTER();
5933
5934 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5935
5936 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5937 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5938 status = VOS_STATUS_E_FAILURE;
5939 }
5940 else {
5941 *pBufSize = pHddCtx->fw->size;
5942 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5943 release_firmware(pHddCtx->fw);
5944 pHddCtx->fw = NULL;
5945 }
5946
5947 EXIT();
5948 return VOS_STATUS_SUCCESS;
5949}
5950
5951/**---------------------------------------------------------------------------
5952
5953 \brief hdd_read_cfg_file() -
5954
5955 This function reads the configuration file using the request firmware
5956 API and returns the cfg data and the buffer size of the configuration file.
5957
5958 \param - pCtx - Pointer to the adapter .
5959 - pFileName - Pointer to the file name.
5960 - pBuffer - Pointer to the data buffer.
5961 - pBufSize - Pointer to the buffer size.
5962
5963 \return - 0 for success, non zero for failure
5964
5965 --------------------------------------------------------------------------*/
5966
5967VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5968 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5969{
5970 int status;
5971 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5972
5973 ENTER();
5974
5975 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5976
5977 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5978 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5979 return VOS_STATUS_E_FAILURE;
5980 }
5981 else {
5982 if(*pBufSize != pHddCtx->fw->size) {
5983 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5984 "file size", __func__);
5985 release_firmware(pHddCtx->fw);
5986 pHddCtx->fw = NULL;
5987 return VOS_STATUS_E_FAILURE;
5988 }
5989 else {
5990 if(pBuffer) {
5991 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5992 }
5993 release_firmware(pHddCtx->fw);
5994 pHddCtx->fw = NULL;
5995 }
5996 }
5997
5998 EXIT();
5999
6000 return VOS_STATUS_SUCCESS;
6001}
6002
6003/**---------------------------------------------------------------------------
6004
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306005 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006006
6007 This function sets the user specified mac address using
6008 the command ifconfig wlanX hw ether <mac adress>.
6009
6010 \param - dev - Pointer to the net device.
6011 - addr - Pointer to the sockaddr.
6012 \return - 0 for success, non zero for failure
6013
6014 --------------------------------------------------------------------------*/
6015
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306016static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006017{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306018 hdd_adapter_t *pAdapter;
6019 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006020 struct sockaddr *psta_mac_addr = addr;
6021 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306022 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006023
6024 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306025 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6026 if (NULL == pAdapter)
6027 {
6028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6029 "%s: Adapter is NULL",__func__);
6030 return -EINVAL;
6031 }
6032 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6033 ret = wlan_hdd_validate_context(pHddCtx);
6034 if (0 != ret)
6035 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306036 return ret;
6037 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006038
6039 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6041
6042 EXIT();
6043 return halStatus;
6044}
6045
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306046/**---------------------------------------------------------------------------
6047
6048 \brief hdd_set_mac_address() -
6049
6050 Wrapper function to protect __hdd_set_mac_address() function from ssr
6051
6052 \param - dev - Pointer to the net device.
6053 - addr - Pointer to the sockaddr.
6054 \return - 0 for success, non zero for failure
6055
6056 --------------------------------------------------------------------------*/
6057static int hdd_set_mac_address(struct net_device *dev, void *addr)
6058{
6059 int ret;
6060
6061 vos_ssr_protect(__func__);
6062 ret = __hdd_set_mac_address(dev, addr);
6063 vos_ssr_unprotect(__func__);
6064
6065 return ret;
6066}
6067
Jeff Johnson295189b2012-06-20 16:38:30 -07006068tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6069{
6070 int i;
6071 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6072 {
Abhishek Singheb183782014-02-06 13:37:21 +05306073 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 break;
6075 }
6076
6077 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6078 return NULL;
6079
6080 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6081 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6082}
6083
6084void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6085{
6086 int i;
6087 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6088 {
6089 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6090 {
6091 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6092 break;
6093 }
6094 }
6095 return;
6096}
6097
6098#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6099 static struct net_device_ops wlan_drv_ops = {
6100 .ndo_open = hdd_open,
6101 .ndo_stop = hdd_stop,
6102 .ndo_uninit = hdd_uninit,
6103 .ndo_start_xmit = hdd_hard_start_xmit,
6104 .ndo_tx_timeout = hdd_tx_timeout,
6105 .ndo_get_stats = hdd_stats,
6106 .ndo_do_ioctl = hdd_ioctl,
6107 .ndo_set_mac_address = hdd_set_mac_address,
6108 .ndo_select_queue = hdd_select_queue,
6109#ifdef WLAN_FEATURE_PACKET_FILTERING
6110#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6111 .ndo_set_rx_mode = hdd_set_multicast_list,
6112#else
6113 .ndo_set_multicast_list = hdd_set_multicast_list,
6114#endif //LINUX_VERSION_CODE
6115#endif
6116 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006117 static struct net_device_ops wlan_mon_drv_ops = {
6118 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306119 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006120 .ndo_uninit = hdd_uninit,
6121 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6122 .ndo_tx_timeout = hdd_tx_timeout,
6123 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306124 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 .ndo_set_mac_address = hdd_set_mac_address,
6126 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306127
Jeff Johnson295189b2012-06-20 16:38:30 -07006128#endif
6129
6130void hdd_set_station_ops( struct net_device *pWlanDev )
6131{
6132#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006133 pWlanDev->netdev_ops = &wlan_drv_ops;
6134#else
6135 pWlanDev->open = hdd_open;
6136 pWlanDev->stop = hdd_stop;
6137 pWlanDev->uninit = hdd_uninit;
6138 pWlanDev->hard_start_xmit = NULL;
6139 pWlanDev->tx_timeout = hdd_tx_timeout;
6140 pWlanDev->get_stats = hdd_stats;
6141 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006142 pWlanDev->set_mac_address = hdd_set_mac_address;
6143#endif
6144}
6145
Katya Nigam1fd24402015-02-16 14:52:19 +05306146void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6147{
6148 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6149 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6150 #else
6151 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6152 #endif
6153}
6154
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006155static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006156{
6157 struct net_device *pWlanDev = NULL;
6158 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006159 /*
6160 * cfg80211 initialization and registration....
6161 */
6162 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6163
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 if(pWlanDev != NULL)
6165 {
6166
6167 //Save the pointer to the net_device in the HDD adapter
6168 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6169
Jeff Johnson295189b2012-06-20 16:38:30 -07006170 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6171
6172 pAdapter->dev = pWlanDev;
6173 pAdapter->pHddCtx = pHddCtx;
6174 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306175 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006176
6177 init_completion(&pAdapter->session_open_comp_var);
6178 init_completion(&pAdapter->session_close_comp_var);
6179 init_completion(&pAdapter->disconnect_comp_var);
6180 init_completion(&pAdapter->linkup_event_var);
6181 init_completion(&pAdapter->cancel_rem_on_chan_var);
6182 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306183 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006184#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6185 init_completion(&pAdapter->offchannel_tx_event);
6186#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006187 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006188#ifdef FEATURE_WLAN_TDLS
6189 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006190 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006191 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306192 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006194 init_completion(&pHddCtx->mc_sus_event_var);
6195 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306196 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006197 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006198 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006199
Rajeev79dbe4c2013-10-05 11:03:42 +05306200#ifdef FEATURE_WLAN_BATCH_SCAN
6201 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6202 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6203 pAdapter->pBatchScanRsp = NULL;
6204 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006205 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006206 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306207 mutex_init(&pAdapter->hdd_batch_scan_lock);
6208#endif
6209
Jeff Johnson295189b2012-06-20 16:38:30 -07006210 pAdapter->isLinkUpSvcNeeded = FALSE;
6211 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6212 //Init the net_device structure
6213 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6214
6215 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6216 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6217 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6218 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6219
6220 hdd_set_station_ops( pAdapter->dev );
6221
6222 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6224 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6225 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 /* set pWlanDev's parent to underlying device */
6227 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006228
6229 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006230 }
6231
6232 return pAdapter;
6233}
6234
6235VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6236{
6237 struct net_device *pWlanDev = pAdapter->dev;
6238 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6239 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6240 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6241
6242 if( rtnl_lock_held )
6243 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006244 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006245 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6246 {
6247 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6248 return VOS_STATUS_E_FAILURE;
6249 }
6250 }
6251 if (register_netdevice(pWlanDev))
6252 {
6253 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6254 return VOS_STATUS_E_FAILURE;
6255 }
6256 }
6257 else
6258 {
6259 if(register_netdev(pWlanDev))
6260 {
6261 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6262 return VOS_STATUS_E_FAILURE;
6263 }
6264 }
6265 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6266
6267 return VOS_STATUS_SUCCESS;
6268}
6269
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006270static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006271{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006272 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006273
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006274 if (NULL == pAdapter)
6275 {
6276 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6277 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006279
6280 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6281 {
6282 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6283 return eHAL_STATUS_NOT_INITIALIZED;
6284 }
6285
6286 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6287
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006288#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006289 /* need to make sure all of our scheduled work has completed.
6290 * This callback is called from MC thread context, so it is safe to
6291 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006292 *
6293 * Even though this is called from MC thread context, if there is a faulty
6294 * work item in the system, that can hang this call forever. So flushing
6295 * this global work queue is not safe; and now we make sure that
6296 * individual work queues are stopped correctly. But the cancel work queue
6297 * is a GPL only API, so the proprietary version of the driver would still
6298 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006299 */
6300 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006301#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006302
6303 /* We can be blocked while waiting for scheduled work to be
6304 * flushed, and the adapter structure can potentially be freed, in
6305 * which case the magic will have been reset. So make sure the
6306 * magic is still good, and hence the adapter structure is still
6307 * valid, before signaling completion */
6308 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6309 {
6310 complete(&pAdapter->session_close_comp_var);
6311 }
6312
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 return eHAL_STATUS_SUCCESS;
6314}
6315
6316VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6317{
6318 struct net_device *pWlanDev = pAdapter->dev;
6319 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6320 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6321 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6322 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306323 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006324
Nirav Shah7e3c8132015-06-22 23:51:42 +05306325 spin_lock_init( &pAdapter->sta_hash_lock);
6326 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6327
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006329 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 //Open a SME session for future operation
6331 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006332 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6334 {
6335 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006336 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 halStatus, halStatus );
6338 status = VOS_STATUS_E_FAILURE;
6339 goto error_sme_open;
6340 }
6341
6342 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306343 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006344 &pAdapter->session_open_comp_var,
6345 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306346 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006347 {
6348 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306349 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 status = VOS_STATUS_E_FAILURE;
6351 goto error_sme_open;
6352 }
6353
6354 // Register wireless extensions
6355 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6356 {
6357 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006358 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 halStatus, halStatus );
6360 status = VOS_STATUS_E_FAILURE;
6361 goto error_register_wext;
6362 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306363
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306365 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6366 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6367 #else
6368 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6369 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006370
6371 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306372 hddLog(VOS_TRACE_LEVEL_INFO,
6373 "%s: Set HDD connState to eConnectionState_NotConnected",
6374 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6376
6377 //Set the default operation channel
6378 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6379
6380 /* Make the default Auth Type as OPEN*/
6381 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6382
6383 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6384 {
6385 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006386 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 status, status );
6388 goto error_init_txrx;
6389 }
6390
6391 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6392
6393 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6394 {
6395 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006396 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 status, status );
6398 goto error_wmm_init;
6399 }
6400
6401 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6402
6403 return VOS_STATUS_SUCCESS;
6404
6405error_wmm_init:
6406 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6407 hdd_deinit_tx_rx(pAdapter);
6408error_init_txrx:
6409 hdd_UnregisterWext(pWlanDev);
6410error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006411 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 {
6413 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006414 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306415 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006416 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306418 unsigned long rc;
6419
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306421 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006423 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306424 if (rc <= 0)
6425 hddLog(VOS_TRACE_LEVEL_ERROR,
6426 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 }
6428}
6429error_sme_open:
6430 return status;
6431}
6432
Jeff Johnson295189b2012-06-20 16:38:30 -07006433void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6434{
6435 hdd_cfg80211_state_t *cfgState;
6436
6437 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6438
6439 if( NULL != cfgState->buf )
6440 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306441 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6443 rc = wait_for_completion_interruptible_timeout(
6444 &pAdapter->tx_action_cnf_event,
6445 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306446 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306449 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6450 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 }
6452 }
6453 return;
6454}
Jeff Johnson295189b2012-06-20 16:38:30 -07006455
c_hpothu002231a2015-02-05 14:58:51 +05306456void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006457{
6458 ENTER();
6459 switch ( pAdapter->device_mode )
6460 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306461 case WLAN_HDD_IBSS:
6462 {
6463 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6464 {
6465 hdd_ibss_deinit_tx_rx( pAdapter );
6466 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6467 }
6468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 case WLAN_HDD_INFRA_STATION:
6470 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006471 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006472 {
6473 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6474 {
6475 hdd_deinit_tx_rx( pAdapter );
6476 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6477 }
6478
6479 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6480 {
6481 hdd_wmm_adapter_close( pAdapter );
6482 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6483 }
6484
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 break;
6487 }
6488
6489 case WLAN_HDD_SOFTAP:
6490 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306492
6493 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6494 {
6495 hdd_wmm_adapter_close( pAdapter );
6496 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6497 }
6498
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006500
c_hpothu002231a2015-02-05 14:58:51 +05306501 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006503 break;
6504 }
6505
6506 case WLAN_HDD_MONITOR:
6507 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006508 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6509 {
6510 hdd_deinit_tx_rx( pAdapter );
6511 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6512 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006513 break;
6514 }
6515
6516
6517 default:
6518 break;
6519 }
6520
6521 EXIT();
6522}
6523
6524void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6525{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006526 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306527
6528 ENTER();
6529 if (NULL == pAdapter)
6530 {
6531 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6532 "%s: HDD adapter is Null", __func__);
6533 return;
6534 }
6535
6536 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006537
Rajeev79dbe4c2013-10-05 11:03:42 +05306538#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306539 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6540 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006541 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306542 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6543 )
6544 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006545 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306546 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006547 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6548 {
6549 hdd_deinit_batch_scan(pAdapter);
6550 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306551 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006552 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306553#endif
6554
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6556 if( rtnl_held )
6557 {
6558 unregister_netdevice(pWlanDev);
6559 }
6560 else
6561 {
6562 unregister_netdev(pWlanDev);
6563 }
6564 // note that the pAdapter is no longer valid at this point
6565 // since the memory has been reclaimed
6566 }
6567
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306568 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006569}
6570
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006571void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6572{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306573 VOS_STATUS status;
6574 hdd_adapter_t *pAdapter = NULL;
6575 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006576
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306577 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006578
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306579 /*loop through all adapters.*/
6580 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006581 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306582 pAdapter = pAdapterNode->pAdapter;
6583 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6584 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006585
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306586 { // we skip this registration for modes other than STA and P2P client modes.
6587 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6588 pAdapterNode = pNext;
6589 continue;
6590 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006591
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306592 //Apply Dynamic DTIM For P2P
6593 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6594 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6595 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6596 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6597 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6598 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6599 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6600 (eConnectionState_Associated ==
6601 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6602 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6603 {
6604 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006605
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306606 powerRequest.uIgnoreDTIM = 1;
6607 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6608
6609 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6610 {
6611 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6612 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6613 }
6614 else
6615 {
6616 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6617 }
6618
6619 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6620 * specified during Enter/Exit BMPS when LCD off*/
6621 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6622 NULL, eANI_BOOLEAN_FALSE);
6623 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6624 NULL, eANI_BOOLEAN_FALSE);
6625
6626 /* switch to the DTIM specified in cfg.ini */
6627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6628 "Switch to DTIM %d", powerRequest.uListenInterval);
6629 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6630 break;
6631
6632 }
6633
6634 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6635 pAdapterNode = pNext;
6636 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006637}
6638
6639void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6640{
6641 /*Switch back to DTIM 1*/
6642 tSirSetPowerParamsReq powerRequest = { 0 };
6643
6644 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6645 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006646 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006647
6648 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6649 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6650 NULL, eANI_BOOLEAN_FALSE);
6651 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6652 NULL, eANI_BOOLEAN_FALSE);
6653
6654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6655 "Switch to DTIM%d",powerRequest.uListenInterval);
6656 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6657
6658}
6659
Jeff Johnson295189b2012-06-20 16:38:30 -07006660VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6661{
6662 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306663 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6664 {
6665 hddLog( LOGE, FL("Wlan Unload in progress"));
6666 return VOS_STATUS_E_PERM;
6667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006668 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6669 {
6670 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6671 }
6672
6673 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6674 {
6675 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6676 }
6677
6678 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6679 {
6680 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6681 }
6682
6683 return status;
6684}
6685
6686VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6687{
6688 hdd_adapter_t *pAdapter = NULL;
6689 eHalStatus halStatus;
6690 VOS_STATUS status = VOS_STATUS_E_INVAL;
6691 v_BOOL_t disableBmps = FALSE;
6692 v_BOOL_t disableImps = FALSE;
6693
6694 switch(session_type)
6695 {
6696 case WLAN_HDD_INFRA_STATION:
6697 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006698 case WLAN_HDD_P2P_CLIENT:
6699 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006700 //Exit BMPS -> Is Sta/P2P Client is already connected
6701 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6702 if((NULL != pAdapter)&&
6703 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6704 {
6705 disableBmps = TRUE;
6706 }
6707
6708 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6709 if((NULL != pAdapter)&&
6710 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6711 {
6712 disableBmps = TRUE;
6713 }
6714
6715 //Exit both Bmps and Imps incase of Go/SAP Mode
6716 if((WLAN_HDD_SOFTAP == session_type) ||
6717 (WLAN_HDD_P2P_GO == session_type))
6718 {
6719 disableBmps = TRUE;
6720 disableImps = TRUE;
6721 }
6722
6723 if(TRUE == disableImps)
6724 {
6725 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6726 {
6727 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6728 }
6729 }
6730
6731 if(TRUE == disableBmps)
6732 {
6733 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6734 {
6735 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6736
6737 if(eHAL_STATUS_SUCCESS != halStatus)
6738 {
6739 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006740 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006741 VOS_ASSERT(0);
6742 return status;
6743 }
6744 }
6745
6746 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6747 {
6748 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6749
6750 if(eHAL_STATUS_SUCCESS != halStatus)
6751 {
6752 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006753 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006754 VOS_ASSERT(0);
6755 return status;
6756 }
6757 }
6758 }
6759
6760 if((TRUE == disableBmps) ||
6761 (TRUE == disableImps))
6762 {
6763 /* Now, get the chip into Full Power now */
6764 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6765 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6766 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6767
6768 if(halStatus != eHAL_STATUS_SUCCESS)
6769 {
6770 if(halStatus == eHAL_STATUS_PMC_PENDING)
6771 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306772 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306774 ret = wait_for_completion_interruptible_timeout(
6775 &pHddCtx->full_pwr_comp_var,
6776 msecs_to_jiffies(1000));
6777 if (ret <= 0)
6778 {
6779 hddLog(VOS_TRACE_LEVEL_ERROR,
6780 "%s: wait on full_pwr_comp_var failed %ld",
6781 __func__, ret);
6782 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006783 }
6784 else
6785 {
6786 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006787 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006788 VOS_ASSERT(0);
6789 return status;
6790 }
6791 }
6792
6793 status = VOS_STATUS_SUCCESS;
6794 }
6795
6796 break;
6797 }
6798 return status;
6799}
Katya Nigame7b69a82015-04-28 15:24:06 +05306800void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6801 {
6802 hdd_mon_ctx_t *pMonCtx = NULL;
6803 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6804
6805 pMonCtx->state = 0;
6806 pMonCtx->ChannelNo = 1;
6807 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306808 pMonCtx->crcCheckEnabled = 1;
6809 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6810 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306811 pMonCtx->numOfMacFilters = 0;
6812 }
6813
Jeff Johnson295189b2012-06-20 16:38:30 -07006814
6815hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006816 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006817 tANI_U8 rtnl_held )
6818{
6819 hdd_adapter_t *pAdapter = NULL;
6820 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6821 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6822 VOS_STATUS exitbmpsStatus;
6823
Arif Hussain6d2a3322013-11-17 19:50:10 -08006824 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006825
Nirav Shah436658f2014-02-28 17:05:45 +05306826 if(macAddr == NULL)
6827 {
6828 /* Not received valid macAddr */
6829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6830 "%s:Unable to add virtual intf: Not able to get"
6831 "valid mac address",__func__);
6832 return NULL;
6833 }
6834
Jeff Johnson295189b2012-06-20 16:38:30 -07006835 //Disable BMPS incase of Concurrency
6836 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6837
6838 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6839 {
6840 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306841 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 VOS_ASSERT(0);
6843 return NULL;
6844 }
6845
6846 switch(session_type)
6847 {
6848 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006850 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 {
6852 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6853
6854 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306855 {
6856 hddLog(VOS_TRACE_LEVEL_FATAL,
6857 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006858 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306859 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006860
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306861#ifdef FEATURE_WLAN_TDLS
6862 /* A Mutex Lock is introduced while changing/initializing the mode to
6863 * protect the concurrent access for the Adapters by TDLS module.
6864 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306865 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306866#endif
6867
Jeff Johnsone7245742012-09-05 17:12:55 -07006868 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6869 NL80211_IFTYPE_P2P_CLIENT:
6870 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006871
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306873#ifdef FEATURE_WLAN_TDLS
6874 mutex_unlock(&pHddCtx->tdls_lock);
6875#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306876
6877 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 if( VOS_STATUS_SUCCESS != status )
6879 goto err_free_netdev;
6880
6881 status = hdd_register_interface( pAdapter, rtnl_held );
6882 if( VOS_STATUS_SUCCESS != status )
6883 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306884#ifdef FEATURE_WLAN_TDLS
6885 mutex_lock(&pHddCtx->tdls_lock);
6886#endif
c_hpothu002231a2015-02-05 14:58:51 +05306887 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306888#ifdef FEATURE_WLAN_TDLS
6889 mutex_unlock(&pHddCtx->tdls_lock);
6890#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006891 goto err_free_netdev;
6892 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306893
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306894 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306895 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306896
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306897#ifdef WLAN_NS_OFFLOAD
6898 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306899 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306900#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006901 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306902 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 netif_tx_disable(pAdapter->dev);
6904 //netif_tx_disable(pWlanDev);
6905 netif_carrier_off(pAdapter->dev);
6906
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306907 if (WLAN_HDD_P2P_CLIENT == session_type ||
6908 WLAN_HDD_P2P_DEVICE == session_type)
6909 {
6910 /* Initialize the work queue to defer the
6911 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306912 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306913 hdd_p2p_roc_work_queue);
6914 }
6915
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 break;
6917 }
6918
Jeff Johnson295189b2012-06-20 16:38:30 -07006919 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 case WLAN_HDD_SOFTAP:
6921 {
6922 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6923 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306924 {
6925 hddLog(VOS_TRACE_LEVEL_FATAL,
6926 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006927 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306928 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006929
Jeff Johnson295189b2012-06-20 16:38:30 -07006930 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6931 NL80211_IFTYPE_AP:
6932 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 pAdapter->device_mode = session_type;
6934
6935 status = hdd_init_ap_mode(pAdapter);
6936 if( VOS_STATUS_SUCCESS != status )
6937 goto err_free_netdev;
6938
Nirav Shah7e3c8132015-06-22 23:51:42 +05306939 status = hdd_sta_id_hash_attach(pAdapter);
6940 if (VOS_STATUS_SUCCESS != status)
6941 {
6942 hddLog(VOS_TRACE_LEVEL_FATAL,
6943 FL("failed to attach hash for session %d"), session_type);
6944 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6945 goto err_free_netdev;
6946 }
6947
Jeff Johnson295189b2012-06-20 16:38:30 -07006948 status = hdd_register_hostapd( pAdapter, rtnl_held );
6949 if( VOS_STATUS_SUCCESS != status )
6950 {
c_hpothu002231a2015-02-05 14:58:51 +05306951 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 goto err_free_netdev;
6953 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306954 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006955 netif_tx_disable(pAdapter->dev);
6956 netif_carrier_off(pAdapter->dev);
6957
6958 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306959
6960 if (WLAN_HDD_P2P_GO == session_type)
6961 {
6962 /* Initialize the work queue to
6963 * defer the back to back RoC request */
6964 INIT_DELAYED_WORK(&pAdapter->roc_work,
6965 hdd_p2p_roc_work_queue);
6966 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 break;
6968 }
6969 case WLAN_HDD_MONITOR:
6970 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006971 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6972 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306973 {
6974 hddLog(VOS_TRACE_LEVEL_FATAL,
6975 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006976 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306977 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006978
Katya Nigame7b69a82015-04-28 15:24:06 +05306979 // Register wireless extensions
6980 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6981 {
6982 hddLog(VOS_TRACE_LEVEL_FATAL,
6983 "hdd_register_wext() failed with status code %08d [x%08x]",
6984 status, status );
6985 status = VOS_STATUS_E_FAILURE;
6986 }
6987
Jeff Johnson295189b2012-06-20 16:38:30 -07006988 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6989 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006990#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6991 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6992#else
6993 pAdapter->dev->open = hdd_mon_open;
6994 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05306995 pAdapter->dev->stop = hdd_mon_stop;
6996 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006997#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05306998 status = hdd_register_interface( pAdapter, rtnl_held );
6999 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 hdd_init_tx_rx( pAdapter );
7001 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307002 //Stop the Interface TX queue.
7003 netif_tx_disable(pAdapter->dev);
7004 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007005 }
7006 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007007 case WLAN_HDD_FTM:
7008 {
7009 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7010
7011 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307012 {
7013 hddLog(VOS_TRACE_LEVEL_FATAL,
7014 FL("failed to allocate adapter for session %d"), session_type);
7015 return NULL;
7016 }
7017
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7019 * message while loading driver in FTM mode. */
7020 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7021 pAdapter->device_mode = session_type;
7022 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307023
7024 hdd_init_tx_rx( pAdapter );
7025
7026 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307027 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307028 netif_tx_disable(pAdapter->dev);
7029 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007030 }
7031 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 default:
7033 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307034 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7035 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007036 VOS_ASSERT(0);
7037 return NULL;
7038 }
7039 }
7040
Jeff Johnson295189b2012-06-20 16:38:30 -07007041 if( VOS_STATUS_SUCCESS == status )
7042 {
7043 //Add it to the hdd's session list.
7044 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7045 if( NULL == pHddAdapterNode )
7046 {
7047 status = VOS_STATUS_E_NOMEM;
7048 }
7049 else
7050 {
7051 pHddAdapterNode->pAdapter = pAdapter;
7052 status = hdd_add_adapter_back ( pHddCtx,
7053 pHddAdapterNode );
7054 }
7055 }
7056
7057 if( VOS_STATUS_SUCCESS != status )
7058 {
7059 if( NULL != pAdapter )
7060 {
7061 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7062 pAdapter = NULL;
7063 }
7064 if( NULL != pHddAdapterNode )
7065 {
7066 vos_mem_free( pHddAdapterNode );
7067 }
7068
7069 goto resume_bmps;
7070 }
7071
7072 if(VOS_STATUS_SUCCESS == status)
7073 {
7074 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7075
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007076 //Initialize the WoWL service
7077 if(!hdd_init_wowl(pAdapter))
7078 {
7079 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7080 goto err_free_netdev;
7081 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007082 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007083 return pAdapter;
7084
7085err_free_netdev:
7086 free_netdev(pAdapter->dev);
7087 wlan_hdd_release_intf_addr( pHddCtx,
7088 pAdapter->macAddressCurrent.bytes );
7089
7090resume_bmps:
7091 //If bmps disabled enable it
7092 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7093 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307094 if (pHddCtx->hdd_wlan_suspended)
7095 {
7096 hdd_set_pwrparams(pHddCtx);
7097 }
7098 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007099 }
7100 return NULL;
7101}
7102
7103VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7104 tANI_U8 rtnl_held )
7105{
7106 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7107 VOS_STATUS status;
7108
7109 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7110 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307111 {
7112 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7113 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307115 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007116
7117 while ( pCurrent->pAdapter != pAdapter )
7118 {
7119 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7120 if( VOS_STATUS_SUCCESS != status )
7121 break;
7122
7123 pCurrent = pNext;
7124 }
7125 pAdapterNode = pCurrent;
7126 if( VOS_STATUS_SUCCESS == status )
7127 {
7128 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7129 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307130
7131#ifdef FEATURE_WLAN_TDLS
7132
7133 /* A Mutex Lock is introduced while changing/initializing the mode to
7134 * protect the concurrent access for the Adapters by TDLS module.
7135 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307136 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307137#endif
7138
Jeff Johnson295189b2012-06-20 16:38:30 -07007139 hdd_remove_adapter( pHddCtx, pAdapterNode );
7140 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007141 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007142
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307143#ifdef FEATURE_WLAN_TDLS
7144 mutex_unlock(&pHddCtx->tdls_lock);
7145#endif
7146
Jeff Johnson295189b2012-06-20 16:38:30 -07007147
7148 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307149 if ((!vos_concurrent_open_sessions_running()) &&
7150 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7151 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007152 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307153 if (pHddCtx->hdd_wlan_suspended)
7154 {
7155 hdd_set_pwrparams(pHddCtx);
7156 }
7157 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007158 }
7159
7160 return VOS_STATUS_SUCCESS;
7161 }
7162
7163 return VOS_STATUS_E_FAILURE;
7164}
7165
7166VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7167{
7168 hdd_adapter_list_node_t *pHddAdapterNode;
7169 VOS_STATUS status;
7170
7171 ENTER();
7172
7173 do
7174 {
7175 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7176 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7177 {
7178 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7179 vos_mem_free( pHddAdapterNode );
7180 }
7181 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7182
7183 EXIT();
7184
7185 return VOS_STATUS_SUCCESS;
7186}
7187
7188void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7189{
7190 v_U8_t addIE[1] = {0};
7191
7192 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7193 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7194 eANI_BOOLEAN_FALSE) )
7195 {
7196 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007197 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007198 }
7199
7200 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7201 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7202 eANI_BOOLEAN_FALSE) )
7203 {
7204 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007205 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007206 }
7207
7208 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7209 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7210 eANI_BOOLEAN_FALSE) )
7211 {
7212 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007213 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007214 }
7215}
7216
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307217VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7218 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007219{
7220 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7221 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307222 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307224 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307225 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307226 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007227
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307228 if (pHddCtx->isLogpInProgress) {
7229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7230 "%s:LOGP in Progress. Ignore!!!",__func__);
7231 return VOS_STATUS_E_FAILURE;
7232 }
7233
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307235
Nirav Shah7e3c8132015-06-22 23:51:42 +05307236 status = hdd_sta_id_hash_detach(pAdapter);
7237 if (status != VOS_STATUS_SUCCESS)
7238 hddLog(VOS_TRACE_LEVEL_ERROR,
7239 FL("sta id hash detach failed"));
7240
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307241 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007242 switch(pAdapter->device_mode)
7243 {
7244 case WLAN_HDD_INFRA_STATION:
7245 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007246 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307247 {
7248 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307249#ifdef FEATURE_WLAN_TDLS
7250 mutex_lock(&pHddCtx->tdls_lock);
7251 wlan_hdd_tdls_exit(pAdapter, TRUE);
7252 mutex_unlock(&pHddCtx->tdls_lock);
7253#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307254 if( hdd_connIsConnected(pstation) ||
7255 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007256 {
7257 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7258 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7259 pAdapter->sessionId,
7260 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7261 else
7262 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7263 pAdapter->sessionId,
7264 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7265 //success implies disconnect command got queued up successfully
7266 if(halStatus == eHAL_STATUS_SUCCESS)
7267 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307268 ret = wait_for_completion_interruptible_timeout(
7269 &pAdapter->disconnect_comp_var,
7270 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7271 if (ret <= 0)
7272 {
7273 hddLog(VOS_TRACE_LEVEL_ERROR,
7274 "%s: wait on disconnect_comp_var failed %ld",
7275 __func__, ret);
7276 }
7277 }
7278 else
7279 {
7280 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7281 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 }
7283 memset(&wrqu, '\0', sizeof(wrqu));
7284 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7285 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7286 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7287 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307288 else if(pstation->conn_info.connState ==
7289 eConnectionState_Disconnecting)
7290 {
7291 ret = wait_for_completion_interruptible_timeout(
7292 &pAdapter->disconnect_comp_var,
7293 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7294 if (ret <= 0)
7295 {
7296 hddLog(VOS_TRACE_LEVEL_ERROR,
7297 FL("wait on disconnect_comp_var failed %ld"), ret);
7298 }
7299 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307300 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007301 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307302 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307303 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007304 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307305 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7306 {
7307 while (pAdapter->is_roc_inprogress)
7308 {
7309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7310 "%s: ROC in progress for session %d!!!",
7311 __func__, pAdapter->sessionId);
7312 // waiting for ROC to expire
7313 msleep(500);
7314 /* In GO present case , if retry exceeds 3,
7315 it means something went wrong. */
7316 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7317 {
7318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7319 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307320 if (eHAL_STATUS_SUCCESS !=
7321 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7322 pAdapter->sessionId ))
7323 {
7324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7325 FL("Failed to Cancel Remain on Channel"));
7326 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307327 wait_for_completion_interruptible_timeout(
7328 &pAdapter->cancel_rem_on_chan_var,
7329 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7330 break;
7331 }
7332 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307333 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307334 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307335#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307336 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307337#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307338
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307339 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307340
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307341 /* It is possible that the caller of this function does not
7342 * wish to close the session
7343 */
7344 if (VOS_TRUE == bCloseSession &&
7345 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007346 {
7347 INIT_COMPLETION(pAdapter->session_close_comp_var);
7348 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307349 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307350 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007351 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307352 unsigned long ret;
7353
Jeff Johnson295189b2012-06-20 16:38:30 -07007354 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307355 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307356 &pAdapter->session_close_comp_var,
7357 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307358 if ( 0 >= ret)
7359 {
7360 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307361 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307362 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007363 }
7364 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307365 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007366 break;
7367
7368 case WLAN_HDD_SOFTAP:
7369 case WLAN_HDD_P2P_GO:
7370 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307371 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7372 while (pAdapter->is_roc_inprogress) {
7373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7374 "%s: ROC in progress for session %d!!!",
7375 __func__, pAdapter->sessionId);
7376 msleep(500);
7377 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7379 "%s: ROC completion is not received.!!!", __func__);
7380 WLANSAP_CancelRemainOnChannel(
7381 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7382 wait_for_completion_interruptible_timeout(
7383 &pAdapter->cancel_rem_on_chan_var,
7384 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7385 break;
7386 }
7387 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307388
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307389 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307390 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007391 mutex_lock(&pHddCtx->sap_lock);
7392 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7393 {
7394 VOS_STATUS status;
7395 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7396
7397 //Stop Bss.
7398 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7399 if (VOS_IS_STATUS_SUCCESS(status))
7400 {
7401 hdd_hostapd_state_t *pHostapdState =
7402 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7403
7404 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7405
7406 if (!VOS_IS_STATUS_SUCCESS(status))
7407 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307408 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7409 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 }
7411 }
7412 else
7413 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007414 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007415 }
7416 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307417 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007418
7419 if (eHAL_STATUS_FAILURE ==
7420 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7421 0, NULL, eANI_BOOLEAN_FALSE))
7422 {
7423 hddLog(LOGE,
7424 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007425 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 }
7427
7428 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7429 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7430 eANI_BOOLEAN_FALSE) )
7431 {
7432 hddLog(LOGE,
7433 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7434 }
7435
7436 // Reset WNI_CFG_PROBE_RSP Flags
7437 wlan_hdd_reset_prob_rspies(pAdapter);
7438 kfree(pAdapter->sessionCtx.ap.beacon);
7439 pAdapter->sessionCtx.ap.beacon = NULL;
7440 }
7441 mutex_unlock(&pHddCtx->sap_lock);
7442 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007443
Jeff Johnson295189b2012-06-20 16:38:30 -07007444 case WLAN_HDD_MONITOR:
7445 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007446
Jeff Johnson295189b2012-06-20 16:38:30 -07007447 default:
7448 break;
7449 }
7450
7451 EXIT();
7452 return VOS_STATUS_SUCCESS;
7453}
7454
7455VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7456{
7457 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7458 VOS_STATUS status;
7459 hdd_adapter_t *pAdapter;
7460
7461 ENTER();
7462
7463 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7464
7465 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7466 {
7467 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007468
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307469 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007470
7471 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7472 pAdapterNode = pNext;
7473 }
7474
7475 EXIT();
7476
7477 return VOS_STATUS_SUCCESS;
7478}
7479
Rajeev Kumarf999e582014-01-09 17:33:29 -08007480
7481#ifdef FEATURE_WLAN_BATCH_SCAN
7482/**---------------------------------------------------------------------------
7483
7484 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7485 structures
7486
7487 \param - pAdapter Pointer to HDD adapter
7488
7489 \return - None
7490
7491 --------------------------------------------------------------------------*/
7492void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7493{
7494 tHddBatchScanRsp *pNode;
7495 tHddBatchScanRsp *pPrev;
7496
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307497 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007498 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307499 hddLog(VOS_TRACE_LEVEL_ERROR,
7500 "%s: Adapter context is Null", __func__);
7501 return;
7502 }
7503
7504 pNode = pAdapter->pBatchScanRsp;
7505 while (pNode)
7506 {
7507 pPrev = pNode;
7508 pNode = pNode->pNext;
7509 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007510 }
7511
7512 pAdapter->pBatchScanRsp = NULL;
7513 pAdapter->numScanList = 0;
7514 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7515 pAdapter->prev_batch_id = 0;
7516
7517 return;
7518}
7519#endif
7520
7521
Jeff Johnson295189b2012-06-20 16:38:30 -07007522VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7523{
7524 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7525 VOS_STATUS status;
7526 hdd_adapter_t *pAdapter;
7527
7528 ENTER();
7529
7530 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7531
7532 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7533 {
7534 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307535 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007536 netif_tx_disable(pAdapter->dev);
7537 netif_carrier_off(pAdapter->dev);
7538
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007539 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7540
Jeff Johnson295189b2012-06-20 16:38:30 -07007541 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307542
Katya Nigam1fd24402015-02-16 14:52:19 +05307543 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7544 hdd_ibss_deinit_tx_rx(pAdapter);
7545
Nirav Shah7e3c8132015-06-22 23:51:42 +05307546 status = hdd_sta_id_hash_detach(pAdapter);
7547 if (status != VOS_STATUS_SUCCESS)
7548 hddLog(VOS_TRACE_LEVEL_ERROR,
7549 FL("sta id hash detach failed for session id %d"),
7550 pAdapter->sessionId);
7551
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307552 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7553
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307554 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7555 {
7556 hdd_wmm_adapter_close( pAdapter );
7557 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7558 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007559
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307560 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7561 {
7562 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7563 }
7564
Rajeev Kumarf999e582014-01-09 17:33:29 -08007565#ifdef FEATURE_WLAN_BATCH_SCAN
7566 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7567 {
7568 hdd_deinit_batch_scan(pAdapter);
7569 }
7570#endif
7571
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307572#ifdef FEATURE_WLAN_TDLS
7573 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307574 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307575 mutex_unlock(&pHddCtx->tdls_lock);
7576#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007577 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7578 pAdapterNode = pNext;
7579 }
7580
7581 EXIT();
7582
7583 return VOS_STATUS_SUCCESS;
7584}
7585
7586VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7587{
7588 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7589 VOS_STATUS status;
7590 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307591 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007592
7593 ENTER();
7594
7595 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7596
7597 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7598 {
7599 pAdapter = pAdapterNode->pAdapter;
7600
Kumar Anand82c009f2014-05-29 00:29:42 -07007601 hdd_wmm_init( pAdapter );
7602
Jeff Johnson295189b2012-06-20 16:38:30 -07007603 switch(pAdapter->device_mode)
7604 {
7605 case WLAN_HDD_INFRA_STATION:
7606 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007607 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307608
7609 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7610
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 hdd_init_station_mode(pAdapter);
7612 /* Open the gates for HDD to receive Wext commands */
7613 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007614 pHddCtx->scan_info.mScanPending = FALSE;
7615 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007616
7617 //Trigger the initial scan
7618 hdd_wlan_initial_scan(pAdapter);
7619
7620 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307621 if (eConnectionState_Associated == connState ||
7622 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007623 {
7624 union iwreq_data wrqu;
7625 memset(&wrqu, '\0', sizeof(wrqu));
7626 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7627 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7628 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007629 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007630
Jeff Johnson295189b2012-06-20 16:38:30 -07007631 /* indicate disconnected event to nl80211 */
7632 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7633 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007634 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307635 else if (eConnectionState_Connecting == connState)
7636 {
7637 /*
7638 * Indicate connect failure to supplicant if we were in the
7639 * process of connecting
7640 */
7641 cfg80211_connect_result(pAdapter->dev, NULL,
7642 NULL, 0, NULL, 0,
7643 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7644 GFP_KERNEL);
7645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007646 break;
7647
7648 case WLAN_HDD_SOFTAP:
7649 /* softAP can handle SSR */
7650 break;
7651
7652 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007653 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007654 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007655 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007656 break;
7657
7658 case WLAN_HDD_MONITOR:
7659 /* monitor interface start */
7660 break;
7661 default:
7662 break;
7663 }
7664
7665 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7666 pAdapterNode = pNext;
7667 }
7668
7669 EXIT();
7670
7671 return VOS_STATUS_SUCCESS;
7672}
7673
7674VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7675{
7676 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7677 hdd_adapter_t *pAdapter;
7678 VOS_STATUS status;
7679 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307680 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007681
7682 ENTER();
7683
7684 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7685
7686 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7687 {
7688 pAdapter = pAdapterNode->pAdapter;
7689
7690 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7691 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7692 {
7693 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7694 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7695
Abhishek Singhf4669da2014-05-26 15:07:49 +05307696 hddLog(VOS_TRACE_LEVEL_INFO,
7697 "%s: Set HDD connState to eConnectionState_NotConnected",
7698 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007699 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7700 init_completion(&pAdapter->disconnect_comp_var);
7701 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7702 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7703
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307704 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007705 &pAdapter->disconnect_comp_var,
7706 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307707 if (0 >= ret)
7708 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7709 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007710
7711 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7712 pHddCtx->isAmpAllowed = VOS_FALSE;
7713 sme_RoamConnect(pHddCtx->hHal,
7714 pAdapter->sessionId, &(pWextState->roamProfile),
7715 &roamId);
7716 }
7717
7718 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7719 pAdapterNode = pNext;
7720 }
7721
7722 EXIT();
7723
7724 return VOS_STATUS_SUCCESS;
7725}
7726
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007727void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7728{
7729 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7730 VOS_STATUS status;
7731 hdd_adapter_t *pAdapter;
7732 hdd_station_ctx_t *pHddStaCtx;
7733 hdd_ap_ctx_t *pHddApCtx;
7734 hdd_hostapd_state_t * pHostapdState;
7735 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7736 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7737 const char *p2pMode = "DEV";
7738 const char *ccMode = "Standalone";
7739 int n;
7740
7741 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7742 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7743 {
7744 pAdapter = pAdapterNode->pAdapter;
7745 switch (pAdapter->device_mode) {
7746 case WLAN_HDD_INFRA_STATION:
7747 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7748 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7749 staChannel = pHddStaCtx->conn_info.operationChannel;
7750 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7751 }
7752 break;
7753 case WLAN_HDD_P2P_CLIENT:
7754 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7755 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7756 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7757 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7758 p2pMode = "CLI";
7759 }
7760 break;
7761 case WLAN_HDD_P2P_GO:
7762 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7763 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7764 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7765 p2pChannel = pHddApCtx->operatingChannel;
7766 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7767 }
7768 p2pMode = "GO";
7769 break;
7770 case WLAN_HDD_SOFTAP:
7771 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7772 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7773 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7774 apChannel = pHddApCtx->operatingChannel;
7775 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7776 }
7777 break;
7778 default:
7779 break;
7780 }
7781 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7782 pAdapterNode = pNext;
7783 }
7784 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7785 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7786 }
7787 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7788 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7789 if (p2pChannel > 0) {
7790 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7791 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7792 }
7793 if (apChannel > 0) {
7794 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7795 apChannel, MAC_ADDR_ARRAY(apBssid));
7796 }
7797
7798 if (p2pChannel > 0 && apChannel > 0) {
7799 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7800 }
7801}
7802
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007803bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007804{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007805 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007806}
7807
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007808/* Once SSR is disabled then it cannot be set. */
7809void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007810{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007811 if (HDD_SSR_DISABLED == isSsrRequired)
7812 return;
7813
Jeff Johnson295189b2012-06-20 16:38:30 -07007814 isSsrRequired = value;
7815}
7816
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307817void hdd_set_pre_close( hdd_context_t *pHddCtx)
7818{
7819 sme_PreClose(pHddCtx->hHal);
7820}
7821
Jeff Johnson295189b2012-06-20 16:38:30 -07007822VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7823 hdd_adapter_list_node_t** ppAdapterNode)
7824{
7825 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307826 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007827 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7828 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307829 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 return status;
7831}
7832
7833VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7834 hdd_adapter_list_node_t* pAdapterNode,
7835 hdd_adapter_list_node_t** pNextAdapterNode)
7836{
7837 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307838 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007839 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7840 (hdd_list_node_t*) pAdapterNode,
7841 (hdd_list_node_t**)pNextAdapterNode );
7842
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307843 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007844 return status;
7845}
7846
7847VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7848 hdd_adapter_list_node_t* pAdapterNode)
7849{
7850 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307851 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007852 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7853 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307854 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007855 return status;
7856}
7857
7858VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7859 hdd_adapter_list_node_t** ppAdapterNode)
7860{
7861 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307862 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7864 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307865 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007866 return status;
7867}
7868
7869VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7870 hdd_adapter_list_node_t* pAdapterNode)
7871{
7872 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307873 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007874 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7875 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307876 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007877 return status;
7878}
7879
7880VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7881 hdd_adapter_list_node_t* pAdapterNode)
7882{
7883 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307884 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7886 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307887 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007888 return status;
7889}
7890
7891hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7892 tSirMacAddr macAddr )
7893{
7894 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7895 hdd_adapter_t *pAdapter;
7896 VOS_STATUS status;
7897
7898 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7899
7900 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7901 {
7902 pAdapter = pAdapterNode->pAdapter;
7903
7904 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7905 macAddr, sizeof(tSirMacAddr) ) )
7906 {
7907 return pAdapter;
7908 }
7909 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7910 pAdapterNode = pNext;
7911 }
7912
7913 return NULL;
7914
7915}
7916
7917hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7918{
7919 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7920 hdd_adapter_t *pAdapter;
7921 VOS_STATUS status;
7922
7923 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7924
7925 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7926 {
7927 pAdapter = pAdapterNode->pAdapter;
7928
7929 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7930 IFNAMSIZ ) )
7931 {
7932 return pAdapter;
7933 }
7934 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7935 pAdapterNode = pNext;
7936 }
7937
7938 return NULL;
7939
7940}
7941
7942hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7943{
7944 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7945 hdd_adapter_t *pAdapter;
7946 VOS_STATUS status;
7947
7948 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7949
7950 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7951 {
7952 pAdapter = pAdapterNode->pAdapter;
7953
7954 if( pAdapter && (mode == pAdapter->device_mode) )
7955 {
7956 return pAdapter;
7957 }
7958 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7959 pAdapterNode = pNext;
7960 }
7961
7962 return NULL;
7963
7964}
7965
7966//Remove this function later
7967hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7968{
7969 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7970 hdd_adapter_t *pAdapter;
7971 VOS_STATUS status;
7972
7973 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7974
7975 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7976 {
7977 pAdapter = pAdapterNode->pAdapter;
7978
7979 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7980 {
7981 return pAdapter;
7982 }
7983
7984 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7985 pAdapterNode = pNext;
7986 }
7987
7988 return NULL;
7989
7990}
7991
Jeff Johnson295189b2012-06-20 16:38:30 -07007992/**---------------------------------------------------------------------------
7993
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307994 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007995
7996 This API returns the operating channel of the requested device mode
7997
7998 \param - pHddCtx - Pointer to the HDD context.
7999 - mode - Device mode for which operating channel is required
8000 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8001 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8002 \return - channel number. "0" id the requested device is not found OR it is not connected.
8003 --------------------------------------------------------------------------*/
8004v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8005{
8006 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8007 VOS_STATUS status;
8008 hdd_adapter_t *pAdapter;
8009 v_U8_t operatingChannel = 0;
8010
8011 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8012
8013 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8014 {
8015 pAdapter = pAdapterNode->pAdapter;
8016
8017 if( mode == pAdapter->device_mode )
8018 {
8019 switch(pAdapter->device_mode)
8020 {
8021 case WLAN_HDD_INFRA_STATION:
8022 case WLAN_HDD_P2P_CLIENT:
8023 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8024 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8025 break;
8026 case WLAN_HDD_SOFTAP:
8027 case WLAN_HDD_P2P_GO:
8028 /*softap connection info */
8029 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8030 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8031 break;
8032 default:
8033 break;
8034 }
8035
8036 break; //Found the device of interest. break the loop
8037 }
8038
8039 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8040 pAdapterNode = pNext;
8041 }
8042 return operatingChannel;
8043}
8044
8045#ifdef WLAN_FEATURE_PACKET_FILTERING
8046/**---------------------------------------------------------------------------
8047
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308048 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008049
8050 This used to set the multicast address list.
8051
8052 \param - dev - Pointer to the WLAN device.
8053 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308054 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008055
8056 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308057static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008058{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308059 hdd_adapter_t *pAdapter;
8060 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308062 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308064
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308065 ENTER();
8066
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308067 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308068 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008069 {
8070 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308071 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 return;
8073 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308074 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8075 ret = wlan_hdd_validate_context(pHddCtx);
8076 if (0 != ret)
8077 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308078 return;
8079 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008080 if (dev->flags & IFF_ALLMULTI)
8081 {
8082 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008083 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308084 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308086 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 {
8088 mc_count = netdev_mc_count(dev);
8089 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008090 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8092 {
8093 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008094 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308095 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008096 return;
8097 }
8098
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308099 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008100
8101 netdev_for_each_mc_addr(ha, dev) {
8102 if (i == mc_count)
8103 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308104 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8105 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008106 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308107 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308108 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008109 i++;
8110 }
8111 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308112
8113 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 return;
8115}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308116
8117static void hdd_set_multicast_list(struct net_device *dev)
8118{
8119 vos_ssr_protect(__func__);
8120 __hdd_set_multicast_list(dev);
8121 vos_ssr_unprotect(__func__);
8122}
Jeff Johnson295189b2012-06-20 16:38:30 -07008123#endif
8124
8125/**---------------------------------------------------------------------------
8126
8127 \brief hdd_select_queue() -
8128
8129 This function is registered with the Linux OS for network
8130 core to decide which queue to use first.
8131
8132 \param - dev - Pointer to the WLAN device.
8133 - skb - Pointer to OS packet (sk_buff).
8134 \return - ac, Queue Index/access category corresponding to UP in IP header
8135
8136 --------------------------------------------------------------------------*/
8137v_U16_t hdd_select_queue(struct net_device *dev,
8138 struct sk_buff *skb)
8139{
8140 return hdd_wmm_select_queue(dev, skb);
8141}
8142
8143
8144/**---------------------------------------------------------------------------
8145
8146 \brief hdd_wlan_initial_scan() -
8147
8148 This function triggers the initial scan
8149
8150 \param - pAdapter - Pointer to the HDD adapter.
8151
8152 --------------------------------------------------------------------------*/
8153void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8154{
8155 tCsrScanRequest scanReq;
8156 tCsrChannelInfo channelInfo;
8157 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008158 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008159 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8160
8161 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8162 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8163 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8164
8165 if(sme_Is11dSupported(pHddCtx->hHal))
8166 {
8167 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8168 if ( HAL_STATUS_SUCCESS( halStatus ) )
8169 {
8170 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8171 if( !scanReq.ChannelInfo.ChannelList )
8172 {
8173 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8174 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008175 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 return;
8177 }
8178 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8179 channelInfo.numOfChannels);
8180 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8181 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008182 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008183 }
8184
8185 scanReq.scanType = eSIR_PASSIVE_SCAN;
8186 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8187 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8188 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8189 }
8190 else
8191 {
8192 scanReq.scanType = eSIR_ACTIVE_SCAN;
8193 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8194 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8195 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8196 }
8197
8198 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8199 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8200 {
8201 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8202 __func__, halStatus );
8203 }
8204
8205 if(sme_Is11dSupported(pHddCtx->hHal))
8206 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8207}
8208
mukul sharmabab477d2015-06-11 17:14:55 +05308209void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8210{
8211 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8212 VOS_STATUS status;
8213 hdd_adapter_t *pAdapter;
8214
8215 ENTER();
8216
8217 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8218
8219 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8220 {
8221 pAdapter = pAdapterNode->pAdapter;
8222
8223 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8224 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8225 pAdapterNode = pNext;
8226 }
8227
8228 EXIT();
8229}
Jeff Johnson295189b2012-06-20 16:38:30 -07008230/**---------------------------------------------------------------------------
8231
8232 \brief hdd_full_power_callback() - HDD full power callback function
8233
8234 This is the function invoked by SME to inform the result of a full power
8235 request issued by HDD
8236
8237 \param - callbackcontext - Pointer to cookie
8238 \param - status - result of request
8239
8240 \return - None
8241
8242 --------------------------------------------------------------------------*/
8243static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8244{
Jeff Johnson72a40512013-12-19 10:14:15 -08008245 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008246
8247 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308248 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008249
8250 if (NULL == callbackContext)
8251 {
8252 hddLog(VOS_TRACE_LEVEL_ERROR,
8253 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008254 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008255 return;
8256 }
8257
Jeff Johnson72a40512013-12-19 10:14:15 -08008258 /* there is a race condition that exists between this callback
8259 function and the caller since the caller could time out either
8260 before or while this code is executing. we use a spinlock to
8261 serialize these actions */
8262 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008263
8264 if (POWER_CONTEXT_MAGIC != pContext->magic)
8265 {
8266 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008267 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 hddLog(VOS_TRACE_LEVEL_WARN,
8269 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008270 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008271 return;
8272 }
8273
Jeff Johnson72a40512013-12-19 10:14:15 -08008274 /* context is valid so caller is still waiting */
8275
8276 /* paranoia: invalidate the magic */
8277 pContext->magic = 0;
8278
8279 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008280 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008281
8282 /* serialization is complete */
8283 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008284}
8285
Katya Nigamf0511f62015-05-05 16:40:57 +05308286void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8287{
8288 pMonCtx->typeSubtypeBitmap = 0;
8289 if( type%10 ) /* Management Packets */
8290 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8291 type/=10;
8292 if( type%10 ) /* Control Packets */
8293 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8294 type/=10;
8295 if( type%10 ) /* Data Packets */
8296 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8297}
8298
8299VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8300{
8301 vos_msg_t monMsg;
8302
8303 monMsg.type = WDA_MON_START_REQ;
8304 monMsg.reserved = 0;
8305 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8306 monMsg.bodyval = 0;
8307
8308 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8309 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8310 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8311 return VOS_STATUS_E_FAILURE;
8312 }
8313
8314 return VOS_STATUS_SUCCESS;
8315}
8316
8317void wlan_hdd_mon_poststopmsg(void)
8318{
8319 vos_msg_t monMsg;
8320
8321 monMsg.type = WDA_MON_STOP_REQ;
8322 monMsg.reserved = 0;
8323 monMsg.bodyptr = NULL;
8324 monMsg.bodyval = 0;
8325
8326 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8327 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8328 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8329 }
8330}
8331
Katya Nigame7b69a82015-04-28 15:24:06 +05308332void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8333{
8334 VOS_STATUS vosStatus;
8335 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8336 struct wiphy *wiphy = pHddCtx->wiphy;
8337
8338 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8339 if(pAdapter == NULL || pVosContext == NULL)
8340 {
8341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8342 return ;
8343 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308344
8345 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308346 hdd_UnregisterWext(pAdapter->dev);
8347
8348 vos_mon_stop( pVosContext );
8349
8350 vosStatus = vos_sched_close( pVosContext );
8351 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8352 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8353 "%s: Failed to close VOSS Scheduler",__func__);
8354 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8355 }
8356
8357 vosStatus = vos_nv_close();
8358 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8359 {
8360 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8361 "%s: Failed to close NV", __func__);
8362 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8363 }
8364
8365 vos_close(pVosContext);
8366
8367 #ifdef WLAN_KD_READY_NOTIFIER
8368 nl_srv_exit(pHddCtx->ptt_pid);
8369 #else
8370 nl_srv_exit();
8371 #endif
8372
8373 if (pHddCtx->cfg_ini)
8374 {
8375 kfree(pHddCtx->cfg_ini);
8376 pHddCtx->cfg_ini= NULL;
8377 }
8378 hdd_close_all_adapters( pHddCtx );
8379
8380 wiphy_free(wiphy) ;
8381
8382}
Jeff Johnson295189b2012-06-20 16:38:30 -07008383/**---------------------------------------------------------------------------
8384
8385 \brief hdd_wlan_exit() - HDD WLAN exit function
8386
8387 This is the driver exit point (invoked during rmmod)
8388
8389 \param - pHddCtx - Pointer to the HDD Context
8390
8391 \return - None
8392
8393 --------------------------------------------------------------------------*/
8394void hdd_wlan_exit(hdd_context_t *pHddCtx)
8395{
8396 eHalStatus halStatus;
8397 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8398 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308399 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008400 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008401 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308403 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008404
8405 ENTER();
8406
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308407
Katya Nigame7b69a82015-04-28 15:24:06 +05308408 if (VOS_MONITOR_MODE == hdd_get_conparam())
8409 {
8410 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8411 wlan_hdd_mon_close(pHddCtx);
8412 return;
8413 }
8414 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008415 {
8416 // Unloading, restart logic is no more required.
8417 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008418
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308419#ifdef FEATURE_WLAN_TDLS
8420 /* At the time of driver unloading; if tdls connection is present;
8421 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8422 * wlan_hdd_tdls_find_peer always checks for valid context;
8423 * as load/unload in progress there can be a race condition.
8424 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8425 * when tdls state is enabled.
8426 * As soon as driver set load/unload flag; tdls flag also needs
8427 * to be disabled so that hdd_rx_packet_cbk won't call
8428 * wlan_hdd_tdls_find_peer.
8429 */
8430 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8431#endif
8432
c_hpothu5ab05e92014-06-13 17:34:05 +05308433 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8434 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008435 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308436 pAdapter = pAdapterNode->pAdapter;
8437 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308439 /* Disable TX on the interface, after this hard_start_xmit() will
8440 * not be called on that interface
8441 */
8442 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8443 netif_tx_disable(pAdapter->dev);
8444
8445 /* Mark the interface status as "down" for outside world */
8446 netif_carrier_off(pAdapter->dev);
8447
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308448 /* DeInit the adapter. This ensures that all data packets
8449 * are freed.
8450 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308451#ifdef FEATURE_WLAN_TDLS
8452 mutex_lock(&pHddCtx->tdls_lock);
8453#endif
c_hpothu002231a2015-02-05 14:58:51 +05308454 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308455#ifdef FEATURE_WLAN_TDLS
8456 mutex_unlock(&pHddCtx->tdls_lock);
8457#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308458
c_hpothu5ab05e92014-06-13 17:34:05 +05308459 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8460 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8461 {
8462 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8463 hdd_UnregisterWext(pAdapter->dev);
8464 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308465
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308467 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8468 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008469 }
mukul sharmabab477d2015-06-11 17:14:55 +05308470
8471 //Purge all sme cmd's for all interface
8472 hdd_purge_cmd_list_all_adapters(pHddCtx);
8473
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308474 // Cancel any outstanding scan requests. We are about to close all
8475 // of our adapters, but an adapter structure is what SME passes back
8476 // to our callback function. Hence if there are any outstanding scan
8477 // requests then there is a race condition between when the adapter
8478 // is closed and when the callback is invoked.We try to resolve that
8479 // race condition here by canceling any outstanding scans before we
8480 // close the adapters.
8481 // Note that the scans may be cancelled in an asynchronous manner,
8482 // so ideally there needs to be some kind of synchronization. Rather
8483 // than introduce a new synchronization here, we will utilize the
8484 // fact that we are about to Request Full Power, and since that is
8485 // synchronized, the expectation is that by the time Request Full
8486 // Power has completed all scans will be cancelled.
8487 if (pHddCtx->scan_info.mScanPending)
8488 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308489 if(NULL != pAdapter)
8490 {
8491 hddLog(VOS_TRACE_LEVEL_INFO,
8492 FL("abort scan mode: %d sessionId: %d"),
8493 pAdapter->device_mode,
8494 pAdapter->sessionId);
8495 }
8496 hdd_abort_mac_scan(pHddCtx,
8497 pHddCtx->scan_info.sessionId,
8498 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008500 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308501 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008502 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308503 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308504 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8505 {
8506 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8508 "%s: in middle of FTM START", __func__);
8509 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8510 msecs_to_jiffies(20000));
8511 if(!lrc)
8512 {
8513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8514 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8515 }
8516 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008517 wlan_hdd_ftm_close(pHddCtx);
8518 goto free_hdd_ctx;
8519 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308520
Jeff Johnson295189b2012-06-20 16:38:30 -07008521 /* DeRegister with platform driver as client for Suspend/Resume */
8522 vosStatus = hddDeregisterPmOps(pHddCtx);
8523 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8524 {
8525 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8526 VOS_ASSERT(0);
8527 }
8528
8529 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8530 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8531 {
8532 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8533 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008534
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008535 //Stop the traffic monitor timer
8536 if ( VOS_TIMER_STATE_RUNNING ==
8537 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8538 {
8539 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8540 }
8541
8542 // Destroy the traffic monitor timer
8543 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8544 &pHddCtx->tx_rx_trafficTmr)))
8545 {
8546 hddLog(VOS_TRACE_LEVEL_ERROR,
8547 "%s: Cannot deallocate Traffic monitor timer", __func__);
8548 }
8549
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 //Disable IMPS/BMPS as we do not want the device to enter any power
8551 //save mode during shutdown
8552 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8553 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8554 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8555
8556 //Ensure that device is in full power as we will touch H/W during vos_Stop
8557 init_completion(&powerContext.completion);
8558 powerContext.magic = POWER_CONTEXT_MAGIC;
8559
8560 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8561 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8562
8563 if (eHAL_STATUS_SUCCESS != halStatus)
8564 {
8565 if (eHAL_STATUS_PMC_PENDING == halStatus)
8566 {
8567 /* request was sent -- wait for the response */
8568 lrc = wait_for_completion_interruptible_timeout(
8569 &powerContext.completion,
8570 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008571 if (lrc <= 0)
8572 {
8573 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008574 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008575 }
8576 }
8577 else
8578 {
8579 hddLog(VOS_TRACE_LEVEL_ERROR,
8580 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008581 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 /* continue -- need to clean up as much as possible */
8583 }
8584 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308585 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8586 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8587 {
8588 /* This will issue a dump command which will clean up
8589 BTQM queues and unblock MC thread */
8590 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008592
Jeff Johnson72a40512013-12-19 10:14:15 -08008593 /* either we never sent a request, we sent a request and received a
8594 response or we sent a request and timed out. if we never sent a
8595 request or if we sent a request and got a response, we want to
8596 clear the magic out of paranoia. if we timed out there is a
8597 race condition such that the callback function could be
8598 executing at the same time we are. of primary concern is if the
8599 callback function had already verified the "magic" but had not
8600 yet set the completion variable when a timeout occurred. we
8601 serialize these activities by invalidating the magic while
8602 holding a shared spinlock which will cause us to block if the
8603 callback is currently executing */
8604 spin_lock(&hdd_context_lock);
8605 powerContext.magic = 0;
8606 spin_unlock(&hdd_context_lock);
8607
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308608 /* If Device is shutdown, no point for SME to wait for responses
8609 from device. Pre Close SME */
8610 if(wcnss_device_is_shutdown())
8611 {
8612 sme_PreClose(pHddCtx->hHal);
8613 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008614 hdd_debugfs_exit(pHddCtx);
8615
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308616#ifdef WLAN_NS_OFFLOAD
8617 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8618 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8619#endif
8620 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8621 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8622
Jeff Johnson295189b2012-06-20 16:38:30 -07008623 // Unregister the Net Device Notifier
8624 unregister_netdevice_notifier(&hdd_netdev_notifier);
8625
Jeff Johnson295189b2012-06-20 16:38:30 -07008626 hdd_stop_all_adapters( pHddCtx );
8627
Jeff Johnson295189b2012-06-20 16:38:30 -07008628#ifdef WLAN_BTAMP_FEATURE
8629 vosStatus = WLANBAP_Stop(pVosContext);
8630 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8631 {
8632 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8633 "%s: Failed to stop BAP",__func__);
8634 }
8635#endif //WLAN_BTAMP_FEATURE
8636
8637 //Stop all the modules
8638 vosStatus = vos_stop( pVosContext );
8639 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8640 {
8641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8642 "%s: Failed to stop VOSS",__func__);
8643 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8644 }
8645
Jeff Johnson295189b2012-06-20 16:38:30 -07008646 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008648
8649 //Close the scheduler before calling vos_close to make sure no thread is
8650 // scheduled after the each module close is called i.e after all the data
8651 // structures are freed.
8652 vosStatus = vos_sched_close( pVosContext );
8653 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8654 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8655 "%s: Failed to close VOSS Scheduler",__func__);
8656 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8657 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008658#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8659 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308660 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008661#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008662 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308663 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008664
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308665#ifdef CONFIG_ENABLE_LINUX_REG
8666 vosStatus = vos_nv_close();
8667 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8668 {
8669 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8670 "%s: Failed to close NV", __func__);
8671 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8672 }
8673#endif
8674
Jeff Johnson295189b2012-06-20 16:38:30 -07008675 //Close VOSS
8676 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8677 vos_close(pVosContext);
8678
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 //Close Watchdog
8680 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8681 vos_watchdog_close(pVosContext);
8682
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308683 //Clean up HDD Nlink Service
8684 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308685
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308686#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308687 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308688 {
8689 wlan_logging_sock_deactivate_svc();
8690 }
8691#endif
8692
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308693#ifdef WLAN_KD_READY_NOTIFIER
8694 nl_srv_exit(pHddCtx->ptt_pid);
8695#else
8696 nl_srv_exit();
8697#endif /* WLAN_KD_READY_NOTIFIER */
8698
8699
Jeff Johnson295189b2012-06-20 16:38:30 -07008700 hdd_close_all_adapters( pHddCtx );
8701
Jeff Johnson295189b2012-06-20 16:38:30 -07008702 /* free the power on lock from platform driver */
8703 if (free_riva_power_on_lock("wlan"))
8704 {
8705 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8706 __func__);
8707 }
8708
Jeff Johnson88ba7742013-02-27 14:36:02 -08008709free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308710
8711 //Free up dynamically allocated members inside HDD Adapter
8712 if (pHddCtx->cfg_ini)
8713 {
8714 kfree(pHddCtx->cfg_ini);
8715 pHddCtx->cfg_ini= NULL;
8716 }
8717
Leo Changf04ddad2013-09-18 13:46:38 -07008718 /* FTM mode, WIPHY did not registered
8719 If un-register here, system crash will happen */
8720 if (VOS_FTM_MODE != hdd_get_conparam())
8721 {
8722 wiphy_unregister(wiphy) ;
8723 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008725 if (hdd_is_ssr_required())
8726 {
8727 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008728 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 msleep(5000);
8730 }
8731 hdd_set_ssr_required (VOS_FALSE);
8732}
8733
8734
8735/**---------------------------------------------------------------------------
8736
8737 \brief hdd_update_config_from_nv() - Function to update the contents of
8738 the running configuration with parameters taken from NV storage
8739
8740 \param - pHddCtx - Pointer to the HDD global context
8741
8742 \return - VOS_STATUS_SUCCESS if successful
8743
8744 --------------------------------------------------------------------------*/
8745static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8746{
Jeff Johnson295189b2012-06-20 16:38:30 -07008747 v_BOOL_t itemIsValid = VOS_FALSE;
8748 VOS_STATUS status;
8749 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8750 v_U8_t macLoop;
8751
8752 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8753 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8754 if(status != VOS_STATUS_SUCCESS)
8755 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008756 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 return VOS_STATUS_E_FAILURE;
8758 }
8759
8760 if (itemIsValid == VOS_TRUE)
8761 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008762 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8764 VOS_MAX_CONCURRENCY_PERSONA);
8765 if(status != VOS_STATUS_SUCCESS)
8766 {
8767 /* Get MAC from NV fail, not update CFG info
8768 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008769 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008770 return VOS_STATUS_E_FAILURE;
8771 }
8772
8773 /* If first MAC is not valid, treat all others are not valid
8774 * Then all MACs will be got from ini file */
8775 if(vos_is_macaddr_zero(&macFromNV[0]))
8776 {
8777 /* MAC address in NV file is not configured yet */
8778 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8779 return VOS_STATUS_E_INVAL;
8780 }
8781
8782 /* Get MAC address from NV, update CFG info */
8783 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8784 {
8785 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8786 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308787 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008788 /* This MAC is not valid, skip it
8789 * This MAC will be got from ini file */
8790 }
8791 else
8792 {
8793 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8794 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8795 VOS_MAC_ADDR_SIZE);
8796 }
8797 }
8798 }
8799 else
8800 {
8801 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8802 return VOS_STATUS_E_FAILURE;
8803 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008804
Jeff Johnson295189b2012-06-20 16:38:30 -07008805
8806 return VOS_STATUS_SUCCESS;
8807}
8808
8809/**---------------------------------------------------------------------------
8810
8811 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8812
8813 \param - pAdapter - Pointer to the HDD
8814
8815 \return - None
8816
8817 --------------------------------------------------------------------------*/
8818VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8819{
8820 eHalStatus halStatus;
8821 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308822 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008823
Jeff Johnson295189b2012-06-20 16:38:30 -07008824
8825 // Send ready indication to the HDD. This will kick off the MAC
8826 // into a 'running' state and should kick off an initial scan.
8827 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8828 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8829 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308830 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008831 "code %08d [x%08x]",__func__, halStatus, halStatus );
8832 return VOS_STATUS_E_FAILURE;
8833 }
8834
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308835 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008836 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8837 // And RIVA will crash
8838 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8839 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308840 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8841 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8842
8843
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 return VOS_STATUS_SUCCESS;
8845}
8846
Jeff Johnson295189b2012-06-20 16:38:30 -07008847/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308848void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008849{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308850
8851 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8852
Jeff Johnson295189b2012-06-20 16:38:30 -07008853}
8854
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308855void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008856{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308857
8858 vos_wake_lock_release(&wlan_wake_lock, reason);
8859
Jeff Johnson295189b2012-06-20 16:38:30 -07008860}
8861
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308862void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008863{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308864
8865 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8866 reason);
8867
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008868}
8869
Jeff Johnson295189b2012-06-20 16:38:30 -07008870/**---------------------------------------------------------------------------
8871
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008872 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8873 information between Host and Riva
8874
8875 This function gets reported version of FW
8876 It also finds the version of Riva headers used to compile the host
8877 It compares the above two and prints a warning if they are different
8878 It gets the SW and HW version string
8879 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8880 indicating the features they support through a bitmap
8881
8882 \param - pHddCtx - Pointer to HDD context
8883
8884 \return - void
8885
8886 --------------------------------------------------------------------------*/
8887
8888void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8889{
8890
8891 tSirVersionType versionCompiled;
8892 tSirVersionType versionReported;
8893 tSirVersionString versionString;
8894 tANI_U8 fwFeatCapsMsgSupported = 0;
8895 VOS_STATUS vstatus;
8896
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008897 memset(&versionCompiled, 0, sizeof(versionCompiled));
8898 memset(&versionReported, 0, sizeof(versionReported));
8899
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008900 /* retrieve and display WCNSS version information */
8901 do {
8902
8903 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8904 &versionCompiled);
8905 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8906 {
8907 hddLog(VOS_TRACE_LEVEL_FATAL,
8908 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008909 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008910 break;
8911 }
8912
8913 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8914 &versionReported);
8915 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8916 {
8917 hddLog(VOS_TRACE_LEVEL_FATAL,
8918 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008919 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008920 break;
8921 }
8922
8923 if ((versionCompiled.major != versionReported.major) ||
8924 (versionCompiled.minor != versionReported.minor) ||
8925 (versionCompiled.version != versionReported.version) ||
8926 (versionCompiled.revision != versionReported.revision))
8927 {
8928 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8929 "Host expected %u.%u.%u.%u\n",
8930 WLAN_MODULE_NAME,
8931 (int)versionReported.major,
8932 (int)versionReported.minor,
8933 (int)versionReported.version,
8934 (int)versionReported.revision,
8935 (int)versionCompiled.major,
8936 (int)versionCompiled.minor,
8937 (int)versionCompiled.version,
8938 (int)versionCompiled.revision);
8939 }
8940 else
8941 {
8942 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8943 WLAN_MODULE_NAME,
8944 (int)versionReported.major,
8945 (int)versionReported.minor,
8946 (int)versionReported.version,
8947 (int)versionReported.revision);
8948 }
8949
8950 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8951 versionString,
8952 sizeof(versionString));
8953 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8954 {
8955 hddLog(VOS_TRACE_LEVEL_FATAL,
8956 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008957 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008958 break;
8959 }
8960
8961 pr_info("%s: WCNSS software version %s\n",
8962 WLAN_MODULE_NAME, versionString);
8963
8964 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8965 versionString,
8966 sizeof(versionString));
8967 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8968 {
8969 hddLog(VOS_TRACE_LEVEL_FATAL,
8970 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008971 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008972 break;
8973 }
8974
8975 pr_info("%s: WCNSS hardware version %s\n",
8976 WLAN_MODULE_NAME, versionString);
8977
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008978 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8979 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008980 send the message only if it the riva is 1.1
8981 minor numbers for different riva branches:
8982 0 -> (1.0)Mainline Build
8983 1 -> (1.1)Mainline Build
8984 2->(1.04) Stability Build
8985 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008986 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008987 ((versionReported.minor>=1) && (versionReported.version>=1)))
8988 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8989 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008990
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008991 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008992 {
8993#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8994 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8995 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8996#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008997 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8998 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8999 {
9000 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9001 }
9002
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009003 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009004 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009005
9006 } while (0);
9007
9008}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309009void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9010{
9011 struct sk_buff *skb;
9012 struct nlmsghdr *nlh;
9013 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309014 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309015
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309016 if (in_interrupt() || irqs_disabled() || in_atomic())
9017 flags = GFP_ATOMIC;
9018
9019 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309020
9021 if(skb == NULL) {
9022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9023 "%s: alloc_skb failed", __func__);
9024 return;
9025 }
9026
9027 nlh = (struct nlmsghdr *)skb->data;
9028 nlh->nlmsg_pid = 0; /* from kernel */
9029 nlh->nlmsg_flags = 0;
9030 nlh->nlmsg_seq = 0;
9031 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9032
9033 ani_hdr = NLMSG_DATA(nlh);
9034 ani_hdr->type = type;
9035
9036 switch(type) {
9037 case WLAN_SVC_SAP_RESTART_IND:
9038 ani_hdr->length = 0;
9039 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9040 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9041 break;
9042 default:
9043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9044 "Attempt to send unknown nlink message %d", type);
9045 kfree_skb(skb);
9046 return;
9047 }
9048
9049 nl_srv_bcast(skb);
9050
9051 return;
9052}
9053
9054
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009055
9056/**---------------------------------------------------------------------------
9057
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309058 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9059
9060 \param - pHddCtx - Pointer to the hdd context
9061
9062 \return - true if hardware supports 5GHz
9063
9064 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309065boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309066{
9067 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9068 * then hardware support 5Ghz.
9069 */
9070 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9071 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309073 return true;
9074 }
9075 else
9076 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309078 __func__);
9079 return false;
9080 }
9081}
9082
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309083/**---------------------------------------------------------------------------
9084
9085 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9086 generate function
9087
9088 This is generate the random mac address for WLAN interface
9089
9090 \param - pHddCtx - Pointer to HDD context
9091 idx - Start interface index to get auto
9092 generated mac addr.
9093 mac_addr - Mac address
9094
9095 \return - 0 for success, < 0 for failure
9096
9097 --------------------------------------------------------------------------*/
9098
9099static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9100 int idx, v_MACADDR_t mac_addr)
9101{
9102 int i;
9103 unsigned int serialno;
9104 serialno = wcnss_get_serial_number();
9105
9106 if (0 != serialno)
9107 {
9108 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9109 bytes of the serial number that can be used to generate
9110 the other 3 bytes of the MAC address. Mask off all but
9111 the lower 3 bytes (this will also make sure we don't
9112 overflow in the next step) */
9113 serialno &= 0x00FFFFFF;
9114
9115 /* we need a unique address for each session */
9116 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9117
9118 /* autogen other Mac addresses */
9119 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9120 {
9121 /* start with the entire default address */
9122 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9123 /* then replace the lower 3 bytes */
9124 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9125 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9126 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9127
9128 serialno++;
9129 hddLog(VOS_TRACE_LEVEL_ERROR,
9130 "%s: Derived Mac Addr: "
9131 MAC_ADDRESS_STR, __func__,
9132 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9133 }
9134
9135 }
9136 else
9137 {
9138 hddLog(LOGE, FL("Failed to Get Serial NO"));
9139 return -1;
9140 }
9141 return 0;
9142}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309143
Katya Nigame7b69a82015-04-28 15:24:06 +05309144int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9145{
9146 VOS_STATUS status;
9147 v_CONTEXT_t pVosContext= NULL;
9148 hdd_adapter_t *pAdapter= NULL;
9149
9150 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9151
9152 if (NULL == pVosContext)
9153 {
9154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9155 "%s: Trying to open VOSS without a PreOpen", __func__);
9156 VOS_ASSERT(0);
9157 return VOS_STATUS_E_FAILURE;
9158 }
9159
9160 status = vos_nv_open();
9161 if (!VOS_IS_STATUS_SUCCESS(status))
9162 {
9163 /* NV module cannot be initialized */
9164 hddLog( VOS_TRACE_LEVEL_FATAL,
9165 "%s: vos_nv_open failed", __func__);
9166 return VOS_STATUS_E_FAILURE;
9167 }
9168
9169 status = vos_init_wiphy_from_nv_bin();
9170 if (!VOS_IS_STATUS_SUCCESS(status))
9171 {
9172 /* NV module cannot be initialized */
9173 hddLog( VOS_TRACE_LEVEL_FATAL,
9174 "%s: vos_init_wiphy failed", __func__);
9175 goto err_vos_nv_close;
9176 }
9177
9178 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9179 if ( !VOS_IS_STATUS_SUCCESS( status ))
9180 {
9181 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9182 goto err_vos_nv_close;
9183 }
9184
9185 status = vos_mon_start( pVosContext );
9186 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9187 {
9188 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9189 goto err_vosclose;
9190 }
9191
9192 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9193 WDA_featureCapsExchange(pVosContext);
9194 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9195
9196 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9197 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9198 if( pAdapter == NULL )
9199 {
9200 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9201 goto err_close_adapter;
9202 }
9203
9204 //Initialize the nlink service
9205 if(nl_srv_init() != 0)
9206 {
9207 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9208 goto err_close_adapter;
9209 }
9210 return VOS_STATUS_SUCCESS;
9211
9212err_close_adapter:
9213 hdd_close_all_adapters( pHddCtx );
9214 vos_mon_stop( pVosContext );
9215err_vosclose:
9216 status = vos_sched_close( pVosContext );
9217 if (!VOS_IS_STATUS_SUCCESS(status)) {
9218 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9219 "%s: Failed to close VOSS Scheduler", __func__);
9220 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9221 }
9222 vos_close(pVosContext );
9223
9224err_vos_nv_close:
9225 vos_nv_close();
9226
9227return status;
9228}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309229/**---------------------------------------------------------------------------
9230
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309231 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9232 completed to flush out the scan results
9233
9234 11d scan is done during driver load and is a passive scan on all
9235 channels supported by the device, 11d scans may find some APs on
9236 frequencies which are forbidden to be used in the regulatory domain
9237 the device is operating in. If these APs are notified to the supplicant
9238 it may try to connect to these APs, thus flush out all the scan results
9239 which are present in SME after 11d scan is done.
9240
9241 \return - eHalStatus
9242
9243 --------------------------------------------------------------------------*/
9244static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9245 tANI_U32 scanId, eCsrScanStatus status)
9246{
9247 ENTER();
9248
9249 sme_ScanFlushResult(halHandle, 0);
9250
9251 EXIT();
9252
9253 return eHAL_STATUS_SUCCESS;
9254}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309255/**---------------------------------------------------------------------------
9256
9257 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9258 logging is completed successfully.
9259
9260 \return - None
9261
9262 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309263void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309264{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309265 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309266
9267 if (NULL == pHddCtx)
9268 {
9269 hddLog(VOS_TRACE_LEVEL_ERROR,
9270 "%s: HDD context is NULL",__func__);
9271 return;
9272 }
9273
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309274 if ((VOS_STATUS_SUCCESS == status) &&
9275 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309276 {
9277 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9278 pHddCtx->mgmt_frame_logging = TRUE;
9279 }
9280 else
9281 {
9282 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9283 pHddCtx->mgmt_frame_logging = FALSE;
9284 }
9285
9286 return;
9287}
9288/**---------------------------------------------------------------------------
9289
9290 \brief hdd_init_frame_logging - function to initialize frame logging.
9291 Currently only Mgmt Frames are logged in both TX
9292 and Rx direction and are sent to userspace
9293 application using logger thread when queried.
9294
9295 \return - None
9296
9297 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309298void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309299{
9300 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309301 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309302
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309303 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9304 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309305 {
9306 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9307 return;
9308 }
9309
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309310 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9311 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309312 {
9313 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9314 return;
9315 }
9316
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309317 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309318
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309319 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9320 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9321 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9322 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309323
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309324 if (pHddCtx->cfg_ini->enableFWLogging ||
9325 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309326 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309327 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309328 }
9329
Sushant Kaushik46804902015-07-08 14:46:03 +05309330 if (pHddCtx->cfg_ini->enableMgmtLogging)
9331 {
9332 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9333 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309334 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9335 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309336 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309337 }
9338
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309339 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9340 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9341 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9342 wlanFWLoggingInitParam->continuousFrameLogging =
9343 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309344
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309345 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309346
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309347 wlanFWLoggingInitParam->minLogBufferSize =
9348 pHddCtx->cfg_ini->minLoggingBufferSize;
9349 wlanFWLoggingInitParam->maxLogBufferSize =
9350 pHddCtx->cfg_ini->maxLoggingBufferSize;
9351 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9352 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309353
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309354 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309355
9356 if (eHAL_STATUS_SUCCESS != halStatus)
9357 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309358 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309359 }
9360
9361 return;
9362}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309363
9364/**---------------------------------------------------------------------------
9365
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 \brief hdd_wlan_startup() - HDD init function
9367
9368 This is the driver startup code executed once a WLAN device has been detected
9369
9370 \param - dev - Pointer to the underlying device
9371
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009372 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009373
9374 --------------------------------------------------------------------------*/
9375
9376int hdd_wlan_startup(struct device *dev )
9377{
9378 VOS_STATUS status;
9379 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009380 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 hdd_context_t *pHddCtx = NULL;
9382 v_CONTEXT_t pVosContext= NULL;
9383#ifdef WLAN_BTAMP_FEATURE
9384 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9385 WLANBAP_ConfigType btAmpConfig;
9386 hdd_config_t *pConfig;
9387#endif
9388 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009389 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309390 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009391
9392 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009393 /*
9394 * cfg80211: wiphy allocation
9395 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309396 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009397
9398 if(wiphy == NULL)
9399 {
9400 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009401 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009402 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 pHddCtx = wiphy_priv(wiphy);
9404
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 //Initialize the adapter context to zeros.
9406 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9407
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309409 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309410 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009411
9412 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9413
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309414 /* register for riva power on lock to platform driver
9415 * Locking power early to ensure FW doesn't reset by kernel while
9416 * host driver is busy initializing itself */
9417 if (req_riva_power_on_lock("wlan"))
9418 {
9419 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9420 __func__);
9421 goto err_free_hdd_context;
9422 }
9423
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 /*Get vos context here bcoz vos_open requires it*/
9425 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9426
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009427 if(pVosContext == NULL)
9428 {
9429 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9430 goto err_free_hdd_context;
9431 }
9432
Jeff Johnson295189b2012-06-20 16:38:30 -07009433 //Save the Global VOSS context in adapter context for future.
9434 pHddCtx->pvosContext = pVosContext;
9435
9436 //Save the adapter context in global context for future.
9437 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9438
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 pHddCtx->parent_dev = dev;
9440
9441 init_completion(&pHddCtx->full_pwr_comp_var);
9442 init_completion(&pHddCtx->standby_comp_var);
9443 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009444 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009445 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309446 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309447 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009448
9449#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009450 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009451#else
9452 init_completion(&pHddCtx->driver_crda_req);
9453#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009454
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309455 spin_lock_init(&pHddCtx->schedScan_lock);
9456
Jeff Johnson295189b2012-06-20 16:38:30 -07009457 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9458
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309459#ifdef FEATURE_WLAN_TDLS
9460 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9461 * invoked by other instances also) to protect the concurrent
9462 * access for the Adapters by TDLS module.
9463 */
9464 mutex_init(&pHddCtx->tdls_lock);
9465#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309466 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309467 mutex_init(&pHddCtx->wmmLock);
9468
Agarwal Ashish1f422872014-07-22 00:11:55 +05309469 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309470
Agarwal Ashish1f422872014-07-22 00:11:55 +05309471 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 // Load all config first as TL config is needed during vos_open
9473 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9474 if(pHddCtx->cfg_ini == NULL)
9475 {
9476 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9477 goto err_free_hdd_context;
9478 }
9479
9480 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9481
9482 // Read and parse the qcom_cfg.ini file
9483 status = hdd_parse_config_ini( pHddCtx );
9484 if ( VOS_STATUS_SUCCESS != status )
9485 {
9486 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9487 __func__, WLAN_INI_FILE);
9488 goto err_config;
9489 }
Arif Hussaind5218912013-12-05 01:10:55 -08009490#ifdef MEMORY_DEBUG
9491 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9492 vos_mem_init();
9493
9494 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9495 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9496#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009497
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309498 /* INI has been read, initialise the configuredMcastBcastFilter with
9499 * INI value as this will serve as the default value
9500 */
9501 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9502 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9503 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309504
9505 if (false == hdd_is_5g_supported(pHddCtx))
9506 {
9507 //5Ghz is not supported.
9508 if (1 != pHddCtx->cfg_ini->nBandCapability)
9509 {
9510 hddLog(VOS_TRACE_LEVEL_INFO,
9511 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9512 pHddCtx->cfg_ini->nBandCapability = 1;
9513 }
9514 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309515
9516 /* If SNR Monitoring is enabled, FW has to parse all beacons
9517 * for calcaluting and storing the average SNR, so set Nth beacon
9518 * filter to 1 to enable FW to parse all the beaocons
9519 */
9520 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9521 {
9522 /* The log level is deliberately set to WARN as overriding
9523 * nthBeaconFilter to 1 will increase power cosumption and this
9524 * might just prove helpful to detect the power issue.
9525 */
9526 hddLog(VOS_TRACE_LEVEL_WARN,
9527 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9528 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009530 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309531 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009533 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009534 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009535 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9536 {
9537 hddLog(VOS_TRACE_LEVEL_FATAL,
9538 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9539 goto err_config;
9540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009542
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009543 // Update VOS trace levels based upon the cfg.ini
9544 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9545 pHddCtx->cfg_ini->vosTraceEnableBAP);
9546 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9547 pHddCtx->cfg_ini->vosTraceEnableTL);
9548 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9549 pHddCtx->cfg_ini->vosTraceEnableWDI);
9550 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9551 pHddCtx->cfg_ini->vosTraceEnableHDD);
9552 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9553 pHddCtx->cfg_ini->vosTraceEnableSME);
9554 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9555 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309556 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9557 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009558 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9559 pHddCtx->cfg_ini->vosTraceEnableWDA);
9560 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9561 pHddCtx->cfg_ini->vosTraceEnableSYS);
9562 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9563 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009564 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9565 pHddCtx->cfg_ini->vosTraceEnableSAP);
9566 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9567 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009568
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 // Update WDI trace levels based upon the cfg.ini
9570 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9571 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9572 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9573 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9574 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9575 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9576 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9577 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009578
Jeff Johnson88ba7742013-02-27 14:36:02 -08009579 if (VOS_FTM_MODE == hdd_get_conparam())
9580 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9582 {
9583 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9584 goto err_free_hdd_context;
9585 }
9586 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309587 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309588 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009590 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009591
Katya Nigame7b69a82015-04-28 15:24:06 +05309592 if( VOS_MONITOR_MODE == hdd_get_conparam())
9593 {
9594 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9595 {
9596 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9597 goto err_free_hdd_context;
9598 }
9599 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9600 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9601 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9602 return VOS_STATUS_SUCCESS;
9603 }
9604
Jeff Johnson88ba7742013-02-27 14:36:02 -08009605 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9607 {
9608 status = vos_watchdog_open(pVosContext,
9609 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9610
9611 if(!VOS_IS_STATUS_SUCCESS( status ))
9612 {
9613 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309614 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009615 }
9616 }
9617
9618 pHddCtx->isLogpInProgress = FALSE;
9619 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9620
Amar Singhala49cbc52013-10-08 18:37:44 -07009621#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009622 /* initialize the NV module. This is required so that
9623 we can initialize the channel information in wiphy
9624 from the NV.bin data. The channel information in
9625 wiphy needs to be initialized before wiphy registration */
9626
9627 status = vos_nv_open();
9628 if (!VOS_IS_STATUS_SUCCESS(status))
9629 {
9630 /* NV module cannot be initialized */
9631 hddLog( VOS_TRACE_LEVEL_FATAL,
9632 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309633 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009634 }
9635
9636 status = vos_init_wiphy_from_nv_bin();
9637 if (!VOS_IS_STATUS_SUCCESS(status))
9638 {
9639 /* NV module cannot be initialized */
9640 hddLog( VOS_TRACE_LEVEL_FATAL,
9641 "%s: vos_init_wiphy failed", __func__);
9642 goto err_vos_nv_close;
9643 }
9644
Amar Singhala49cbc52013-10-08 18:37:44 -07009645#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309646 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309647 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 if ( !VOS_IS_STATUS_SUCCESS( status ))
9649 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009650 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309651 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 }
9653
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9655
9656 if ( NULL == pHddCtx->hHal )
9657 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009658 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009659 goto err_vosclose;
9660 }
9661
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009662 status = vos_preStart( pHddCtx->pvosContext );
9663 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9664 {
9665 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309666 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009667 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009668
Arif Hussaineaf68602013-12-30 23:10:44 -08009669 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9670 {
9671 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9672 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9673 __func__, enable_dfs_chan_scan);
9674 }
9675 if (0 == enable_11d || 1 == enable_11d)
9676 {
9677 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9678 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9679 __func__, enable_11d);
9680 }
9681
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009682 /* Note that the vos_preStart() sequence triggers the cfg download.
9683 The cfg download must occur before we update the SME config
9684 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009685 status = hdd_set_sme_config( pHddCtx );
9686
9687 if ( VOS_STATUS_SUCCESS != status )
9688 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009689 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309690 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009691 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009692
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 /* In the integrated architecture we update the configuration from
9694 the INI file and from NV before vOSS has been started so that
9695 the final contents are available to send down to the cCPU */
9696
9697 // Apply the cfg.ini to cfg.dat
9698 if (FALSE == hdd_update_config_dat(pHddCtx))
9699 {
9700 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309701 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009702 }
9703
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309704 // Get mac addr from platform driver
9705 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9706
9707 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309709 /* Store the mac addr for first interface */
9710 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9711
9712 hddLog(VOS_TRACE_LEVEL_ERROR,
9713 "%s: WLAN Mac Addr: "
9714 MAC_ADDRESS_STR, __func__,
9715 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9716
9717 /* Here, passing Arg2 as 1 because we do not want to change the
9718 last 3 bytes (means non OUI bytes) of first interface mac
9719 addr.
9720 */
9721 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9722 {
9723 hddLog(VOS_TRACE_LEVEL_ERROR,
9724 "%s: Failed to generate wlan interface mac addr "
9725 "using MAC from ini file ", __func__);
9726 }
9727 }
9728 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9729 {
9730 // Apply the NV to cfg.dat
9731 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009732#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9733 /* There was not a valid set of MAC Addresses in NV. See if the
9734 default addresses were modified by the cfg.ini settings. If so,
9735 we'll use them, but if not, we'll autogenerate a set of MAC
9736 addresses based upon the device serial number */
9737
9738 static const v_MACADDR_t default_address =
9739 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009740
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309741 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9742 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009743 {
9744 /* cfg.ini has the default address, invoke autogen logic */
9745
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309746 /* Here, passing Arg2 as 0 because we want to change the
9747 last 3 bytes (means non OUI bytes) of all the interfaces
9748 mac addr.
9749 */
9750 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9751 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309753 hddLog(VOS_TRACE_LEVEL_ERROR,
9754 "%s: Failed to generate wlan interface mac addr "
9755 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9756 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 }
9759 else
9760#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9761 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009762 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 "%s: Invalid MAC address in NV, using MAC from ini file "
9764 MAC_ADDRESS_STR, __func__,
9765 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9766 }
9767 }
9768 {
9769 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309770
9771 /* Set the MAC Address Currently this is used by HAL to
9772 * add self sta. Remove this once self sta is added as
9773 * part of session open.
9774 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9776 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9777 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309778
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 if (!HAL_STATUS_SUCCESS( halStatus ))
9780 {
9781 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9782 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309783 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009784 }
9785 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009786
9787 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9788 Note: Firmware image will be read and downloaded inside vos_start API */
9789 status = vos_start( pHddCtx->pvosContext );
9790 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9791 {
9792 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309793 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 }
9795
Leo Chang6cec3e22014-01-21 15:33:49 -08009796#ifdef FEATURE_WLAN_CH_AVOID
9797 /* Plug in avoid channel notification callback
9798 * This should happen before ADD_SELF_STA
9799 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309800
9801 /* check the Channel Avoidance is enabled */
9802 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9803 {
9804 sme_AddChAvoidCallback(pHddCtx->hHal,
9805 hdd_hostapd_ch_avoid_cb);
9806 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009807#endif /* FEATURE_WLAN_CH_AVOID */
9808
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009809 /* Exchange capability info between Host and FW and also get versioning info from FW */
9810 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009811
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309812#ifdef CONFIG_ENABLE_LINUX_REG
9813 status = wlan_hdd_init_channels(pHddCtx);
9814 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9815 {
9816 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9817 __func__);
9818 goto err_vosstop;
9819 }
9820#endif
9821
Jeff Johnson295189b2012-06-20 16:38:30 -07009822 status = hdd_post_voss_start_config( pHddCtx );
9823 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9824 {
9825 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9826 __func__);
9827 goto err_vosstop;
9828 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009829
9830#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309831 wlan_hdd_cfg80211_update_reg_info( wiphy );
9832
9833 /* registration of wiphy dev with cfg80211 */
9834 if (0 > wlan_hdd_cfg80211_register(wiphy))
9835 {
9836 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9837 goto err_vosstop;
9838 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009839#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009840
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309841#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309842 /* registration of wiphy dev with cfg80211 */
9843 if (0 > wlan_hdd_cfg80211_register(wiphy))
9844 {
9845 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9846 goto err_vosstop;
9847 }
9848
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309849 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309850 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9851 {
9852 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9853 __func__);
9854 goto err_unregister_wiphy;
9855 }
9856#endif
9857
c_hpothu4a298be2014-12-22 21:12:51 +05309858 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9859
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9861 {
9862 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9863 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9864 }
9865 else
9866 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9868 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9869 if (pAdapter != NULL)
9870 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309871 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309873 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9874 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9875 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009876
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309877 /* Generate the P2P Device Address. This consists of the device's
9878 * primary MAC address with the locally administered bit set.
9879 */
9880 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009881 }
9882 else
9883 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309884 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9885 if (p2p_dev_addr != NULL)
9886 {
9887 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9888 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9889 }
9890 else
9891 {
9892 hddLog(VOS_TRACE_LEVEL_FATAL,
9893 "%s: Failed to allocate mac_address for p2p_device",
9894 __func__);
9895 goto err_close_adapter;
9896 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009898
9899 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9900 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9901 if ( NULL == pP2pAdapter )
9902 {
9903 hddLog(VOS_TRACE_LEVEL_FATAL,
9904 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009905 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009906 goto err_close_adapter;
9907 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009908 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009910
9911 if( pAdapter == NULL )
9912 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9914 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009916
Arif Hussain66559122013-11-21 10:11:40 -08009917 if (country_code)
9918 {
9919 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009920 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009921 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9922#ifndef CONFIG_ENABLE_LINUX_REG
9923 hdd_checkandupdate_phymode(pAdapter, country_code);
9924#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009925 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9926 (void *)(tSmeChangeCountryCallback)
9927 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009928 country_code,
9929 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309930 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009931 if (eHAL_STATUS_SUCCESS == ret)
9932 {
Arif Hussaincb607082013-12-20 11:57:42 -08009933 ret = wait_for_completion_interruptible_timeout(
9934 &pAdapter->change_country_code,
9935 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9936
9937 if (0 >= ret)
9938 {
9939 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9940 "%s: SME while setting country code timed out", __func__);
9941 }
Arif Hussain66559122013-11-21 10:11:40 -08009942 }
9943 else
9944 {
Arif Hussaincb607082013-12-20 11:57:42 -08009945 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9946 "%s: SME Change Country code from module param fail ret=%d",
9947 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009948 }
9949 }
9950
Jeff Johnson295189b2012-06-20 16:38:30 -07009951#ifdef WLAN_BTAMP_FEATURE
9952 vStatus = WLANBAP_Open(pVosContext);
9953 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9954 {
9955 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9956 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009957 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 }
9959
9960 vStatus = BSL_Init(pVosContext);
9961 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9962 {
9963 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9964 "%s: Failed to Init BSL",__func__);
9965 goto err_bap_close;
9966 }
9967 vStatus = WLANBAP_Start(pVosContext);
9968 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9969 {
9970 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9971 "%s: Failed to start TL",__func__);
9972 goto err_bap_close;
9973 }
9974
9975 pConfig = pHddCtx->cfg_ini;
9976 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9977 status = WLANBAP_SetConfig(&btAmpConfig);
9978
9979#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009980
Mihir Shete9c238772014-10-15 14:35:16 +05309981 /*
9982 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9983 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9984 * which is greater than 0xf. So the below check is safe to make
9985 * sure that there is no entry for UapsdMask in the ini
9986 */
9987 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9988 {
9989 if(IS_DYNAMIC_WMM_PS_ENABLED)
9990 {
9991 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9992 __func__);
9993 pHddCtx->cfg_ini->UapsdMask =
9994 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9995 }
9996 else
9997 {
9998 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9999 __func__);
10000 pHddCtx->cfg_ini->UapsdMask =
10001 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10002 }
10003 }
10004
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010005#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10006 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10007 {
10008 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10009 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10010 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10011 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10012 }
10013#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010014
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010015 wlan_hdd_tdls_init(pHddCtx);
10016
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010017 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10018
Jeff Johnson295189b2012-06-20 16:38:30 -070010019 /* Register with platform driver as client for Suspend/Resume */
10020 status = hddRegisterPmOps(pHddCtx);
10021 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10022 {
10023 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10024#ifdef WLAN_BTAMP_FEATURE
10025 goto err_bap_stop;
10026#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010027 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010028#endif //WLAN_BTAMP_FEATURE
10029 }
10030
Yue Ma0d4891e2013-08-06 17:01:45 -070010031 /* Open debugfs interface */
10032 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10033 {
10034 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10035 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010036 }
10037
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 /* Register TM level change handler function to the platform */
10039 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10040 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10041 {
10042 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10043 goto err_unregister_pmops;
10044 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010045
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 // register net device notifier for device change notification
10047 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10048
10049 if(ret < 0)
10050 {
10051 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010052 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 }
10054
10055 //Initialize the nlink service
10056 if(nl_srv_init() != 0)
10057 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010058 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 goto err_reg_netdev;
10060 }
10061
Leo Chang4ce1cc52013-10-21 18:27:15 -070010062#ifdef WLAN_KD_READY_NOTIFIER
10063 pHddCtx->kd_nl_init = 1;
10064#endif /* WLAN_KD_READY_NOTIFIER */
10065
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 //Initialize the BTC service
10067 if(btc_activate_service(pHddCtx) != 0)
10068 {
10069 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10070 goto err_nl_srv;
10071 }
10072
10073#ifdef PTT_SOCK_SVC_ENABLE
10074 //Initialize the PTT service
10075 if(ptt_sock_activate_svc(pHddCtx) != 0)
10076 {
10077 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10078 goto err_nl_srv;
10079 }
10080#endif
10081
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010082#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10083 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10084 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010085 if(wlan_logging_sock_activate_svc(
10086 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10087 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10088 {
10089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10090 " failed", __func__);
10091 goto err_nl_srv;
10092 }
10093 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10094 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010095 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10096 pHddCtx->cfg_ini->gEnableDebugLog =
10097 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010098 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010099
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010100 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10101 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010102 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010103 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010104 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010105 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010106 }
10107 else
10108 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010109 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010110 }
10111
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010112#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010113
10114
Sushant Kaushik215778f2015-05-21 14:05:36 +053010115 if (vos_is_multicast_logging())
10116 wlan_logging_set_log_level();
10117
Jeff Johnson295189b2012-06-20 16:38:30 -070010118 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010120 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010121 /* Action frame registered in one adapter which will
10122 * applicable to all interfaces
10123 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010124 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010125 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010126
10127 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010128 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010129
Jeff Johnsone7245742012-09-05 17:12:55 -070010130#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10131 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010132 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010133 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010134
Jeff Johnsone7245742012-09-05 17:12:55 -070010135#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010136 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010137 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010138 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010139
Jeff Johnsone7245742012-09-05 17:12:55 -070010140
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010141 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10142 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010143
Katya Nigam5c306ea2014-06-19 15:39:54 +053010144 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010146 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010147
10148#ifdef FEATURE_WLAN_SCAN_PNO
10149 /*SME must send channel update configuration to RIVA*/
10150 sme_UpdateChannelConfig(pHddCtx->hHal);
10151#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010152 /* Send the update default channel list to the FW*/
10153 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010154
10155 /* Fwr capabilities received, Set the Dot11 mode */
10156 sme_SetDefDot11Mode(pHddCtx->hHal);
10157
Abhishek Singha306a442013-11-07 18:39:01 +053010158#ifndef CONFIG_ENABLE_LINUX_REG
10159 /*updating wiphy so that regulatory user hints can be processed*/
10160 if (wiphy)
10161 {
10162 regulatory_hint(wiphy, "00");
10163 }
10164#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010165 // Initialize the restart logic
10166 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010167
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010168 //Register the traffic monitor timer now
10169 if ( pHddCtx->cfg_ini->dynSplitscan)
10170 {
10171 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10172 VOS_TIMER_TYPE_SW,
10173 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10174 (void *)pHddCtx);
10175 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010176 wlan_hdd_cfg80211_nan_init(pHddCtx);
10177
Dino Mycle6fb96c12014-06-10 11:52:40 +053010178#ifdef WLAN_FEATURE_EXTSCAN
10179 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10180 wlan_hdd_cfg80211_extscan_callback,
10181 pHddCtx);
10182#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010183
10184#ifdef WLAN_NS_OFFLOAD
10185 // Register IPv6 notifier to notify if any change in IP
10186 // So that we can reconfigure the offload parameters
10187 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10188 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10189 if (ret)
10190 {
10191 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10192 }
10193 else
10194 {
10195 hddLog(LOGE, FL("Registered IPv6 notifier"));
10196 }
10197#endif
10198
10199 // Register IPv4 notifier to notify if any change in IP
10200 // So that we can reconfigure the offload parameters
10201 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10202 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10203 if (ret)
10204 {
10205 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10206 }
10207 else
10208 {
10209 hddLog(LOGE, FL("Registered IPv4 notifier"));
10210 }
10211
Jeff Johnson295189b2012-06-20 16:38:30 -070010212 goto success;
10213
10214err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010215#ifdef WLAN_KD_READY_NOTIFIER
10216 nl_srv_exit(pHddCtx->ptt_pid);
10217#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010219#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010220err_reg_netdev:
10221 unregister_netdevice_notifier(&hdd_netdev_notifier);
10222
Jeff Johnson295189b2012-06-20 16:38:30 -070010223err_unregister_pmops:
10224 hddDevTmUnregisterNotifyCallback(pHddCtx);
10225 hddDeregisterPmOps(pHddCtx);
10226
Yue Ma0d4891e2013-08-06 17:01:45 -070010227 hdd_debugfs_exit(pHddCtx);
10228
Jeff Johnson295189b2012-06-20 16:38:30 -070010229#ifdef WLAN_BTAMP_FEATURE
10230err_bap_stop:
10231 WLANBAP_Stop(pVosContext);
10232#endif
10233
10234#ifdef WLAN_BTAMP_FEATURE
10235err_bap_close:
10236 WLANBAP_Close(pVosContext);
10237#endif
10238
Jeff Johnson295189b2012-06-20 16:38:30 -070010239err_close_adapter:
10240 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010241#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010242err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010243#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010244 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010245err_vosstop:
10246 vos_stop(pVosContext);
10247
Amar Singhala49cbc52013-10-08 18:37:44 -070010248err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010249 status = vos_sched_close( pVosContext );
10250 if (!VOS_IS_STATUS_SUCCESS(status)) {
10251 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10252 "%s: Failed to close VOSS Scheduler", __func__);
10253 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10254 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010255 vos_close(pVosContext );
10256
Amar Singhal0a402232013-10-11 20:57:16 -070010257err_vos_nv_close:
10258
c_hpothue6a36282014-03-19 12:27:38 +053010259#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010260 vos_nv_close();
10261
c_hpothu70f8d812014-03-22 22:59:23 +053010262#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010263
10264err_wdclose:
10265 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10266 vos_watchdog_close(pVosContext);
10267
Jeff Johnson295189b2012-06-20 16:38:30 -070010268err_config:
10269 kfree(pHddCtx->cfg_ini);
10270 pHddCtx->cfg_ini= NULL;
10271
10272err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010273 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010274 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010275 wiphy_free(wiphy) ;
10276 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010277 VOS_BUG(1);
10278
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010279 if (hdd_is_ssr_required())
10280 {
10281 /* WDI timeout had happened during load, so SSR is needed here */
10282 subsystem_restart("wcnss");
10283 msleep(5000);
10284 }
10285 hdd_set_ssr_required (VOS_FALSE);
10286
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010287 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010288
10289success:
10290 EXIT();
10291 return 0;
10292}
10293
10294/**---------------------------------------------------------------------------
10295
Jeff Johnson32d95a32012-09-10 13:15:23 -070010296 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010297
Jeff Johnson32d95a32012-09-10 13:15:23 -070010298 This is the driver entry point - called in different timeline depending
10299 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010300
10301 \param - None
10302
10303 \return - 0 for success, non zero for failure
10304
10305 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010306static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010307{
10308 VOS_STATUS status;
10309 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010310 struct device *dev = NULL;
10311 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010312#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10313 int max_retries = 0;
10314#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010315#ifdef HAVE_CBC_DONE
10316 int max_cbc_retries = 0;
10317#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010318
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010319#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10320 wlan_logging_sock_init_svc();
10321#endif
10322
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 ENTER();
10324
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010325 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010326
10327 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10328 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10329
Jeff Johnson295189b2012-06-20 16:38:30 -070010330#ifdef ANI_BUS_TYPE_PCI
10331
10332 dev = wcnss_wlan_get_device();
10333
10334#endif // ANI_BUS_TYPE_PCI
10335
10336#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010337
10338#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10339 /* wait until WCNSS driver downloads NV */
10340 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10341 msleep(1000);
10342 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010343
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010344 if (max_retries >= 5) {
10345 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010346 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010347#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10348 wlan_logging_sock_deinit_svc();
10349#endif
10350
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010351 return -ENODEV;
10352 }
10353#endif
10354
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010355#ifdef HAVE_CBC_DONE
10356 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10357 msleep(1000);
10358 }
10359 if (max_cbc_retries >= 10) {
10360 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10361 }
10362#endif
10363
Jeff Johnson295189b2012-06-20 16:38:30 -070010364 dev = wcnss_wlan_get_device();
10365#endif // ANI_BUS_TYPE_PLATFORM
10366
10367
10368 do {
10369 if (NULL == dev) {
10370 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10371 ret_status = -1;
10372 break;
10373 }
10374
Jeff Johnson295189b2012-06-20 16:38:30 -070010375#ifdef TIMER_MANAGER
10376 vos_timer_manager_init();
10377#endif
10378
10379 /* Preopen VOSS so that it is ready to start at least SAL */
10380 status = vos_preOpen(&pVosContext);
10381
10382 if (!VOS_IS_STATUS_SUCCESS(status))
10383 {
10384 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10385 ret_status = -1;
10386 break;
10387 }
10388
Sushant Kaushik02beb352015-06-04 15:15:01 +053010389 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010390#ifndef MODULE
10391 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10392 */
10393 hdd_set_conparam((v_UINT_t)con_mode);
10394#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010395
10396 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010397 if (hdd_wlan_startup(dev))
10398 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010399 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010400 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 vos_preClose( &pVosContext );
10402 ret_status = -1;
10403 break;
10404 }
10405
Jeff Johnson295189b2012-06-20 16:38:30 -070010406 } while (0);
10407
10408 if (0 != ret_status)
10409 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010410#ifdef TIMER_MANAGER
10411 vos_timer_exit();
10412#endif
10413#ifdef MEMORY_DEBUG
10414 vos_mem_exit();
10415#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010416 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010417#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10418 wlan_logging_sock_deinit_svc();
10419#endif
10420
Jeff Johnson295189b2012-06-20 16:38:30 -070010421 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10422 }
10423 else
10424 {
10425 //Send WLAN UP indication to Nlink Service
10426 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10427
10428 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010429 }
10430
10431 EXIT();
10432
10433 return ret_status;
10434}
10435
Jeff Johnson32d95a32012-09-10 13:15:23 -070010436/**---------------------------------------------------------------------------
10437
10438 \brief hdd_module_init() - Init Function
10439
10440 This is the driver entry point (invoked when module is loaded using insmod)
10441
10442 \param - None
10443
10444 \return - 0 for success, non zero for failure
10445
10446 --------------------------------------------------------------------------*/
10447#ifdef MODULE
10448static int __init hdd_module_init ( void)
10449{
10450 return hdd_driver_init();
10451}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010452#else /* #ifdef MODULE */
10453static int __init hdd_module_init ( void)
10454{
10455 /* Driver initialization is delayed to fwpath_changed_handler */
10456 return 0;
10457}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010458#endif /* #ifdef MODULE */
10459
Jeff Johnson295189b2012-06-20 16:38:30 -070010460
10461/**---------------------------------------------------------------------------
10462
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010463 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010464
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010465 This is the driver exit point (invoked when module is unloaded using rmmod
10466 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010467
10468 \param - None
10469
10470 \return - None
10471
10472 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010473static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010474{
10475 hdd_context_t *pHddCtx = NULL;
10476 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010477 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010478 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010479
10480 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10481
10482 //Get the global vos context
10483 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10484
10485 if(!pVosContext)
10486 {
10487 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10488 goto done;
10489 }
10490
10491 //Get the HDD context.
10492 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10493
10494 if(!pHddCtx)
10495 {
10496 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10497 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010498 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10499 {
10500 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10501 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10502 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10503 hdd_wlan_exit(pHddCtx);
10504 vos_preClose( &pVosContext );
10505 goto done;
10506 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010507 else
10508 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010509 /* We wait for active entry threads to exit from driver
10510 * by waiting until rtnl_lock is available.
10511 */
10512 rtnl_lock();
10513 rtnl_unlock();
10514
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010515 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10516 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10517 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10518 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010520 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010521 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10522 msecs_to_jiffies(30000));
10523 if(!rc)
10524 {
10525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10526 "%s:SSR timedout, fatal error", __func__);
10527 VOS_BUG(0);
10528 }
10529 }
10530
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010531 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10532 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010533
c_hpothu8adb97b2014-12-08 19:38:20 +053010534 /* Driver Need to send country code 00 in below condition
10535 * 1) If gCountryCodePriority is set to 1; and last country
10536 * code set is through 11d. This needs to be done in case
10537 * when NV country code is 00.
10538 * This Needs to be done as when kernel store last country
10539 * code and if stored country code is not through 11d,
10540 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10541 * in next load/unload as soon as we get any country through
10542 * 11d. In sme_HandleChangeCountryCodeByUser
10543 * pMsg->countryCode will be last countryCode and
10544 * pMac->scan.countryCode11d will be country through 11d so
10545 * due to mismatch driver will disable 11d.
10546 *
10547 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010548
c_hpothu8adb97b2014-12-08 19:38:20 +053010549 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010550 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010551 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010552 {
10553 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010554 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010555 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10556 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010557
c_hpothu8adb97b2014-12-08 19:38:20 +053010558 //Do all the cleanup before deregistering the driver
10559 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 }
10561
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 vos_preClose( &pVosContext );
10563
10564#ifdef TIMER_MANAGER
10565 vos_timer_exit();
10566#endif
10567#ifdef MEMORY_DEBUG
10568 vos_mem_exit();
10569#endif
10570
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010571#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10572 wlan_logging_sock_deinit_svc();
10573#endif
10574
Jeff Johnson295189b2012-06-20 16:38:30 -070010575done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010576 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010577
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10579}
10580
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010581/**---------------------------------------------------------------------------
10582
10583 \brief hdd_module_exit() - Exit function
10584
10585 This is the driver exit point (invoked when module is unloaded using rmmod)
10586
10587 \param - None
10588
10589 \return - None
10590
10591 --------------------------------------------------------------------------*/
10592static void __exit hdd_module_exit(void)
10593{
10594 hdd_driver_exit();
10595}
10596
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010597#ifdef MODULE
10598static int fwpath_changed_handler(const char *kmessage,
10599 struct kernel_param *kp)
10600{
Jeff Johnson76052702013-04-16 13:55:05 -070010601 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010602}
10603
10604static int con_mode_handler(const char *kmessage,
10605 struct kernel_param *kp)
10606{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010607 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010608}
10609#else /* #ifdef MODULE */
10610/**---------------------------------------------------------------------------
10611
Jeff Johnson76052702013-04-16 13:55:05 -070010612 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010613
Jeff Johnson76052702013-04-16 13:55:05 -070010614 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010615 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010616 - invoked when module parameter fwpath is modified from userspace to signal
10617 initializing the WLAN driver or when con_mode is modified from userspace
10618 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010619
10620 \return - 0 for success, non zero for failure
10621
10622 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010623static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010624{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010625 int ret_status;
10626
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010627 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010628 ret_status = hdd_driver_init();
10629 wlan_hdd_inited = ret_status ? 0 : 1;
10630 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010631 }
10632
10633 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010634
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010635 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010636
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010637 ret_status = hdd_driver_init();
10638 wlan_hdd_inited = ret_status ? 0 : 1;
10639 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010640}
10641
Jeff Johnson295189b2012-06-20 16:38:30 -070010642/**---------------------------------------------------------------------------
10643
Jeff Johnson76052702013-04-16 13:55:05 -070010644 \brief fwpath_changed_handler() - Handler Function
10645
10646 Handle changes to the fwpath parameter
10647
10648 \return - 0 for success, non zero for failure
10649
10650 --------------------------------------------------------------------------*/
10651static int fwpath_changed_handler(const char *kmessage,
10652 struct kernel_param *kp)
10653{
10654 int ret;
10655
10656 ret = param_set_copystring(kmessage, kp);
10657 if (0 == ret)
10658 ret = kickstart_driver();
10659 return ret;
10660}
10661
10662/**---------------------------------------------------------------------------
10663
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010664 \brief con_mode_handler() -
10665
10666 Handler function for module param con_mode when it is changed by userspace
10667 Dynamically linked - do nothing
10668 Statically linked - exit and init driver, as in rmmod and insmod
10669
Jeff Johnson76052702013-04-16 13:55:05 -070010670 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010671
Jeff Johnson76052702013-04-16 13:55:05 -070010672 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010673
10674 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010675static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010676{
Jeff Johnson76052702013-04-16 13:55:05 -070010677 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010678
Jeff Johnson76052702013-04-16 13:55:05 -070010679 ret = param_set_int(kmessage, kp);
10680 if (0 == ret)
10681 ret = kickstart_driver();
10682 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010683}
10684#endif /* #ifdef MODULE */
10685
10686/**---------------------------------------------------------------------------
10687
Jeff Johnson295189b2012-06-20 16:38:30 -070010688 \brief hdd_get_conparam() -
10689
10690 This is the driver exit point (invoked when module is unloaded using rmmod)
10691
10692 \param - None
10693
10694 \return - tVOS_CON_MODE
10695
10696 --------------------------------------------------------------------------*/
10697tVOS_CON_MODE hdd_get_conparam ( void )
10698{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010699#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010700 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010701#else
10702 return (tVOS_CON_MODE)curr_con_mode;
10703#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010704}
10705void hdd_set_conparam ( v_UINT_t newParam )
10706{
10707 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010708#ifndef MODULE
10709 curr_con_mode = con_mode;
10710#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010711}
10712/**---------------------------------------------------------------------------
10713
10714 \brief hdd_softap_sta_deauth() - function
10715
10716 This to take counter measure to handle deauth req from HDD
10717
10718 \param - pAdapter - Pointer to the HDD
10719
10720 \param - enable - boolean value
10721
10722 \return - None
10723
10724 --------------------------------------------------------------------------*/
10725
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010726VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10727 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010728{
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010730 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010731
10732 ENTER();
10733
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010734 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10735 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010736
10737 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010738 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010739 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010740
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010741 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010742
10743 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010744 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010745}
10746
10747/**---------------------------------------------------------------------------
10748
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010749 \brief hdd_del_all_sta() - function
10750
10751 This function removes all the stations associated on stopping AP/P2P GO.
10752
10753 \param - pAdapter - Pointer to the HDD
10754
10755 \return - None
10756
10757 --------------------------------------------------------------------------*/
10758
10759int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10760{
10761 v_U16_t i;
10762 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010763 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10764 ptSapContext pSapCtx = NULL;
10765 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10766 if(pSapCtx == NULL){
10767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10768 FL("psapCtx is NULL"));
10769 return 1;
10770 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010771 ENTER();
10772
10773 hddLog(VOS_TRACE_LEVEL_INFO,
10774 "%s: Delete all STAs associated.",__func__);
10775 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10776 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10777 )
10778 {
10779 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10780 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010781 if ((pSapCtx->aStaInfo[i].isUsed) &&
10782 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010783 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010784 struct tagCsrDelStaParams delStaParams;
10785
10786 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010787 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010788 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10789 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010790 &delStaParams);
10791 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010792 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010793 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010794 }
10795 }
10796 }
10797
10798 EXIT();
10799 return 0;
10800}
10801
10802/**---------------------------------------------------------------------------
10803
Jeff Johnson295189b2012-06-20 16:38:30 -070010804 \brief hdd_softap_sta_disassoc() - function
10805
10806 This to take counter measure to handle deauth req from HDD
10807
10808 \param - pAdapter - Pointer to the HDD
10809
10810 \param - enable - boolean value
10811
10812 \return - None
10813
10814 --------------------------------------------------------------------------*/
10815
10816void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10817{
10818 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10819
10820 ENTER();
10821
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010822 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010823
10824 //Ignore request to disassoc bcmc station
10825 if( pDestMacAddress[0] & 0x1 )
10826 return;
10827
10828 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10829}
10830
10831void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10832{
10833 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10834
10835 ENTER();
10836
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010837 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010838
10839 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10840}
10841
Jeff Johnson295189b2012-06-20 16:38:30 -070010842/**---------------------------------------------------------------------------
10843 *
10844 * \brief hdd_get__concurrency_mode() -
10845 *
10846 *
10847 * \param - None
10848 *
10849 * \return - CONCURRENCY MODE
10850 *
10851 * --------------------------------------------------------------------------*/
10852tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10853{
10854 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10855 hdd_context_t *pHddCtx;
10856
10857 if (NULL != pVosContext)
10858 {
10859 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10860 if (NULL != pHddCtx)
10861 {
10862 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10863 }
10864 }
10865
10866 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010867 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010868 return VOS_STA;
10869}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010870v_BOOL_t
10871wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10872{
10873 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010874
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010875 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10876 if (pAdapter == NULL)
10877 {
10878 hddLog(VOS_TRACE_LEVEL_INFO,
10879 FL("GO doesn't exist"));
10880 return TRUE;
10881 }
10882 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10883 {
10884 hddLog(VOS_TRACE_LEVEL_INFO,
10885 FL("GO started"));
10886 return TRUE;
10887 }
10888 else
10889 /* wait till GO changes its interface to p2p device */
10890 hddLog(VOS_TRACE_LEVEL_INFO,
10891 FL("Del_bss called, avoid apps suspend"));
10892 return FALSE;
10893
10894}
Jeff Johnson295189b2012-06-20 16:38:30 -070010895/* Decide whether to allow/not the apps power collapse.
10896 * Allow apps power collapse if we are in connected state.
10897 * if not, allow only if we are in IMPS */
10898v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10899{
10900 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010901 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010902 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010903 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10904 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10905 hdd_adapter_t *pAdapter = NULL;
10906 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010907 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010908
Jeff Johnson295189b2012-06-20 16:38:30 -070010909 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10910 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010911
Yathish9f22e662012-12-10 14:21:35 -080010912 concurrent_state = hdd_get_concurrency_mode();
10913
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010914 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10915 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10916 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010917#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010918
Yathish9f22e662012-12-10 14:21:35 -080010919 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010920 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010921 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10922 return TRUE;
10923#endif
10924
Jeff Johnson295189b2012-06-20 16:38:30 -070010925 /*loop through all adapters. TBD fix for Concurrency */
10926 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10927 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10928 {
10929 pAdapter = pAdapterNode->pAdapter;
10930 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10931 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10932 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010933 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010934 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010935 && pmcState != STOPPED && pmcState != STANDBY &&
10936 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010937 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10938 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010939 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010940 if(pmcState == FULL_POWER &&
10941 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10942 {
10943 /*
10944 * When SCO indication comes from Coex module , host will
10945 * enter in to full power mode, but this should not prevent
10946 * apps processor power collapse.
10947 */
10948 hddLog(LOG1,
10949 FL("Allow apps power collapse"
10950 "even when sco indication is set"));
10951 return TRUE;
10952 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010953 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010954 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10955 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010956 return FALSE;
10957 }
10958 }
10959 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10960 pAdapterNode = pNext;
10961 }
10962 return TRUE;
10963}
10964
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010965/* Decides whether to send suspend notification to Riva
10966 * if any adapter is in BMPS; then it is required */
10967v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10968{
10969 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10970 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10971
10972 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10973 {
10974 return TRUE;
10975 }
10976 return FALSE;
10977}
10978
Jeff Johnson295189b2012-06-20 16:38:30 -070010979void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10980{
10981 switch(mode)
10982 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010983 case VOS_STA_MODE:
10984 case VOS_P2P_CLIENT_MODE:
10985 case VOS_P2P_GO_MODE:
10986 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010987 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010988 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010989 break;
10990 default:
10991 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010992 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010993 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10994 "Number of open sessions for mode %d = %d"),
10995 pHddCtx->concurrency_mode, mode,
10996 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010997}
10998
10999
11000void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11001{
11002 switch(mode)
11003 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011004 case VOS_STA_MODE:
11005 case VOS_P2P_CLIENT_MODE:
11006 case VOS_P2P_GO_MODE:
11007 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011008 pHddCtx->no_of_open_sessions[mode]--;
11009 if (!(pHddCtx->no_of_open_sessions[mode]))
11010 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011011 break;
11012 default:
11013 break;
11014 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011015 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11016 "Number of open sessions for mode %d = %d"),
11017 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11018
11019}
11020/**---------------------------------------------------------------------------
11021 *
11022 * \brief wlan_hdd_incr_active_session()
11023 *
11024 * This function increments the number of active sessions
11025 * maintained per device mode
11026 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11027 * Incase of SAP/P2P GO upon bss start it is incremented
11028 *
11029 * \param pHddCtx - HDD Context
11030 * \param mode - device mode
11031 *
11032 * \return - None
11033 *
11034 * --------------------------------------------------------------------------*/
11035void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11036{
11037 switch (mode) {
11038 case VOS_STA_MODE:
11039 case VOS_P2P_CLIENT_MODE:
11040 case VOS_P2P_GO_MODE:
11041 case VOS_STA_SAP_MODE:
11042 pHddCtx->no_of_active_sessions[mode]++;
11043 break;
11044 default:
11045 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11046 break;
11047 }
11048 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11049 mode,
11050 pHddCtx->no_of_active_sessions[mode]);
11051}
11052
11053/**---------------------------------------------------------------------------
11054 *
11055 * \brief wlan_hdd_decr_active_session()
11056 *
11057 * This function decrements the number of active sessions
11058 * maintained per device mode
11059 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11060 * Incase of SAP/P2P GO upon bss stop it is decremented
11061 *
11062 * \param pHddCtx - HDD Context
11063 * \param mode - device mode
11064 *
11065 * \return - None
11066 *
11067 * --------------------------------------------------------------------------*/
11068void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11069{
11070 switch (mode) {
11071 case VOS_STA_MODE:
11072 case VOS_P2P_CLIENT_MODE:
11073 case VOS_P2P_GO_MODE:
11074 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011075 if (pHddCtx->no_of_active_sessions[mode] > 0)
11076 pHddCtx->no_of_active_sessions[mode]--;
11077 else
11078 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11079 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011080 break;
11081 default:
11082 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11083 break;
11084 }
11085 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11086 mode,
11087 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011088}
11089
Jeff Johnsone7245742012-09-05 17:12:55 -070011090/**---------------------------------------------------------------------------
11091 *
11092 * \brief wlan_hdd_restart_init
11093 *
11094 * This function initalizes restart timer/flag. An internal function.
11095 *
11096 * \param - pHddCtx
11097 *
11098 * \return - None
11099 *
11100 * --------------------------------------------------------------------------*/
11101
11102static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11103{
11104 /* Initialize */
11105 pHddCtx->hdd_restart_retries = 0;
11106 atomic_set(&pHddCtx->isRestartInProgress, 0);
11107 vos_timer_init(&pHddCtx->hdd_restart_timer,
11108 VOS_TIMER_TYPE_SW,
11109 wlan_hdd_restart_timer_cb,
11110 pHddCtx);
11111}
11112/**---------------------------------------------------------------------------
11113 *
11114 * \brief wlan_hdd_restart_deinit
11115 *
11116 * This function cleans up the resources used. An internal function.
11117 *
11118 * \param - pHddCtx
11119 *
11120 * \return - None
11121 *
11122 * --------------------------------------------------------------------------*/
11123
11124static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11125{
11126
11127 VOS_STATUS vos_status;
11128 /* Block any further calls */
11129 atomic_set(&pHddCtx->isRestartInProgress, 1);
11130 /* Cleanup */
11131 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11132 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011133 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011134 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11135 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011136 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011137
11138}
11139
11140/**---------------------------------------------------------------------------
11141 *
11142 * \brief wlan_hdd_framework_restart
11143 *
11144 * This function uses a cfg80211 API to start a framework initiated WLAN
11145 * driver module unload/load.
11146 *
11147 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11148 *
11149 *
11150 * \param - pHddCtx
11151 *
11152 * \return - VOS_STATUS_SUCCESS: Success
11153 * VOS_STATUS_E_EMPTY: Adapter is Empty
11154 * VOS_STATUS_E_NOMEM: No memory
11155
11156 * --------------------------------------------------------------------------*/
11157
11158static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11159{
11160 VOS_STATUS status = VOS_STATUS_SUCCESS;
11161 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011162 int len = (sizeof (struct ieee80211_mgmt));
11163 struct ieee80211_mgmt *mgmt = NULL;
11164
11165 /* Prepare the DEAUTH managment frame with reason code */
11166 mgmt = kzalloc(len, GFP_KERNEL);
11167 if(mgmt == NULL)
11168 {
11169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11170 "%s: memory allocation failed (%d bytes)", __func__, len);
11171 return VOS_STATUS_E_NOMEM;
11172 }
11173 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011174
11175 /* Iterate over all adapters/devices */
11176 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011177 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11178 {
11179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11180 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11181 goto end;
11182 }
11183
Jeff Johnsone7245742012-09-05 17:12:55 -070011184 do
11185 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011186 if(pAdapterNode->pAdapter &&
11187 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011188 {
11189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11190 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11191 pAdapterNode->pAdapter->dev->name,
11192 pAdapterNode->pAdapter->device_mode,
11193 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011194 /*
11195 * CFG80211 event to restart the driver
11196 *
11197 * 'cfg80211_send_unprot_deauth' sends a
11198 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11199 * of SME(Linux Kernel) state machine.
11200 *
11201 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11202 * the driver.
11203 *
11204 */
11205
11206 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011207 }
11208 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11209 pAdapterNode = pNext;
11210 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11211
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011212 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011213 /* Free the allocated management frame */
11214 kfree(mgmt);
11215
Jeff Johnsone7245742012-09-05 17:12:55 -070011216 /* Retry until we unload or reach max count */
11217 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11218 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11219
11220 return status;
11221
11222}
11223/**---------------------------------------------------------------------------
11224 *
11225 * \brief wlan_hdd_restart_timer_cb
11226 *
11227 * Restart timer callback. An internal function.
11228 *
11229 * \param - User data:
11230 *
11231 * \return - None
11232 *
11233 * --------------------------------------------------------------------------*/
11234
11235void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11236{
11237 hdd_context_t *pHddCtx = usrDataForCallback;
11238 wlan_hdd_framework_restart(pHddCtx);
11239 return;
11240
11241}
11242
11243
11244/**---------------------------------------------------------------------------
11245 *
11246 * \brief wlan_hdd_restart_driver
11247 *
11248 * This function sends an event to supplicant to restart the WLAN driver.
11249 *
11250 * This function is called from vos_wlanRestart.
11251 *
11252 * \param - pHddCtx
11253 *
11254 * \return - VOS_STATUS_SUCCESS: Success
11255 * VOS_STATUS_E_EMPTY: Adapter is Empty
11256 * VOS_STATUS_E_ALREADY: Request already in progress
11257
11258 * --------------------------------------------------------------------------*/
11259VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11260{
11261 VOS_STATUS status = VOS_STATUS_SUCCESS;
11262
11263 /* A tight check to make sure reentrancy */
11264 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11265 {
Mihir Shetefd528652014-06-23 19:07:50 +053011266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011267 "%s: WLAN restart is already in progress", __func__);
11268
11269 return VOS_STATUS_E_ALREADY;
11270 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011271 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011272#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011273 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011274#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011275
Jeff Johnsone7245742012-09-05 17:12:55 -070011276 return status;
11277}
11278
Mihir Shetee1093ba2014-01-21 20:13:32 +053011279/**---------------------------------------------------------------------------
11280 *
11281 * \brief wlan_hdd_init_channels
11282 *
11283 * This function is used to initialize the channel list in CSR
11284 *
11285 * This function is called from hdd_wlan_startup
11286 *
11287 * \param - pHddCtx: HDD context
11288 *
11289 * \return - VOS_STATUS_SUCCESS: Success
11290 * VOS_STATUS_E_FAULT: Failure reported by SME
11291
11292 * --------------------------------------------------------------------------*/
11293static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11294{
11295 eHalStatus status;
11296
11297 status = sme_InitChannels(pHddCtx->hHal);
11298 if (HAL_STATUS_SUCCESS(status))
11299 {
11300 return VOS_STATUS_SUCCESS;
11301 }
11302 else
11303 {
11304 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11305 __func__, status);
11306 return VOS_STATUS_E_FAULT;
11307 }
11308}
11309
Mihir Shete04206452014-11-20 17:50:58 +053011310#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011311VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011312{
11313 eHalStatus status;
11314
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011315 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011316 if (HAL_STATUS_SUCCESS(status))
11317 {
11318 return VOS_STATUS_SUCCESS;
11319 }
11320 else
11321 {
11322 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11323 __func__, status);
11324 return VOS_STATUS_E_FAULT;
11325 }
11326}
Mihir Shete04206452014-11-20 17:50:58 +053011327#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011328/*
11329 * API to find if there is any STA or P2P-Client is connected
11330 */
11331VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11332{
11333 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11334}
Jeff Johnsone7245742012-09-05 17:12:55 -070011335
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011336
11337/*
11338 * API to find if the firmware will send logs using DXE channel
11339 */
11340v_U8_t hdd_is_fw_logging_enabled(void)
11341{
11342 hdd_context_t *pHddCtx;
11343
11344 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11345 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11346
Sachin Ahuja084313e2015-05-21 17:57:10 +053011347 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011348}
11349
Agarwal Ashish57e84372014-12-05 18:26:53 +053011350/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011351 * API to find if the firmware will send trace logs using DXE channel
11352 */
11353v_U8_t hdd_is_fw_ev_logging_enabled(void)
11354{
11355 hdd_context_t *pHddCtx;
11356
11357 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11358 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11359
11360 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11361}
11362/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011363 * API to find if there is any session connected
11364 */
11365VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11366{
11367 return sme_is_any_session_connected(pHddCtx->hHal);
11368}
11369
11370
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011371int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11372{
11373 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11374 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011375 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011376 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011377
11378 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011379 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011380 if (pScanInfo->mScanPending)
11381 {
c_hpothua3d45d52015-01-05 14:11:17 +053011382 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11383 eCSR_SCAN_ABORT_DEFAULT);
11384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11385 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011386
c_hpothua3d45d52015-01-05 14:11:17 +053011387 /* If there is active scan command lets wait for the completion else
11388 * there is no need to wait as scan command might be in the SME pending
11389 * command list.
11390 */
11391 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11392 {
c_hpothua3d45d52015-01-05 14:11:17 +053011393 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011394 &pScanInfo->abortscan_event_var,
11395 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011396 if (0 >= status)
11397 {
11398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011399 "%s: Timeout or Interrupt occurred while waiting for abort"
11400 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011401 return -ETIMEDOUT;
11402 }
11403 }
11404 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11405 {
11406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11407 FL("hdd_abort_mac_scan failed"));
11408 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011409 }
11410 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011411 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011412}
11413
c_hpothu225aa7c2014-10-22 17:45:13 +053011414VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11415{
11416 hdd_adapter_t *pAdapter;
11417 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11418 VOS_STATUS vosStatus;
11419
11420 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11421 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11422 {
11423 pAdapter = pAdapterNode->pAdapter;
11424 if (NULL != pAdapter)
11425 {
11426 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11427 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11428 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11429 {
11430 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11431 pAdapter->device_mode);
11432 if (VOS_STATUS_SUCCESS !=
11433 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11434 {
11435 hddLog(LOGE, FL("failed to abort ROC"));
11436 return VOS_STATUS_E_FAILURE;
11437 }
11438 }
11439 }
11440 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11441 pAdapterNode = pNext;
11442 }
11443 return VOS_STATUS_SUCCESS;
11444}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011445
Mihir Shete0be28772015-02-17 18:42:14 +053011446hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11447{
11448 hdd_adapter_t *pAdapter;
11449 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11450 hdd_cfg80211_state_t *cfgState;
11451 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11452 VOS_STATUS vosStatus;
11453
11454 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11455 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11456 {
11457 pAdapter = pAdapterNode->pAdapter;
11458 if (NULL != pAdapter)
11459 {
11460 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11461 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11462 if (pRemainChanCtx)
11463 break;
11464 }
11465 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11466 pAdapterNode = pNext;
11467 }
11468 return pRemainChanCtx;
11469}
11470
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011471/**
11472 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11473 *
11474 * @pHddCtx: HDD context within host driver
11475 * @dfsScanMode: dfsScanMode passed from ioctl
11476 *
11477 */
11478
11479VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11480 tANI_U8 dfsScanMode)
11481{
11482 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11483 hdd_adapter_t *pAdapter;
11484 VOS_STATUS vosStatus;
11485 hdd_station_ctx_t *pHddStaCtx;
11486 eHalStatus status = eHAL_STATUS_SUCCESS;
11487
11488 if(!pHddCtx)
11489 {
11490 hddLog(LOGE, FL("HDD context is Null"));
11491 return eHAL_STATUS_FAILURE;
11492 }
11493
11494 if (pHddCtx->scan_info.mScanPending)
11495 {
11496 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11497 pHddCtx->scan_info.sessionId);
11498 hdd_abort_mac_scan(pHddCtx,
11499 pHddCtx->scan_info.sessionId,
11500 eCSR_SCAN_ABORT_DEFAULT);
11501 }
11502
11503 if (!dfsScanMode)
11504 {
11505 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11506 while ((NULL != pAdapterNode) &&
11507 (VOS_STATUS_SUCCESS == vosStatus))
11508 {
11509 pAdapter = pAdapterNode->pAdapter;
11510
11511 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11512 {
11513 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11514
11515 if(!pHddStaCtx)
11516 {
11517 hddLog(LOGE, FL("HDD STA context is Null"));
11518 return eHAL_STATUS_FAILURE;
11519 }
11520
11521 /* if STA is already connected on DFS channel,
11522 disconnect immediately*/
11523 if (hdd_connIsConnected(pHddStaCtx) &&
11524 (NV_CHANNEL_DFS ==
11525 vos_nv_getChannelEnabledState(
11526 pHddStaCtx->conn_info.operationChannel)))
11527 {
11528 status = sme_RoamDisconnect(pHddCtx->hHal,
11529 pAdapter->sessionId,
11530 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11531 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11532 "sme_RoamDisconnect returned with status: %d"
11533 "for sessionid: %d"), pHddStaCtx->conn_info.
11534 operationChannel, status, pAdapter->sessionId);
11535 }
11536 }
11537
11538 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11539 &pNext);
11540 pAdapterNode = pNext;
11541 }
11542 }
11543
11544 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11545 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11546 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11547
11548 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11549 if (!HAL_STATUS_SUCCESS(status))
11550 {
11551 hddLog(LOGE,
11552 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11553 return status;
11554 }
11555
11556 return status;
11557}
11558
Nirav Shah7e3c8132015-06-22 23:51:42 +053011559static int hdd_log2_ceil(unsigned value)
11560{
11561 /* need to switch to unsigned math so that negative values
11562 * will right-shift towards 0 instead of -1
11563 */
11564 unsigned tmp = value;
11565 int log2 = -1;
11566
11567 if (value == 0)
11568 return 0;
11569
11570 while (tmp) {
11571 log2++;
11572 tmp >>= 1;
11573 }
11574 if (1U << log2 != value)
11575 log2++;
11576
11577 return log2;
11578}
11579
11580/**
11581 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11582 * @pAdapter: adapter handle
11583 *
11584 * Return: vos status
11585 */
11586VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11587{
11588 int hash_elem, log2, i;
11589
11590 spin_lock_bh( &pAdapter->sta_hash_lock);
11591 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11592 spin_unlock_bh( &pAdapter->sta_hash_lock);
11593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11594 "%s: hash already attached for session id %d",
11595 __func__, pAdapter->sessionId);
11596 return VOS_STATUS_SUCCESS;
11597 }
11598 spin_unlock_bh( &pAdapter->sta_hash_lock);
11599
11600 hash_elem = WLAN_MAX_STA_COUNT;
11601 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11602 log2 = hdd_log2_ceil(hash_elem);
11603 hash_elem = 1 << log2;
11604
11605 pAdapter->sta_id_hash.mask = hash_elem - 1;
11606 pAdapter->sta_id_hash.idx_bits = log2;
11607 pAdapter->sta_id_hash.bins =
11608 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11609 if (!pAdapter->sta_id_hash.bins) {
11610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11611 "%s: malloc failed for session %d",
11612 __func__, pAdapter->sessionId);
11613 return VOS_STATUS_E_NOMEM;
11614 }
11615
11616 for (i = 0; i < hash_elem; i++)
11617 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11618
11619 spin_lock_bh( &pAdapter->sta_hash_lock);
11620 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11621 spin_unlock_bh( &pAdapter->sta_hash_lock);
11622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11623 "%s: Station ID Hash attached for session id %d",
11624 __func__, pAdapter->sessionId);
11625
11626 return VOS_STATUS_SUCCESS;
11627}
11628
11629/**
11630 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11631 * @pAdapter: adapter handle
11632 *
11633 * Return: vos status
11634 */
11635VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11636{
11637 int hash_elem, i;
11638 v_SIZE_t size;
11639
11640 spin_lock_bh( &pAdapter->sta_hash_lock);
11641 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11642 spin_unlock_bh( &pAdapter->sta_hash_lock);
11643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11644 "%s: hash not initialized for session id %d",
11645 __func__, pAdapter->sessionId);
11646 return VOS_STATUS_SUCCESS;
11647 }
11648
11649 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11650 spin_unlock_bh( &pAdapter->sta_hash_lock);
11651
11652 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11653
11654 /* free all station info*/
11655 for (i = 0; i < hash_elem; i++) {
11656 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11657 if (size != 0) {
11658 VOS_STATUS status;
11659 hdd_staid_hash_node_t *sta_info_node = NULL;
11660 hdd_staid_hash_node_t *next_node = NULL;
11661 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11662 (hdd_list_node_t**) &sta_info_node );
11663
11664 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11665 {
11666 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11667 &sta_info_node->node);
11668 vos_mem_free(sta_info_node);
11669
11670 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11671 (hdd_list_node_t*)sta_info_node,
11672 (hdd_list_node_t**)&next_node);
11673 sta_info_node = next_node;
11674 }
11675 }
11676 }
11677
11678 vos_mem_free(pAdapter->sta_id_hash.bins);
11679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11680 "%s: Station ID Hash detached for session id %d",
11681 __func__, pAdapter->sessionId);
11682 return VOS_STATUS_SUCCESS;
11683}
11684
11685/**
11686 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11687 * @pAdapter: adapter handle
11688 * @mac_addr_in: input mac address
11689 *
11690 * Return: index derived from mac address
11691 */
11692int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11693 v_MACADDR_t *mac_addr_in)
11694{
11695 uint16 index;
11696 struct hdd_align_mac_addr_t * mac_addr =
11697 (struct hdd_align_mac_addr_t *)mac_addr_in;
11698
11699 index = mac_addr->bytes_ab ^
11700 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11701 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11702 index &= pAdapter->sta_id_hash.mask;
11703 return index;
11704}
11705
11706/**
11707 * hdd_sta_id_hash_add_entry() - add entry in hash
11708 * @pAdapter: adapter handle
11709 * @sta_id: station id
11710 * @mac_addr: mac address
11711 *
11712 * Return: vos status
11713 */
11714VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11715 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11716{
11717 uint16 index;
11718 hdd_staid_hash_node_t *sta_info_node = NULL;
11719
11720 spin_lock_bh( &pAdapter->sta_hash_lock);
11721 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11722 spin_unlock_bh( &pAdapter->sta_hash_lock);
11723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11724 "%s: hash is not initialized for session id %d",
11725 __func__, pAdapter->sessionId);
11726 return VOS_STATUS_E_FAILURE;
11727 }
11728
11729 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11730 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11731 if (!sta_info_node) {
11732 spin_unlock_bh( &pAdapter->sta_hash_lock);
11733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11734 "%s: malloc failed", __func__);
11735 return VOS_STATUS_E_NOMEM;
11736 }
11737
11738 sta_info_node->sta_id = sta_id;
11739 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11740
11741 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11742 (hdd_list_node_t*) sta_info_node );
11743 spin_unlock_bh( &pAdapter->sta_hash_lock);
11744 return VOS_STATUS_SUCCESS;
11745}
11746
11747/**
11748 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11749 * @pAdapter: adapter handle
11750 * @sta_id: station id
11751 * @mac_addr: mac address
11752 *
11753 * Return: vos status
11754 */
11755VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11756 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11757{
11758 uint16 index;
11759 VOS_STATUS status;
11760 hdd_staid_hash_node_t *sta_info_node = NULL;
11761 hdd_staid_hash_node_t *next_node = NULL;
11762
11763 spin_lock_bh( &pAdapter->sta_hash_lock);
11764 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11765 spin_unlock_bh( &pAdapter->sta_hash_lock);
11766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11767 "%s: hash is not initialized for session id %d",
11768 __func__, pAdapter->sessionId);
11769 return VOS_STATUS_E_FAILURE;
11770 }
11771
11772 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11773 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11774 (hdd_list_node_t**) &sta_info_node );
11775
11776 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11777 {
11778 if (sta_info_node->sta_id == sta_id) {
11779 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11780 &sta_info_node->node);
11781 vos_mem_free(sta_info_node);
11782 break;
11783 }
11784 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11785 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11786 sta_info_node = next_node;
11787 }
11788 spin_unlock_bh( &pAdapter->sta_hash_lock);
11789 return status;
11790}
11791
11792/**
11793 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11794 * @pAdapter: adapter handle
11795 * @mac_addr_in: mac address
11796 *
11797 * Return: station id
11798 */
11799int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11800 v_MACADDR_t *mac_addr_in)
11801{
11802 uint8 is_found = 0;
11803 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11804 uint16 index;
11805 VOS_STATUS status;
11806 hdd_staid_hash_node_t *sta_info_node = NULL;
11807 hdd_staid_hash_node_t *next_node = NULL;
11808
11809 spin_lock_bh( &pAdapter->sta_hash_lock);
11810 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11811 spin_unlock_bh( &pAdapter->sta_hash_lock);
11812 hddLog(VOS_TRACE_LEVEL_ERROR,
11813 FL("hash is not initialized for session id %d"),
11814 pAdapter->sessionId);
11815 return HDD_WLAN_INVALID_STA_ID;
11816 }
11817
11818 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11819 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11820 (hdd_list_node_t**) &sta_info_node );
11821
11822 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11823 {
11824 if (vos_mem_compare(&sta_info_node->mac_addr,
11825 mac_addr_in, sizeof(v_MACADDR_t))) {
11826 is_found = 1;
11827 sta_id = sta_info_node->sta_id;
11828 break;
11829 }
11830 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11831 (hdd_list_node_t*)sta_info_node,
11832 (hdd_list_node_t**)&next_node);
11833 sta_info_node = next_node;
11834 }
11835 spin_unlock_bh( &pAdapter->sta_hash_lock);
11836 return sta_id;
11837}
11838
Jeff Johnson295189b2012-06-20 16:38:30 -070011839//Register the module init/exit functions
11840module_init(hdd_module_init);
11841module_exit(hdd_module_exit);
11842
11843MODULE_LICENSE("Dual BSD/GPL");
11844MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11845MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11846
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011847module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11848 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011849
Jeff Johnson76052702013-04-16 13:55:05 -070011850module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011851 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011852
11853module_param(enable_dfs_chan_scan, int,
11854 S_IRUSR | S_IRGRP | S_IROTH);
11855
11856module_param(enable_11d, int,
11857 S_IRUSR | S_IRGRP | S_IROTH);
11858
11859module_param(country_code, charp,
11860 S_IRUSR | S_IRGRP | S_IROTH);