blob: f562e54cad2b4f306cff7dad5a2f19b7a7a3bd96 [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 */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05302531 len = VOS_MIN(priv_data.total_len, len + 1);
2532 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002533 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 */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05302593 len = VOS_MIN(priv_data.total_len, len + 1);
2594 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002595 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);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05302669 len = VOS_MIN(priv_data.total_len, len + 1);
2670 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002671 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);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05302730 len = VOS_MIN(priv_data.total_len, len + 1);
2731 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002732 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);
Ratnam Rachuri52139592015-07-17 13:17:29 +05302751 len = VOS_MIN(priv_data.total_len, len + 1);
2752 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08002753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 "%s: failed to copy data to user buffer", __func__);
2755 ret = -EFAULT;
2756 goto exit;
2757 }
2758 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002759 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2760 {
2761 tANI_U8 *value = command;
2762 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2763 tANI_U8 numChannels = 0;
2764 eHalStatus status = eHAL_STATUS_SUCCESS;
2765
2766 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2767 if (eHAL_STATUS_SUCCESS != status)
2768 {
2769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2770 "%s: Failed to parse channel list information", __func__);
2771 ret = -EINVAL;
2772 goto exit;
2773 }
2774
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302775 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2776 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2777 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002778 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2782 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2783 ret = -EINVAL;
2784 goto exit;
2785 }
2786 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2787 numChannels);
2788 if (eHAL_STATUS_SUCCESS != status)
2789 {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s: Failed to update channel list information", __func__);
2792 ret = -EINVAL;
2793 goto exit;
2794 }
2795 }
2796 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2797 {
2798 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2799 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002800 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002801 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002802 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002803
2804 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2805 ChannelList, &numChannels ))
2806 {
2807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2808 "%s: failed to get roam scan channel list", __func__);
2809 ret = -EFAULT;
2810 goto exit;
2811 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302812 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2813 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2814 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002815 /* output channel list is of the format
2816 [Number of roam scan channels][Channel1][Channel2]... */
2817 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002818 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002819 for (j = 0; (j < numChannels); j++)
2820 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002821 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2822 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002823 }
2824
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05302825 len = VOS_MIN(priv_data.total_len, len + 1);
2826 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002827 {
2828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2829 "%s: failed to copy data to user buffer", __func__);
2830 ret = -EFAULT;
2831 goto exit;
2832 }
2833 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002834 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2835 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002836 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002837 char extra[32];
2838 tANI_U8 len = 0;
2839
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002840 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002841 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002842 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002843 hdd_is_okc_mode_enabled(pHddCtx) &&
2844 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2845 {
2846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002847 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002848 " hence this operation is not permitted!", __func__);
2849 ret = -EPERM;
2850 goto exit;
2851 }
2852
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002853 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002854 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05302855 len = VOS_MIN(priv_data.total_len, len + 1);
2856 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002857 {
2858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2859 "%s: failed to copy data to user buffer", __func__);
2860 ret = -EFAULT;
2861 goto exit;
2862 }
2863 }
2864 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2865 {
2866 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2867 char extra[32];
2868 tANI_U8 len = 0;
2869
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002870 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002871 then this operation is not permitted (return FAILURE) */
2872 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002873 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002874 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2875 {
2876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002877 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002878 " hence this operation is not permitted!", __func__);
2879 ret = -EPERM;
2880 goto exit;
2881 }
2882
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002883 len = scnprintf(extra, sizeof(extra), "%s %d",
2884 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05302885 len = VOS_MIN(priv_data.total_len, len + 1);
2886 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002887 {
2888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2889 "%s: failed to copy data to user buffer", __func__);
2890 ret = -EFAULT;
2891 goto exit;
2892 }
2893 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002894 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002895 {
2896 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2897 char extra[32];
2898 tANI_U8 len = 0;
2899
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002900 len = scnprintf(extra, sizeof(extra), "%s %d",
2901 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05302902 len = VOS_MIN(priv_data.total_len, len + 1);
2903 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002904 {
2905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2906 "%s: failed to copy data to user buffer", __func__);
2907 ret = -EFAULT;
2908 goto exit;
2909 }
2910 }
2911 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2912 {
2913 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2914 char extra[32];
2915 tANI_U8 len = 0;
2916
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002917 len = scnprintf(extra, sizeof(extra), "%s %d",
2918 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05302919 len = VOS_MIN(priv_data.total_len, len + 1);
2920 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002921 {
2922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2923 "%s: failed to copy data to user buffer", __func__);
2924 ret = -EFAULT;
2925 goto exit;
2926 }
2927 }
2928 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2929 {
2930 tANI_U8 *value = command;
2931 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2932
2933 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2934 value = value + 26;
2935 /* Convert the value from ascii to integer */
2936 ret = kstrtou8(value, 10, &minTime);
2937 if (ret < 0)
2938 {
2939 /* If the input value is greater than max value of datatype, then also
2940 kstrtou8 fails */
2941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2942 "%s: kstrtou8 failed range [%d - %d]", __func__,
2943 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2944 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2945 ret = -EINVAL;
2946 goto exit;
2947 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002948 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2949 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2950 {
2951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2952 "scan min channel time value %d is out of range"
2953 " (Min: %d Max: %d)", minTime,
2954 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2955 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2956 ret = -EINVAL;
2957 goto exit;
2958 }
2959
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302960 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2961 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2962 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2964 "%s: Received Command to change channel min time = %d", __func__, minTime);
2965
2966 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2967 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2968 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002969 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2970 {
2971 tANI_U8 *value = command;
2972 tANI_U8 channel = 0;
2973 tANI_U8 dwellTime = 0;
2974 tANI_U8 bufLen = 0;
2975 tANI_U8 *buf = NULL;
2976 tSirMacAddr targetApBssid;
2977 eHalStatus status = eHAL_STATUS_SUCCESS;
2978 struct ieee80211_channel chan;
2979 tANI_U8 finalLen = 0;
2980 tANI_U8 *finalBuf = NULL;
2981 tANI_U8 temp = 0;
2982 u64 cookie;
2983 hdd_station_ctx_t *pHddStaCtx = NULL;
2984 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2985
2986 /* if not associated, no need to send action frame */
2987 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2988 {
2989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2990 ret = -EINVAL;
2991 goto exit;
2992 }
2993
2994 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2995 &dwellTime, &buf, &bufLen);
2996 if (eHAL_STATUS_SUCCESS != status)
2997 {
2998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2999 "%s: Failed to parse send action frame data", __func__);
3000 ret = -EINVAL;
3001 goto exit;
3002 }
3003
3004 /* if the target bssid is different from currently associated AP,
3005 then no need to send action frame */
3006 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3007 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3008 {
3009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3010 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003011 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003012 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003013 goto exit;
3014 }
3015
3016 /* if the channel number is different from operating channel then
3017 no need to send action frame */
3018 if (channel != pHddStaCtx->conn_info.operationChannel)
3019 {
3020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3021 "%s: channel(%d) is different from operating channel(%d)",
3022 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3023 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003024 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003025 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003026 goto exit;
3027 }
3028 chan.center_freq = sme_ChnToFreq(channel);
3029
3030 finalLen = bufLen + 24;
3031 finalBuf = vos_mem_malloc(finalLen);
3032 if (NULL == finalBuf)
3033 {
3034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3035 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003036 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003037 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003038 goto exit;
3039 }
3040 vos_mem_zero(finalBuf, finalLen);
3041
3042 /* Fill subtype */
3043 temp = SIR_MAC_MGMT_ACTION << 4;
3044 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3045
3046 /* Fill type */
3047 temp = SIR_MAC_MGMT_FRAME;
3048 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3049
3050 /* Fill destination address (bssid of the AP) */
3051 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3052
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003053 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003054 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3055
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003056 /* Fill BSSID (AP mac address) */
3057 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003058
3059 /* Fill received buffer from 24th address */
3060 vos_mem_copy(finalBuf + 24, buf, bufLen);
3061
Jeff Johnson11c33152013-04-16 17:52:40 -07003062 /* done with the parsed buffer */
3063 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003064 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003065
DARAM SUDHA39eede62014-02-12 11:16:40 +05303066 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3068 &(pAdapter->wdev),
3069#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003070 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003071#endif
3072 &chan, 0,
3073#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3074 NL80211_CHAN_HT20, 1,
3075#endif
3076 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003077 1, &cookie );
3078 vos_mem_free(finalBuf);
3079 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003080 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3081 {
3082 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3083 char extra[32];
3084 tANI_U8 len = 0;
3085
3086 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003087 len = scnprintf(extra, sizeof(extra), "%s %d",
3088 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303089 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3090 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3091 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303092 len = VOS_MIN(priv_data.total_len, len + 1);
3093 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003094 {
3095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3096 "%s: failed to copy data to user buffer", __func__);
3097 ret = -EFAULT;
3098 goto exit;
3099 }
3100 }
3101 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3102 {
3103 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003104 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003105
3106 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3107 value = value + 19;
3108 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003109 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003110 if (ret < 0)
3111 {
3112 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003113 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003115 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003116 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3117 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3118 ret = -EINVAL;
3119 goto exit;
3120 }
3121
3122 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3123 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3124 {
3125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3126 "lfr mode value %d is out of range"
3127 " (Min: %d Max: %d)", maxTime,
3128 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3129 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3130 ret = -EINVAL;
3131 goto exit;
3132 }
3133
3134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3135 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3136
3137 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3138 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3139 }
3140 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3141 {
3142 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3143 char extra[32];
3144 tANI_U8 len = 0;
3145
3146 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003147 len = scnprintf(extra, sizeof(extra), "%s %d",
3148 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05303149 len = VOS_MIN(priv_data.total_len, len + 1);
3150 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003151 {
3152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3153 "%s: failed to copy data to user buffer", __func__);
3154 ret = -EFAULT;
3155 goto exit;
3156 }
3157 }
3158 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3159 {
3160 tANI_U8 *value = command;
3161 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3162
3163 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3164 value = value + 16;
3165 /* Convert the value from ascii to integer */
3166 ret = kstrtou16(value, 10, &val);
3167 if (ret < 0)
3168 {
3169 /* If the input value is greater than max value of datatype, then also
3170 kstrtou16 fails */
3171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3172 "%s: kstrtou16 failed range [%d - %d]", __func__,
3173 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3174 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3175 ret = -EINVAL;
3176 goto exit;
3177 }
3178
3179 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3180 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3181 {
3182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3183 "scan home time value %d is out of range"
3184 " (Min: %d Max: %d)", val,
3185 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3186 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3187 ret = -EINVAL;
3188 goto exit;
3189 }
3190
3191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3192 "%s: Received Command to change scan home time = %d", __func__, val);
3193
3194 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3195 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3196 }
3197 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3198 {
3199 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3200 char extra[32];
3201 tANI_U8 len = 0;
3202
3203 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003204 len = scnprintf(extra, sizeof(extra), "%s %d",
3205 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05303206 len = VOS_MIN(priv_data.total_len, len + 1);
3207 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003208 {
3209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3210 "%s: failed to copy data to user buffer", __func__);
3211 ret = -EFAULT;
3212 goto exit;
3213 }
3214 }
3215 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3216 {
3217 tANI_U8 *value = command;
3218 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3219
3220 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3221 value = value + 17;
3222 /* Convert the value from ascii to integer */
3223 ret = kstrtou8(value, 10, &val);
3224 if (ret < 0)
3225 {
3226 /* If the input value is greater than max value of datatype, then also
3227 kstrtou8 fails */
3228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3229 "%s: kstrtou8 failed range [%d - %d]", __func__,
3230 CFG_ROAM_INTRA_BAND_MIN,
3231 CFG_ROAM_INTRA_BAND_MAX);
3232 ret = -EINVAL;
3233 goto exit;
3234 }
3235
3236 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3237 (val > CFG_ROAM_INTRA_BAND_MAX))
3238 {
3239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3240 "intra band mode value %d is out of range"
3241 " (Min: %d Max: %d)", val,
3242 CFG_ROAM_INTRA_BAND_MIN,
3243 CFG_ROAM_INTRA_BAND_MAX);
3244 ret = -EINVAL;
3245 goto exit;
3246 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3248 "%s: Received Command to change intra band = %d", __func__, val);
3249
3250 pHddCtx->cfg_ini->nRoamIntraBand = val;
3251 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3252 }
3253 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3254 {
3255 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3256 char extra[32];
3257 tANI_U8 len = 0;
3258
3259 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003260 len = scnprintf(extra, sizeof(extra), "%s %d",
3261 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05303262 len = VOS_MIN(priv_data.total_len, len + 1);
3263 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003264 {
3265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3266 "%s: failed to copy data to user buffer", __func__);
3267 ret = -EFAULT;
3268 goto exit;
3269 }
3270 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003271 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3272 {
3273 tANI_U8 *value = command;
3274 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3275
3276 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3277 value = value + 15;
3278 /* Convert the value from ascii to integer */
3279 ret = kstrtou8(value, 10, &nProbes);
3280 if (ret < 0)
3281 {
3282 /* If the input value is greater than max value of datatype, then also
3283 kstrtou8 fails */
3284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3285 "%s: kstrtou8 failed range [%d - %d]", __func__,
3286 CFG_ROAM_SCAN_N_PROBES_MIN,
3287 CFG_ROAM_SCAN_N_PROBES_MAX);
3288 ret = -EINVAL;
3289 goto exit;
3290 }
3291
3292 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3293 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3294 {
3295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3296 "NProbes value %d is out of range"
3297 " (Min: %d Max: %d)", nProbes,
3298 CFG_ROAM_SCAN_N_PROBES_MIN,
3299 CFG_ROAM_SCAN_N_PROBES_MAX);
3300 ret = -EINVAL;
3301 goto exit;
3302 }
3303
3304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3305 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3306
3307 pHddCtx->cfg_ini->nProbes = nProbes;
3308 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3309 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303310 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003311 {
3312 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3313 char extra[32];
3314 tANI_U8 len = 0;
3315
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003316 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05303317 len = VOS_MIN(priv_data.total_len, len + 1);
3318 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3320 "%s: failed to copy data to user buffer", __func__);
3321 ret = -EFAULT;
3322 goto exit;
3323 }
3324 }
3325 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3326 {
3327 tANI_U8 *value = command;
3328 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3329
3330 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3331 /* input value is in units of msec */
3332 value = value + 20;
3333 /* Convert the value from ascii to integer */
3334 ret = kstrtou16(value, 10, &homeAwayTime);
3335 if (ret < 0)
3336 {
3337 /* If the input value is greater than max value of datatype, then also
3338 kstrtou8 fails */
3339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3340 "%s: kstrtou8 failed range [%d - %d]", __func__,
3341 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3342 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3343 ret = -EINVAL;
3344 goto exit;
3345 }
3346
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003347 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3348 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3349 {
3350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3351 "homeAwayTime value %d is out of range"
3352 " (Min: %d Max: %d)", homeAwayTime,
3353 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3354 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3355 ret = -EINVAL;
3356 goto exit;
3357 }
3358
3359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3360 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003361 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3362 {
3363 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3364 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3365 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003366 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303367 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003368 {
3369 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3370 char extra[32];
3371 tANI_U8 len = 0;
3372
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003373 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05303374 len = VOS_MIN(priv_data.total_len, len + 1);
3375 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3377 "%s: failed to copy data to user buffer", __func__);
3378 ret = -EFAULT;
3379 goto exit;
3380 }
3381 }
3382 else if (strncmp(command, "REASSOC", 7) == 0)
3383 {
3384 tANI_U8 *value = command;
3385 tANI_U8 channel = 0;
3386 tSirMacAddr targetApBssid;
3387 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003388#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3389 tCsrHandoffRequest handoffInfo;
3390#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003391 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003392 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3393
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003394 /* if not associated, no need to proceed with reassoc */
3395 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3396 {
3397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3398 ret = -EINVAL;
3399 goto exit;
3400 }
3401
3402 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3403 if (eHAL_STATUS_SUCCESS != status)
3404 {
3405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3406 "%s: Failed to parse reassoc command data", __func__);
3407 ret = -EINVAL;
3408 goto exit;
3409 }
3410
3411 /* if the target bssid is same as currently associated AP,
3412 then no need to proceed with reassoc */
3413 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3414 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3415 {
3416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3417 ret = -EINVAL;
3418 goto exit;
3419 }
3420
3421 /* Check channel number is a valid channel number */
3422 if(VOS_STATUS_SUCCESS !=
3423 wlan_hdd_validate_operation_channel(pAdapter, channel))
3424 {
3425 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003426 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003427 return -EINVAL;
3428 }
3429
3430 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003431#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3432 handoffInfo.channel = channel;
3433 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3434 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3435#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003436 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003437 else if (strncmp(command, "SETWESMODE", 10) == 0)
3438 {
3439 tANI_U8 *value = command;
3440 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3441
3442 /* Move pointer to ahead of SETWESMODE<delimiter> */
3443 value = value + 11;
3444 /* Convert the value from ascii to integer */
3445 ret = kstrtou8(value, 10, &wesMode);
3446 if (ret < 0)
3447 {
3448 /* If the input value is greater than max value of datatype, then also
3449 kstrtou8 fails */
3450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3451 "%s: kstrtou8 failed range [%d - %d]", __func__,
3452 CFG_ENABLE_WES_MODE_NAME_MIN,
3453 CFG_ENABLE_WES_MODE_NAME_MAX);
3454 ret = -EINVAL;
3455 goto exit;
3456 }
3457
3458 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3459 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3460 {
3461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3462 "WES Mode value %d is out of range"
3463 " (Min: %d Max: %d)", wesMode,
3464 CFG_ENABLE_WES_MODE_NAME_MIN,
3465 CFG_ENABLE_WES_MODE_NAME_MAX);
3466 ret = -EINVAL;
3467 goto exit;
3468 }
3469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3470 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3471
3472 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3473 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3474 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303475 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003476 {
3477 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3478 char extra[32];
3479 tANI_U8 len = 0;
3480
Arif Hussain826d9412013-11-12 16:44:54 -08003481 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05303482 len = VOS_MIN(priv_data.total_len, len + 1);
3483 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3485 "%s: failed to copy data to user buffer", __func__);
3486 ret = -EFAULT;
3487 goto exit;
3488 }
3489 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003490#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003491#ifdef FEATURE_WLAN_LFR
3492 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3493 {
3494 tANI_U8 *value = command;
3495 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3496
3497 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3498 value = value + 12;
3499 /* Convert the value from ascii to integer */
3500 ret = kstrtou8(value, 10, &lfrMode);
3501 if (ret < 0)
3502 {
3503 /* If the input value is greater than max value of datatype, then also
3504 kstrtou8 fails */
3505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3506 "%s: kstrtou8 failed range [%d - %d]", __func__,
3507 CFG_LFR_FEATURE_ENABLED_MIN,
3508 CFG_LFR_FEATURE_ENABLED_MAX);
3509 ret = -EINVAL;
3510 goto exit;
3511 }
3512
3513 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3514 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3515 {
3516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3517 "lfr mode value %d is out of range"
3518 " (Min: %d Max: %d)", lfrMode,
3519 CFG_LFR_FEATURE_ENABLED_MIN,
3520 CFG_LFR_FEATURE_ENABLED_MAX);
3521 ret = -EINVAL;
3522 goto exit;
3523 }
3524
3525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3526 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3527
3528 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3529 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3530 }
3531#endif
3532#ifdef WLAN_FEATURE_VOWIFI_11R
3533 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3534 {
3535 tANI_U8 *value = command;
3536 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3537
3538 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3539 value = value + 18;
3540 /* Convert the value from ascii to integer */
3541 ret = kstrtou8(value, 10, &ft);
3542 if (ret < 0)
3543 {
3544 /* If the input value is greater than max value of datatype, then also
3545 kstrtou8 fails */
3546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3547 "%s: kstrtou8 failed range [%d - %d]", __func__,
3548 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3549 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3550 ret = -EINVAL;
3551 goto exit;
3552 }
3553
3554 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3555 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3556 {
3557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3558 "ft mode value %d is out of range"
3559 " (Min: %d Max: %d)", ft,
3560 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3561 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3562 ret = -EINVAL;
3563 goto exit;
3564 }
3565
3566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3567 "%s: Received Command to change ft mode = %d", __func__, ft);
3568
3569 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3570 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3571 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303572 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3573 {
3574 tANI_U8 *value = command;
3575 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303576
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303577 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3578 value = value + 15;
3579 /* Convert the value from ascii to integer */
3580 ret = kstrtou8(value, 10, &dfsScanMode);
3581 if (ret < 0)
3582 {
3583 /* If the input value is greater than max value of
3584 datatype, then also kstrtou8 fails
3585 */
3586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3587 "%s: kstrtou8 failed range [%d - %d]", __func__,
3588 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3589 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3590 ret = -EINVAL;
3591 goto exit;
3592 }
3593
3594 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3595 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3596 {
3597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3598 "dfsScanMode value %d is out of range"
3599 " (Min: %d Max: %d)", dfsScanMode,
3600 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3601 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3602 ret = -EINVAL;
3603 goto exit;
3604 }
3605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3606 "%s: Received Command to Set DFS Scan Mode = %d",
3607 __func__, dfsScanMode);
3608
3609 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3610 }
3611 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3612 {
3613 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3614 char extra[32];
3615 tANI_U8 len = 0;
3616
3617 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05303618 len = VOS_MIN(priv_data.total_len, len + 1);
3619 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303620 {
3621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3622 "%s: failed to copy data to user buffer", __func__);
3623 ret = -EFAULT;
3624 goto exit;
3625 }
3626 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303627 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3628 {
3629 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303630 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303631 tSirMacAddr targetApBssid;
3632 tANI_U8 trigger = 0;
3633 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303634 tHalHandle hHal;
3635 v_U32_t roamId = 0;
3636 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303637 hdd_station_ctx_t *pHddStaCtx = NULL;
3638 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303639 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303640
3641 /* if not associated, no need to proceed with reassoc */
3642 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3643 {
3644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3645 ret = -EINVAL;
3646 goto exit;
3647 }
3648
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303649 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303650 if (eHAL_STATUS_SUCCESS != status)
3651 {
3652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3653 "%s: Failed to parse reassoc command data", __func__);
3654 ret = -EINVAL;
3655 goto exit;
3656 }
3657
3658 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303659 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303660 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3661 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3662 {
3663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3664 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3665 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303666 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3667 &modProfileFields);
3668 sme_RoamReassoc(hHal, pAdapter->sessionId,
3669 NULL, modProfileFields, &roamId, 1);
3670 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303671 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303672
3673 /* Check channel number is a valid channel number */
3674 if(VOS_STATUS_SUCCESS !=
3675 wlan_hdd_validate_operation_channel(pAdapter, channel))
3676 {
3677 hddLog(VOS_TRACE_LEVEL_ERROR,
3678 "%s: Invalid Channel [%d]", __func__, channel);
3679 return -EINVAL;
3680 }
3681
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303682 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303683
3684 /* Proceed with scan/roam */
3685 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3686 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303687 (tSmeFastRoamTrigger)(trigger),
3688 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303689 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003690#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003691#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003692 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3693 {
3694 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003695 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003696
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003697 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003698 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003699 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003700 hdd_is_okc_mode_enabled(pHddCtx) &&
3701 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3702 {
3703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003704 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003705 " hence this operation is not permitted!", __func__);
3706 ret = -EPERM;
3707 goto exit;
3708 }
3709
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003710 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3711 value = value + 11;
3712 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003713 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003714 if (ret < 0)
3715 {
3716 /* If the input value is greater than max value of datatype, then also
3717 kstrtou8 fails */
3718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3719 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003720 CFG_ESE_FEATURE_ENABLED_MIN,
3721 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003722 ret = -EINVAL;
3723 goto exit;
3724 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003725 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3726 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003727 {
3728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003729 "Ese mode value %d is out of range"
3730 " (Min: %d Max: %d)", eseMode,
3731 CFG_ESE_FEATURE_ENABLED_MIN,
3732 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003733 ret = -EINVAL;
3734 goto exit;
3735 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003737 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003738
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003739 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3740 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003741 }
3742#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003743 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3744 {
3745 tANI_U8 *value = command;
3746 tANI_BOOLEAN roamScanControl = 0;
3747
3748 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3749 value = value + 19;
3750 /* Convert the value from ascii to integer */
3751 ret = kstrtou8(value, 10, &roamScanControl);
3752 if (ret < 0)
3753 {
3754 /* If the input value is greater than max value of datatype, then also
3755 kstrtou8 fails */
3756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3757 "%s: kstrtou8 failed ", __func__);
3758 ret = -EINVAL;
3759 goto exit;
3760 }
3761
3762 if (0 != roamScanControl)
3763 {
3764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3765 "roam scan control invalid value = %d",
3766 roamScanControl);
3767 ret = -EINVAL;
3768 goto exit;
3769 }
3770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3771 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3772
3773 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3774 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003775#ifdef FEATURE_WLAN_OKC
3776 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3777 {
3778 tANI_U8 *value = command;
3779 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3780
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003781 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003782 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003783 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003784 hdd_is_okc_mode_enabled(pHddCtx) &&
3785 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3786 {
3787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003788 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003789 " hence this operation is not permitted!", __func__);
3790 ret = -EPERM;
3791 goto exit;
3792 }
3793
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003794 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3795 value = value + 11;
3796 /* Convert the value from ascii to integer */
3797 ret = kstrtou8(value, 10, &okcMode);
3798 if (ret < 0)
3799 {
3800 /* If the input value is greater than max value of datatype, then also
3801 kstrtou8 fails */
3802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3803 "%s: kstrtou8 failed range [%d - %d]", __func__,
3804 CFG_OKC_FEATURE_ENABLED_MIN,
3805 CFG_OKC_FEATURE_ENABLED_MAX);
3806 ret = -EINVAL;
3807 goto exit;
3808 }
3809
3810 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3811 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3812 {
3813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3814 "Okc mode value %d is out of range"
3815 " (Min: %d Max: %d)", okcMode,
3816 CFG_OKC_FEATURE_ENABLED_MIN,
3817 CFG_OKC_FEATURE_ENABLED_MAX);
3818 ret = -EINVAL;
3819 goto exit;
3820 }
3821
3822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3823 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3824
3825 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3826 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003827#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303828 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003829 {
3830 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3831 char extra[32];
3832 tANI_U8 len = 0;
3833
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003834 len = scnprintf(extra, sizeof(extra), "%s %d",
3835 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05303836 len = VOS_MIN(priv_data.total_len, len + 1);
3837 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3839 "%s: failed to copy data to user buffer", __func__);
3840 ret = -EFAULT;
3841 goto exit;
3842 }
3843 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303844#ifdef WLAN_FEATURE_PACKET_FILTERING
3845 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3846 {
3847 tANI_U8 filterType = 0;
3848 tANI_U8 *value = command;
3849
3850 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3851 value = value + 22;
3852
3853 /* Convert the value from ascii to integer */
3854 ret = kstrtou8(value, 10, &filterType);
3855 if (ret < 0)
3856 {
3857 /* If the input value is greater than max value of datatype,
3858 * then also kstrtou8 fails
3859 */
3860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3861 "%s: kstrtou8 failed range ", __func__);
3862 ret = -EINVAL;
3863 goto exit;
3864 }
3865
3866 if (filterType != 0 && filterType != 1)
3867 {
3868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3869 "%s: Accepted Values are 0 and 1 ", __func__);
3870 ret = -EINVAL;
3871 goto exit;
3872 }
3873 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3874 pAdapter->sessionId);
3875 }
3876#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303877 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3878 {
Kiet Lamad161252014-07-22 11:23:32 -07003879 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303880 int ret;
3881
Kiet Lamad161252014-07-22 11:23:32 -07003882 dhcpPhase = command + 11;
3883 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303884 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003886 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303887
3888 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003889
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303890 ret = wlan_hdd_scan_abort(pAdapter);
3891 if (ret < 0)
3892 {
3893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3894 FL("failed to abort existing scan %d"), ret);
3895 }
3896
Kiet Lamad161252014-07-22 11:23:32 -07003897 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3898 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303899 }
Kiet Lamad161252014-07-22 11:23:32 -07003900 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303901 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003903 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303904
3905 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003906
3907 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3908 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303909 }
3910 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003911 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3912 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3914 FL("making default scan to ACTIVE"));
3915 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003916 }
3917 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3918 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3920 FL("making default scan to PASSIVE"));
3921 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003922 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303923 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3924 {
3925 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3926 char extra[32];
3927 tANI_U8 len = 0;
3928
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303929 memset(extra, 0, sizeof(extra));
3930 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05303931 len = VOS_MIN(priv_data.total_len, len + 1);
3932 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3934 "%s: failed to copy data to user buffer", __func__);
3935 ret = -EFAULT;
3936 goto exit;
3937 }
3938 ret = len;
3939 }
3940 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3941 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303942 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303943 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003944 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3945 {
3946 tANI_U8 filterType = 0;
3947 tANI_U8 *value;
3948 value = command + 9;
3949
3950 /* Convert the value from ascii to integer */
3951 ret = kstrtou8(value, 10, &filterType);
3952 if (ret < 0)
3953 {
3954 /* If the input value is greater than max value of datatype,
3955 * then also kstrtou8 fails
3956 */
3957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3958 "%s: kstrtou8 failed range ", __func__);
3959 ret = -EINVAL;
3960 goto exit;
3961 }
3962 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3963 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3964 {
3965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3966 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3967 " 2-Sink ", __func__);
3968 ret = -EINVAL;
3969 goto exit;
3970 }
3971 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3972 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303973 pScanInfo = &pHddCtx->scan_info;
3974 if (filterType && pScanInfo != NULL &&
3975 pHddCtx->scan_info.mScanPending)
3976 {
3977 /*Miracast Session started. Abort Scan */
3978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3979 "%s, Aborting Scan For Miracast",__func__);
3980 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3981 eCSR_SCAN_ABORT_DEFAULT);
3982 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003983 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303984 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003985 }
Leo Chang614d2072013-08-22 14:59:44 -07003986 else if (strncmp(command, "SETMCRATE", 9) == 0)
3987 {
Leo Chang614d2072013-08-22 14:59:44 -07003988 tANI_U8 *value = command;
3989 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003990 tSirRateUpdateInd *rateUpdate;
3991 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003992
3993 /* Only valid for SAP mode */
3994 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3995 {
3996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3997 "%s: SAP mode is not running", __func__);
3998 ret = -EFAULT;
3999 goto exit;
4000 }
4001
4002 /* Move pointer to ahead of SETMCRATE<delimiter> */
4003 /* input value is in units of hundred kbps */
4004 value = value + 10;
4005 /* Convert the value from ascii to integer, decimal base */
4006 ret = kstrtouint(value, 10, &targetRate);
4007
Leo Chang1f98cbd2013-10-17 15:03:52 -07004008 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4009 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004010 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004011 hddLog(VOS_TRACE_LEVEL_ERROR,
4012 "%s: SETMCRATE indication alloc fail", __func__);
4013 ret = -EFAULT;
4014 goto exit;
4015 }
4016 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4017
4018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4019 "MC Target rate %d", targetRate);
4020 /* Ignore unicast */
4021 rateUpdate->ucastDataRate = -1;
4022 rateUpdate->mcastDataRate24GHz = targetRate;
4023 rateUpdate->mcastDataRate5GHz = targetRate;
4024 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4025 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4026 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4027 if (eHAL_STATUS_SUCCESS != status)
4028 {
4029 hddLog(VOS_TRACE_LEVEL_ERROR,
4030 "%s: SET_MC_RATE failed", __func__);
4031 vos_mem_free(rateUpdate);
4032 ret = -EFAULT;
4033 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004034 }
4035 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304036#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004037 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304038 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004039 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304040 }
4041#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004042#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004043 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4044 {
4045 tANI_U8 *value = command;
4046 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4047 tANI_U8 numChannels = 0;
4048 eHalStatus status = eHAL_STATUS_SUCCESS;
4049
4050 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4051 if (eHAL_STATUS_SUCCESS != status)
4052 {
4053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4054 "%s: Failed to parse channel list information", __func__);
4055 ret = -EINVAL;
4056 goto exit;
4057 }
4058
4059 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4060 {
4061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4062 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4063 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4064 ret = -EINVAL;
4065 goto exit;
4066 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004067 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004068 ChannelList,
4069 numChannels);
4070 if (eHAL_STATUS_SUCCESS != status)
4071 {
4072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4073 "%s: Failed to update channel list information", __func__);
4074 ret = -EINVAL;
4075 goto exit;
4076 }
4077 }
4078 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4079 {
4080 tANI_U8 *value = command;
4081 char extra[128] = {0};
4082 int len = 0;
4083 tANI_U8 tid = 0;
4084 hdd_station_ctx_t *pHddStaCtx = NULL;
4085 tAniTrafStrmMetrics tsmMetrics;
4086 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4087
4088 /* if not associated, return error */
4089 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4090 {
4091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4092 ret = -EINVAL;
4093 goto exit;
4094 }
4095
4096 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4097 value = value + 12;
4098 /* Convert the value from ascii to integer */
4099 ret = kstrtou8(value, 10, &tid);
4100 if (ret < 0)
4101 {
4102 /* If the input value is greater than max value of datatype, then also
4103 kstrtou8 fails */
4104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4105 "%s: kstrtou8 failed range [%d - %d]", __func__,
4106 TID_MIN_VALUE,
4107 TID_MAX_VALUE);
4108 ret = -EINVAL;
4109 goto exit;
4110 }
4111
4112 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4113 {
4114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4115 "tid value %d is out of range"
4116 " (Min: %d Max: %d)", tid,
4117 TID_MIN_VALUE,
4118 TID_MAX_VALUE);
4119 ret = -EINVAL;
4120 goto exit;
4121 }
4122
4123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4124 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4125
4126 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4127 {
4128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4129 "%s: failed to get tsm stats", __func__);
4130 ret = -EFAULT;
4131 goto exit;
4132 }
4133
4134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4135 "UplinkPktQueueDly(%d)\n"
4136 "UplinkPktQueueDlyHist[0](%d)\n"
4137 "UplinkPktQueueDlyHist[1](%d)\n"
4138 "UplinkPktQueueDlyHist[2](%d)\n"
4139 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304140 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004141 "UplinkPktLoss(%d)\n"
4142 "UplinkPktCount(%d)\n"
4143 "RoamingCount(%d)\n"
4144 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4145 tsmMetrics.UplinkPktQueueDlyHist[0],
4146 tsmMetrics.UplinkPktQueueDlyHist[1],
4147 tsmMetrics.UplinkPktQueueDlyHist[2],
4148 tsmMetrics.UplinkPktQueueDlyHist[3],
4149 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4150 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4151
4152 /* Output TSM stats is of the format
4153 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4154 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004155 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004156 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4157 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4158 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4159 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4160 tsmMetrics.RoamingDly);
4161
Ratnam Rachurid53009c2015-08-07 13:59:00 +05304162 len = VOS_MIN(priv_data.total_len, len + 1);
4163 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4165 "%s: failed to copy data to user buffer", __func__);
4166 ret = -EFAULT;
4167 goto exit;
4168 }
4169 }
4170 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4171 {
4172 tANI_U8 *value = command;
4173 tANI_U8 *cckmIe = NULL;
4174 tANI_U8 cckmIeLen = 0;
4175 eHalStatus status = eHAL_STATUS_SUCCESS;
4176
4177 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4178 if (eHAL_STATUS_SUCCESS != status)
4179 {
4180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4181 "%s: Failed to parse cckm ie data", __func__);
4182 ret = -EINVAL;
4183 goto exit;
4184 }
4185
4186 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4187 {
4188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4189 "%s: CCKM Ie input length is more than max[%d]", __func__,
4190 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004191 vos_mem_free(cckmIe);
4192 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004193 ret = -EINVAL;
4194 goto exit;
4195 }
4196 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004197 vos_mem_free(cckmIe);
4198 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004199 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004200 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4201 {
4202 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004203 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004204 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004205
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004206 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004207 if (eHAL_STATUS_SUCCESS != status)
4208 {
4209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004210 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004211 ret = -EINVAL;
4212 goto exit;
4213 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004214 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4215 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4216 hdd_indicateEseBcnReportNoResults (pAdapter,
4217 eseBcnReq.bcnReq[0].measurementToken,
4218 0x02, //BIT(1) set for measurement done
4219 0); // no BSS
4220 goto exit;
4221 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004222
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004223 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4224 if (eHAL_STATUS_SUCCESS != status)
4225 {
4226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4227 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4228 ret = -EINVAL;
4229 goto exit;
4230 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004231 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004232#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304233 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4234 {
4235 eHalStatus status;
4236 char buf[32], len;
4237 long waitRet;
4238 bcnMissRateContext_t getBcnMissRateCtx;
4239
4240 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4241
4242 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4243 {
4244 hddLog(VOS_TRACE_LEVEL_WARN,
4245 FL("GETBCNMISSRATE: STA is not in connected state"));
4246 ret = -1;
4247 goto exit;
4248 }
4249
4250 init_completion(&(getBcnMissRateCtx.completion));
4251 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4252
4253 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4254 pAdapter->sessionId,
4255 (void *)getBcnMissRateCB,
4256 (void *)(&getBcnMissRateCtx));
4257 if( eHAL_STATUS_SUCCESS != status)
4258 {
4259 hddLog(VOS_TRACE_LEVEL_INFO,
4260 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4261 ret = -EINVAL;
4262 goto exit;
4263 }
4264
4265 waitRet = wait_for_completion_interruptible_timeout
4266 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4267 if(waitRet <= 0)
4268 {
4269 hddLog(VOS_TRACE_LEVEL_ERROR,
4270 FL("failed to wait on bcnMissRateComp %d"), ret);
4271
4272 //Make magic number to zero so that callback is not called.
4273 spin_lock(&hdd_context_lock);
4274 getBcnMissRateCtx.magic = 0x0;
4275 spin_unlock(&hdd_context_lock);
4276 ret = -EINVAL;
4277 goto exit;
4278 }
4279
4280 hddLog(VOS_TRACE_LEVEL_INFO,
4281 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4282
4283 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4284 if (copy_to_user(priv_data.buf, &buf, len + 1))
4285 {
4286 hddLog(VOS_TRACE_LEVEL_ERROR,
4287 "%s: failed to copy data to user buffer", __func__);
4288 ret = -EFAULT;
4289 goto exit;
4290 }
4291 ret = len;
4292 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304293#ifdef FEATURE_WLAN_TDLS
4294 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4295 tANI_U8 *value = command;
4296 int set_value;
4297 /* Move pointer to ahead of TDLSOFFCH*/
4298 value += 26;
4299 sscanf(value, "%d", &set_value);
4300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4301 "%s: Tdls offchannel offset:%d",
4302 __func__, set_value);
4303 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4304 if (ret < 0)
4305 {
4306 ret = -EINVAL;
4307 goto exit;
4308 }
4309
4310 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4311 tANI_U8 *value = command;
4312 int set_value;
4313 /* Move pointer to ahead of tdlsoffchnmode*/
4314 value += 18;
4315 sscanf(value, "%d", &set_value);
4316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4317 "%s: Tdls offchannel mode:%d",
4318 __func__, set_value);
4319 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4320 if (ret < 0)
4321 {
4322 ret = -EINVAL;
4323 goto exit;
4324 }
4325 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4326 tANI_U8 *value = command;
4327 int set_value;
4328 /* Move pointer to ahead of TDLSOFFCH*/
4329 value += 14;
4330 sscanf(value, "%d", &set_value);
4331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4332 "%s: Tdls offchannel num: %d",
4333 __func__, set_value);
4334 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4335 if (ret < 0)
4336 {
4337 ret = -EINVAL;
4338 goto exit;
4339 }
4340 }
4341#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304342 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4343 {
4344 eHalStatus status;
4345 char *buf = NULL;
4346 char len;
4347 long waitRet;
4348 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304349 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304350 tANI_U8 *ptr = command;
4351 int stats = *(ptr + 11) - '0';
4352
4353 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4354 if (!IS_FEATURE_FW_STATS_ENABLE)
4355 {
4356 hddLog(VOS_TRACE_LEVEL_INFO,
4357 FL("Get Firmware stats feature not supported"));
4358 ret = -EINVAL;
4359 goto exit;
4360 }
4361
4362 if (FW_STATS_MAX <= stats || 0 >= stats)
4363 {
4364 hddLog(VOS_TRACE_LEVEL_INFO,
4365 FL(" stats %d not supported"),stats);
4366 ret = -EINVAL;
4367 goto exit;
4368 }
4369
4370 init_completion(&(fwStatsCtx.completion));
4371 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4372 fwStatsCtx.pAdapter = pAdapter;
4373 fwStatsRsp->type = 0;
4374 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304375 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304376 if (eHAL_STATUS_SUCCESS != status)
4377 {
4378 hddLog(VOS_TRACE_LEVEL_ERROR,
4379 FL(" fail to post WDA cmd status = %d"), status);
4380 ret = -EINVAL;
4381 goto exit;
4382 }
4383 waitRet = wait_for_completion_timeout
4384 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4385 if (waitRet <= 0)
4386 {
4387 hddLog(VOS_TRACE_LEVEL_ERROR,
4388 FL("failed to wait on GwtFwstats"));
4389 //Make magic number to zero so that callback is not executed.
4390 spin_lock(&hdd_context_lock);
4391 fwStatsCtx.magic = 0x0;
4392 spin_unlock(&hdd_context_lock);
4393 ret = -EINVAL;
4394 goto exit;
4395 }
4396 if (fwStatsRsp->type)
4397 {
4398 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4399 if (!buf)
4400 {
4401 hddLog(VOS_TRACE_LEVEL_ERROR,
4402 FL(" failed to allocate memory"));
4403 ret = -ENOMEM;
4404 goto exit;
4405 }
4406 switch( fwStatsRsp->type )
4407 {
4408 case FW_UBSP_STATS:
4409 {
4410 len = snprintf(buf, FW_STATE_RSP_LEN,
4411 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304412 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4413 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304414 }
4415 break;
4416 default:
4417 {
4418 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4419 ret = -EFAULT;
4420 kfree(buf);
4421 goto exit;
4422 }
4423 }
4424 if (copy_to_user(priv_data.buf, buf, len + 1))
4425 {
4426 hddLog(VOS_TRACE_LEVEL_ERROR,
4427 FL(" failed to copy data to user buffer"));
4428 ret = -EFAULT;
4429 kfree(buf);
4430 goto exit;
4431 }
4432 ret = len;
4433 kfree(buf);
4434 }
4435 else
4436 {
4437 hddLog(VOS_TRACE_LEVEL_ERROR,
4438 FL("failed to fetch the stats"));
4439 ret = -EFAULT;
4440 goto exit;
4441 }
4442
4443 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304444 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4445 {
4446 /*
4447 * this command wld be called by user-space when it detects WLAN
4448 * ON after airplane mode is set. When APM is set, WLAN turns off.
4449 * But it can be turned back on. Otherwise; when APM is turned back
4450 * off, WLAN wld turn back on. So at that point the command is
4451 * expected to come down. 0 means disable, 1 means enable. The
4452 * constraint is removed when parameter 1 is set or different
4453 * country code is set
4454 */
4455 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4456 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004457 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304458 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4459 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4460 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304461 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4462 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004464 }
4465exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304466 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004467 if (command)
4468 {
4469 kfree(command);
4470 }
4471 return ret;
4472}
4473
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004474#ifdef CONFIG_COMPAT
4475static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4476{
4477 struct {
4478 compat_uptr_t buf;
4479 int used_len;
4480 int total_len;
4481 } compat_priv_data;
4482 hdd_priv_data_t priv_data;
4483 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004484
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004485 /*
4486 * Note that pAdapter and ifr have already been verified by caller,
4487 * and HDD context has also been validated
4488 */
4489 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4490 sizeof(compat_priv_data))) {
4491 ret = -EFAULT;
4492 goto exit;
4493 }
4494 priv_data.buf = compat_ptr(compat_priv_data.buf);
4495 priv_data.used_len = compat_priv_data.used_len;
4496 priv_data.total_len = compat_priv_data.total_len;
4497 ret = hdd_driver_command(pAdapter, &priv_data);
4498 exit:
4499 return ret;
4500}
4501#else /* CONFIG_COMPAT */
4502static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4503{
4504 /* will never be invoked */
4505 return 0;
4506}
4507#endif /* CONFIG_COMPAT */
4508
4509static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4510{
4511 hdd_priv_data_t priv_data;
4512 int ret = 0;
4513
4514 /*
4515 * Note that pAdapter and ifr have already been verified by caller,
4516 * and HDD context has also been validated
4517 */
4518 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4519 ret = -EFAULT;
4520 } else {
4521 ret = hdd_driver_command(pAdapter, &priv_data);
4522 }
4523 return ret;
4524}
4525
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304526int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004527{
4528 hdd_adapter_t *pAdapter;
4529 hdd_context_t *pHddCtx;
4530 int ret;
4531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304532 ENTER();
4533
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004534 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4535 if (NULL == pAdapter) {
4536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4537 "%s: HDD adapter context is Null", __func__);
4538 ret = -ENODEV;
4539 goto exit;
4540 }
4541 if (dev != pAdapter->dev) {
4542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4543 "%s: HDD adapter/dev inconsistency", __func__);
4544 ret = -ENODEV;
4545 goto exit;
4546 }
4547
4548 if ((!ifr) || (!ifr->ifr_data)) {
4549 ret = -EINVAL;
4550 goto exit;
4551 }
4552
4553 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4554 ret = wlan_hdd_validate_context(pHddCtx);
4555 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004556 ret = -EBUSY;
4557 goto exit;
4558 }
4559
4560 switch (cmd) {
4561 case (SIOCDEVPRIVATE + 1):
4562 if (is_compat_task())
4563 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4564 else
4565 ret = hdd_driver_ioctl(pAdapter, ifr);
4566 break;
4567 default:
4568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4569 __func__, cmd);
4570 ret = -EINVAL;
4571 break;
4572 }
4573 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304574 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004575 return ret;
4576}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004577
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304578int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4579{
4580 int ret;
4581
4582 vos_ssr_protect(__func__);
4583 ret = __hdd_ioctl(dev, ifr, cmd);
4584 vos_ssr_unprotect(__func__);
4585
4586 return ret;
4587}
4588
Katya Nigame7b69a82015-04-28 15:24:06 +05304589int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4590{
4591 return 0;
4592}
4593
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004594#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004595/**---------------------------------------------------------------------------
4596
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004598
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004599 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004600 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4601 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4602 <space>Scan Mode N<space>Meas Duration N
4603 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4604 then take N.
4605 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4606 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4607 This function does not take care of removing duplicate channels from the list
4608
4609 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004610 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004611
4612 \return - 0 for success non-zero for failure
4613
4614 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004615static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4616 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004617{
4618 tANI_U8 *inPtr = pValue;
4619 int tempInt = 0;
4620 int j = 0, i = 0, v = 0;
4621 char buf[32];
4622
4623 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4624 /*no argument after the command*/
4625 if (NULL == inPtr)
4626 {
4627 return -EINVAL;
4628 }
4629 /*no space after the command*/
4630 else if (SPACE_ASCII_VALUE != *inPtr)
4631 {
4632 return -EINVAL;
4633 }
4634
4635 /*removing empty spaces*/
4636 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4637
4638 /*no argument followed by spaces*/
4639 if ('\0' == *inPtr) return -EINVAL;
4640
4641 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004642 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004643 if (1 != v) return -EINVAL;
4644
4645 v = kstrtos32(buf, 10, &tempInt);
4646 if ( v < 0) return -EINVAL;
4647
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004648 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004649
4650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004651 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004652
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004653 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004654 {
4655 for (i = 0; i < 4; i++)
4656 {
4657 /*inPtr pointing to the beginning of first space after number of ie fields*/
4658 inPtr = strpbrk( inPtr, " " );
4659 /*no ie data after the number of ie fields argument*/
4660 if (NULL == inPtr) return -EINVAL;
4661
4662 /*removing empty space*/
4663 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4664
4665 /*no ie data after the number of ie fields argument and spaces*/
4666 if ( '\0' == *inPtr ) return -EINVAL;
4667
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004668 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004669 if (1 != v) return -EINVAL;
4670
4671 v = kstrtos32(buf, 10, &tempInt);
4672 if (v < 0) return -EINVAL;
4673
4674 switch (i)
4675 {
4676 case 0: /* Measurement token */
4677 if (tempInt <= 0)
4678 {
4679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4680 "Invalid Measurement Token(%d)", tempInt);
4681 return -EINVAL;
4682 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004683 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004684 break;
4685
4686 case 1: /* Channel number */
4687 if ((tempInt <= 0) ||
4688 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4689 {
4690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4691 "Invalid Channel Number(%d)", tempInt);
4692 return -EINVAL;
4693 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004694 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004695 break;
4696
4697 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004698 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004699 {
4700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4701 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4702 return -EINVAL;
4703 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004704 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004705 break;
4706
4707 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004708 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4709 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004710 {
4711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4712 "Invalid Measurement Duration(%d)", tempInt);
4713 return -EINVAL;
4714 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004715 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004716 break;
4717 }
4718 }
4719 }
4720
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004721 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004722 {
4723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304724 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004725 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004726 pEseBcnReq->bcnReq[j].measurementToken,
4727 pEseBcnReq->bcnReq[j].channel,
4728 pEseBcnReq->bcnReq[j].scanMode,
4729 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004730 }
4731
4732 return VOS_STATUS_SUCCESS;
4733}
4734
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004735static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4736{
4737 struct statsContext *pStatsContext = NULL;
4738 hdd_adapter_t *pAdapter = NULL;
4739
4740 if (NULL == pContext)
4741 {
4742 hddLog(VOS_TRACE_LEVEL_ERROR,
4743 "%s: Bad param, pContext [%p]",
4744 __func__, pContext);
4745 return;
4746 }
4747
Jeff Johnson72a40512013-12-19 10:14:15 -08004748 /* there is a race condition that exists between this callback
4749 function and the caller since the caller could time out either
4750 before or while this code is executing. we use a spinlock to
4751 serialize these actions */
4752 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004753
4754 pStatsContext = pContext;
4755 pAdapter = pStatsContext->pAdapter;
4756 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4757 {
4758 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004759 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004760 hddLog(VOS_TRACE_LEVEL_WARN,
4761 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4762 __func__, pAdapter, pStatsContext->magic);
4763 return;
4764 }
4765
Jeff Johnson72a40512013-12-19 10:14:15 -08004766 /* context is valid so caller is still waiting */
4767
4768 /* paranoia: invalidate the magic */
4769 pStatsContext->magic = 0;
4770
4771 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004772 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4773 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4774 tsmMetrics.UplinkPktQueueDlyHist,
4775 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4776 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4777 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4778 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4779 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4780 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4781 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4782
Jeff Johnson72a40512013-12-19 10:14:15 -08004783 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004784 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004785
4786 /* serialization is complete */
4787 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004788}
4789
4790
4791
4792static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4793 tAniTrafStrmMetrics* pTsmMetrics)
4794{
4795 hdd_station_ctx_t *pHddStaCtx = NULL;
4796 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004797 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004798 long lrc;
4799 struct statsContext context;
4800 hdd_context_t *pHddCtx = NULL;
4801
4802 if (NULL == pAdapter)
4803 {
4804 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4805 return VOS_STATUS_E_FAULT;
4806 }
4807
4808 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4809 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4810
4811 /* we are connected prepare our callback context */
4812 init_completion(&context.completion);
4813 context.pAdapter = pAdapter;
4814 context.magic = STATS_CONTEXT_MAGIC;
4815
4816 /* query tsm stats */
4817 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4818 pHddStaCtx->conn_info.staId[ 0 ],
4819 pHddStaCtx->conn_info.bssId,
4820 &context, pHddCtx->pvosContext, tid);
4821
4822 if (eHAL_STATUS_SUCCESS != hstatus)
4823 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004824 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4825 __func__);
4826 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004827 }
4828 else
4829 {
4830 /* request was sent -- wait for the response */
4831 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4832 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004833 if (lrc <= 0)
4834 {
4835 hddLog(VOS_TRACE_LEVEL_ERROR,
4836 "%s: SME %s while retrieving statistics",
4837 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004838 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004839 }
4840 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004841
Jeff Johnson72a40512013-12-19 10:14:15 -08004842 /* either we never sent a request, we sent a request and received a
4843 response or we sent a request and timed out. if we never sent a
4844 request or if we sent a request and got a response, we want to
4845 clear the magic out of paranoia. if we timed out there is a
4846 race condition such that the callback function could be
4847 executing at the same time we are. of primary concern is if the
4848 callback function had already verified the "magic" but had not
4849 yet set the completion variable when a timeout occurred. we
4850 serialize these activities by invalidating the magic while
4851 holding a shared spinlock which will cause us to block if the
4852 callback is currently executing */
4853 spin_lock(&hdd_context_lock);
4854 context.magic = 0;
4855 spin_unlock(&hdd_context_lock);
4856
4857 if (VOS_STATUS_SUCCESS == vstatus)
4858 {
4859 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4860 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4861 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4862 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4863 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4864 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4865 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4866 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4867 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4868 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4869 }
4870 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004871}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004872#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004873
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004874#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004875void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4876{
4877 eCsrBand band = -1;
4878 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4879 switch (band)
4880 {
4881 case eCSR_BAND_ALL:
4882 *pBand = WLAN_HDD_UI_BAND_AUTO;
4883 break;
4884
4885 case eCSR_BAND_24:
4886 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4887 break;
4888
4889 case eCSR_BAND_5G:
4890 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4891 break;
4892
4893 default:
4894 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4895 *pBand = -1;
4896 break;
4897 }
4898}
4899
4900/**---------------------------------------------------------------------------
4901
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004902 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4903
4904 This function parses the send action frame data passed in the format
4905 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4906
Srinivas Girigowda56076852013-08-20 14:00:50 -07004907 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004908 \param - pTargetApBssid Pointer to target Ap bssid
4909 \param - pChannel Pointer to the Target AP channel
4910 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4911 \param - pBuf Pointer to data
4912 \param - pBufLen Pointer to data length
4913
4914 \return - 0 for success non-zero for failure
4915
4916 --------------------------------------------------------------------------*/
4917VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4918 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4919{
4920 tANI_U8 *inPtr = pValue;
4921 tANI_U8 *dataEnd;
4922 int tempInt;
4923 int j = 0;
4924 int i = 0;
4925 int v = 0;
4926 tANI_U8 tempBuf[32];
4927 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004928 /* 12 hexa decimal digits, 5 ':' and '\0' */
4929 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004930
4931 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4932 /*no argument after the command*/
4933 if (NULL == inPtr)
4934 {
4935 return -EINVAL;
4936 }
4937
4938 /*no space after the command*/
4939 else if (SPACE_ASCII_VALUE != *inPtr)
4940 {
4941 return -EINVAL;
4942 }
4943
4944 /*removing empty spaces*/
4945 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4946
4947 /*no argument followed by spaces*/
4948 if ('\0' == *inPtr)
4949 {
4950 return -EINVAL;
4951 }
4952
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004953 v = sscanf(inPtr, "%17s", macAddress);
4954 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004955 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4957 "Invalid MAC address or All hex inputs are not read (%d)", v);
4958 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004959 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004960
4961 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4962 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4963 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4964 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4965 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4966 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004967
4968 /* point to the next argument */
4969 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4970 /*no argument after the command*/
4971 if (NULL == inPtr) return -EINVAL;
4972
4973 /*removing empty spaces*/
4974 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4975
4976 /*no argument followed by spaces*/
4977 if ('\0' == *inPtr)
4978 {
4979 return -EINVAL;
4980 }
4981
4982 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004983 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004984 if (1 != v) return -EINVAL;
4985
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004986 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304987 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304988 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004989
4990 *pChannel = tempInt;
4991
4992 /* point to the next argument */
4993 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4994 /*no argument after the command*/
4995 if (NULL == inPtr) return -EINVAL;
4996 /*removing empty spaces*/
4997 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4998
4999 /*no argument followed by spaces*/
5000 if ('\0' == *inPtr)
5001 {
5002 return -EINVAL;
5003 }
5004
5005 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005006 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005007 if (1 != v) return -EINVAL;
5008
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005009 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005010 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005011
5012 *pDwellTime = tempInt;
5013
5014 /* point to the next argument */
5015 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5016 /*no argument after the command*/
5017 if (NULL == inPtr) return -EINVAL;
5018 /*removing empty spaces*/
5019 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5020
5021 /*no argument followed by spaces*/
5022 if ('\0' == *inPtr)
5023 {
5024 return -EINVAL;
5025 }
5026
5027 /* find the length of data */
5028 dataEnd = inPtr;
5029 while(('\0' != *dataEnd) )
5030 {
5031 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005032 }
Kiet Lambe150c22013-11-21 16:30:32 +05305033 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005034 if ( *pBufLen <= 0) return -EINVAL;
5035
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005036 /* Allocate the number of bytes based on the number of input characters
5037 whether it is even or odd.
5038 if the number of input characters are even, then we need N/2 byte.
5039 if the number of input characters are odd, then we need do (N+1)/2 to
5040 compensate rounding off.
5041 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5042 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5043 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005044 if (NULL == *pBuf)
5045 {
5046 hddLog(VOS_TRACE_LEVEL_FATAL,
5047 "%s: vos_mem_alloc failed ", __func__);
5048 return -EINVAL;
5049 }
5050
5051 /* the buffer received from the upper layer is character buffer,
5052 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5053 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5054 and f0 in 3rd location */
5055 for (i = 0, j = 0; j < *pBufLen; j += 2)
5056 {
Kiet Lambe150c22013-11-21 16:30:32 +05305057 if( j+1 == *pBufLen)
5058 {
5059 tempByte = hdd_parse_hex(inPtr[j]);
5060 }
5061 else
5062 {
5063 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5064 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005065 (*pBuf)[i++] = tempByte;
5066 }
5067 *pBufLen = i;
5068 return VOS_STATUS_SUCCESS;
5069}
5070
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005071/**---------------------------------------------------------------------------
5072
Srinivas Girigowdade697412013-02-14 16:31:48 -08005073 \brief hdd_parse_channellist() - HDD Parse channel list
5074
5075 This function parses the channel list passed in the format
5076 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005077 if the Number of channels (N) does not match with the actual number of channels passed
5078 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5079 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5080 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5081 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005082
5083 \param - pValue Pointer to input channel list
5084 \param - ChannelList Pointer to local output array to record channel list
5085 \param - pNumChannels Pointer to number of roam scan channels
5086
5087 \return - 0 for success non-zero for failure
5088
5089 --------------------------------------------------------------------------*/
5090VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5091{
5092 tANI_U8 *inPtr = pValue;
5093 int tempInt;
5094 int j = 0;
5095 int v = 0;
5096 char buf[32];
5097
5098 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5099 /*no argument after the command*/
5100 if (NULL == inPtr)
5101 {
5102 return -EINVAL;
5103 }
5104
5105 /*no space after the command*/
5106 else if (SPACE_ASCII_VALUE != *inPtr)
5107 {
5108 return -EINVAL;
5109 }
5110
5111 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005112 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005113
5114 /*no argument followed by spaces*/
5115 if ('\0' == *inPtr)
5116 {
5117 return -EINVAL;
5118 }
5119
5120 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005121 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005122 if (1 != v) return -EINVAL;
5123
Srinivas Girigowdade697412013-02-14 16:31:48 -08005124 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005125 if ((v < 0) ||
5126 (tempInt <= 0) ||
5127 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5128 {
5129 return -EINVAL;
5130 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005131
5132 *pNumChannels = tempInt;
5133
5134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5135 "Number of channels are: %d", *pNumChannels);
5136
5137 for (j = 0; j < (*pNumChannels); j++)
5138 {
5139 /*inPtr pointing to the beginning of first space after number of channels*/
5140 inPtr = strpbrk( inPtr, " " );
5141 /*no channel list after the number of channels argument*/
5142 if (NULL == inPtr)
5143 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005144 if (0 != j)
5145 {
5146 *pNumChannels = j;
5147 return VOS_STATUS_SUCCESS;
5148 }
5149 else
5150 {
5151 return -EINVAL;
5152 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005153 }
5154
5155 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005156 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005157
5158 /*no channel list after the number of channels argument and spaces*/
5159 if ( '\0' == *inPtr )
5160 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005161 if (0 != j)
5162 {
5163 *pNumChannels = j;
5164 return VOS_STATUS_SUCCESS;
5165 }
5166 else
5167 {
5168 return -EINVAL;
5169 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005170 }
5171
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005172 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005173 if (1 != v) return -EINVAL;
5174
Srinivas Girigowdade697412013-02-14 16:31:48 -08005175 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005176 if ((v < 0) ||
5177 (tempInt <= 0) ||
5178 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5179 {
5180 return -EINVAL;
5181 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005182 pChannelList[j] = tempInt;
5183
5184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5185 "Channel %d added to preferred channel list",
5186 pChannelList[j] );
5187 }
5188
Srinivas Girigowdade697412013-02-14 16:31:48 -08005189 return VOS_STATUS_SUCCESS;
5190}
5191
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005192
5193/**---------------------------------------------------------------------------
5194
5195 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5196
5197 This function parses the reasoc command data passed in the format
5198 REASSOC<space><bssid><space><channel>
5199
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005200 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005201 \param - pTargetApBssid Pointer to target Ap bssid
5202 \param - pChannel Pointer to the Target AP channel
5203
5204 \return - 0 for success non-zero for failure
5205
5206 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005207VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5208 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005209{
5210 tANI_U8 *inPtr = pValue;
5211 int tempInt;
5212 int v = 0;
5213 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005214 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005215 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005216
5217 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5218 /*no argument after the command*/
5219 if (NULL == inPtr)
5220 {
5221 return -EINVAL;
5222 }
5223
5224 /*no space after the command*/
5225 else if (SPACE_ASCII_VALUE != *inPtr)
5226 {
5227 return -EINVAL;
5228 }
5229
5230 /*removing empty spaces*/
5231 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5232
5233 /*no argument followed by spaces*/
5234 if ('\0' == *inPtr)
5235 {
5236 return -EINVAL;
5237 }
5238
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005239 v = sscanf(inPtr, "%17s", macAddress);
5240 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005241 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5243 "Invalid MAC address or All hex inputs are not read (%d)", v);
5244 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005245 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005246
5247 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5248 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5249 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5250 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5251 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5252 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005253
5254 /* point to the next argument */
5255 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5256 /*no argument after the command*/
5257 if (NULL == inPtr) return -EINVAL;
5258
5259 /*removing empty spaces*/
5260 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5261
5262 /*no argument followed by spaces*/
5263 if ('\0' == *inPtr)
5264 {
5265 return -EINVAL;
5266 }
5267
5268 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005269 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005270 if (1 != v) return -EINVAL;
5271
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005272 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005273 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305274 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005275 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5276 {
5277 return -EINVAL;
5278 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005279
5280 *pChannel = tempInt;
5281 return VOS_STATUS_SUCCESS;
5282}
5283
5284#endif
5285
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005286#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005287/**---------------------------------------------------------------------------
5288
5289 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5290
5291 This function parses the SETCCKM IE command
5292 SETCCKMIE<space><ie data>
5293
5294 \param - pValue Pointer to input data
5295 \param - pCckmIe Pointer to output cckm Ie
5296 \param - pCckmIeLen Pointer to output cckm ie length
5297
5298 \return - 0 for success non-zero for failure
5299
5300 --------------------------------------------------------------------------*/
5301VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5302 tANI_U8 *pCckmIeLen)
5303{
5304 tANI_U8 *inPtr = pValue;
5305 tANI_U8 *dataEnd;
5306 int j = 0;
5307 int i = 0;
5308 tANI_U8 tempByte = 0;
5309
5310 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5311 /*no argument after the command*/
5312 if (NULL == inPtr)
5313 {
5314 return -EINVAL;
5315 }
5316
5317 /*no space after the command*/
5318 else if (SPACE_ASCII_VALUE != *inPtr)
5319 {
5320 return -EINVAL;
5321 }
5322
5323 /*removing empty spaces*/
5324 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5325
5326 /*no argument followed by spaces*/
5327 if ('\0' == *inPtr)
5328 {
5329 return -EINVAL;
5330 }
5331
5332 /* find the length of data */
5333 dataEnd = inPtr;
5334 while(('\0' != *dataEnd) )
5335 {
5336 dataEnd++;
5337 ++(*pCckmIeLen);
5338 }
5339 if ( *pCckmIeLen <= 0) return -EINVAL;
5340
5341 /* Allocate the number of bytes based on the number of input characters
5342 whether it is even or odd.
5343 if the number of input characters are even, then we need N/2 byte.
5344 if the number of input characters are odd, then we need do (N+1)/2 to
5345 compensate rounding off.
5346 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5347 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5348 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5349 if (NULL == *pCckmIe)
5350 {
5351 hddLog(VOS_TRACE_LEVEL_FATAL,
5352 "%s: vos_mem_alloc failed ", __func__);
5353 return -EINVAL;
5354 }
5355 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5356 /* the buffer received from the upper layer is character buffer,
5357 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5358 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5359 and f0 in 3rd location */
5360 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5361 {
5362 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5363 (*pCckmIe)[i++] = tempByte;
5364 }
5365 *pCckmIeLen = i;
5366
5367 return VOS_STATUS_SUCCESS;
5368}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005369#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005370
Jeff Johnson295189b2012-06-20 16:38:30 -07005371/**---------------------------------------------------------------------------
5372
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005373 \brief hdd_is_valid_mac_address() - Validate MAC address
5374
5375 This function validates whether the given MAC address is valid or not
5376 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5377 where X is the hexa decimal digit character and separated by ':'
5378 This algorithm works even if MAC address is not separated by ':'
5379
5380 This code checks given input string mac contains exactly 12 hexadecimal digits.
5381 and a separator colon : appears in the input string only after
5382 an even number of hex digits.
5383
5384 \param - pMacAddr pointer to the input MAC address
5385 \return - 1 for valid and 0 for invalid
5386
5387 --------------------------------------------------------------------------*/
5388
5389v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5390{
5391 int xdigit = 0;
5392 int separator = 0;
5393 while (*pMacAddr)
5394 {
5395 if (isxdigit(*pMacAddr))
5396 {
5397 xdigit++;
5398 }
5399 else if (':' == *pMacAddr)
5400 {
5401 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5402 break;
5403
5404 ++separator;
5405 }
5406 else
5407 {
5408 separator = -1;
5409 /* Invalid MAC found */
5410 return 0;
5411 }
5412 ++pMacAddr;
5413 }
5414 return (xdigit == 12 && (separator == 5 || separator == 0));
5415}
5416
5417/**---------------------------------------------------------------------------
5418
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305419 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005420
5421 \param - dev Pointer to net_device structure
5422
5423 \return - 0 for success non-zero for failure
5424
5425 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305426int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005427{
5428 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5429 hdd_context_t *pHddCtx;
5430 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5431 VOS_STATUS status;
5432 v_BOOL_t in_standby = TRUE;
5433
5434 if (NULL == pAdapter)
5435 {
5436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305437 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 return -ENODEV;
5439 }
5440
5441 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305442 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5443 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005444 if (NULL == pHddCtx)
5445 {
5446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005447 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005448 return -ENODEV;
5449 }
5450
5451 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5452 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5453 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005454 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5455 {
5456 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305457 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005458 in_standby = FALSE;
5459 break;
5460 }
5461 else
5462 {
5463 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5464 pAdapterNode = pNext;
5465 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 }
5467
5468 if (TRUE == in_standby)
5469 {
5470 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5471 {
5472 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5473 "wlan out of power save", __func__);
5474 return -EINVAL;
5475 }
5476 }
5477
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005478 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5480 {
5481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005482 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005483 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305484 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005485 netif_tx_start_all_queues(dev);
5486 }
5487
5488 return 0;
5489}
5490
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305491/**---------------------------------------------------------------------------
5492
5493 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5494
5495 This is called in response to ifconfig up
5496
5497 \param - dev Pointer to net_device structure
5498
5499 \return - 0 for success non-zero for failure
5500
5501 --------------------------------------------------------------------------*/
5502int hdd_open(struct net_device *dev)
5503{
5504 int ret;
5505
5506 vos_ssr_protect(__func__);
5507 ret = __hdd_open(dev);
5508 vos_ssr_unprotect(__func__);
5509
5510 return ret;
5511}
5512
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305513int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005514{
5515 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5516
5517 if(pAdapter == NULL) {
5518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005519 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005520 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 }
5522
Jeff Johnson295189b2012-06-20 16:38:30 -07005523 return 0;
5524}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305525
5526int hdd_mon_open (struct net_device *dev)
5527{
5528 int ret;
5529
5530 vos_ssr_protect(__func__);
5531 ret = __hdd_mon_open(dev);
5532 vos_ssr_unprotect(__func__);
5533
5534 return ret;
5535}
5536
Katya Nigame7b69a82015-04-28 15:24:06 +05305537int hdd_mon_stop(struct net_device *dev)
5538{
5539 return 0;
5540}
5541
Jeff Johnson295189b2012-06-20 16:38:30 -07005542/**---------------------------------------------------------------------------
5543
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305544 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005545
5546 \param - dev Pointer to net_device structure
5547
5548 \return - 0 for success non-zero for failure
5549
5550 --------------------------------------------------------------------------*/
5551
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305552int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005553{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305554 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005555 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5556 hdd_context_t *pHddCtx;
5557 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5558 VOS_STATUS status;
5559 v_BOOL_t enter_standby = TRUE;
5560
5561 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005562 if (NULL == pAdapter)
5563 {
5564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305565 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 return -ENODEV;
5567 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305568 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305569 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305570
5571 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5572 ret = wlan_hdd_validate_context(pHddCtx);
5573 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305575 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 }
5577
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305578 /* Nothing to be done if the interface is not opened */
5579 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5580 {
5581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5582 "%s: NETDEV Interface is not OPENED", __func__);
5583 return -ENODEV;
5584 }
5585
5586 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005587 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305589
5590 /* Disable TX on the interface, after this hard_start_xmit() will not
5591 * be called on that interface
5592 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305593 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005594 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305595
5596 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005597 netif_carrier_off(pAdapter->dev);
5598
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305599 /* The interface is marked as down for outside world (aka kernel)
5600 * But the driver is pretty much alive inside. The driver needs to
5601 * tear down the existing connection on the netdev (session)
5602 * cleanup the data pipes and wait until the control plane is stabilized
5603 * for this interface. The call also needs to wait until the above
5604 * mentioned actions are completed before returning to the caller.
5605 * Notice that the hdd_stop_adapter is requested not to close the session
5606 * That is intentional to be able to scan if it is a STA/P2P interface
5607 */
5608 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305609#ifdef FEATURE_WLAN_TDLS
5610 mutex_lock(&pHddCtx->tdls_lock);
5611#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305612 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305613 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305614#ifdef FEATURE_WLAN_TDLS
5615 mutex_unlock(&pHddCtx->tdls_lock);
5616#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 /* SoftAP ifaces should never go in power save mode
5618 making sure same here. */
5619 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5620 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 )
5623 {
5624 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5626 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005627 EXIT();
5628 return 0;
5629 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305630 /* Find if any iface is up. If any iface is up then can't put device to
5631 * sleep/power save mode
5632 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5634 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5635 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005636 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5637 {
5638 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305639 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005640 enter_standby = FALSE;
5641 break;
5642 }
5643 else
5644 {
5645 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5646 pAdapterNode = pNext;
5647 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005648 }
5649
5650 if (TRUE == enter_standby)
5651 {
5652 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5653 "entering standby", __func__);
5654 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5655 {
5656 /*log and return success*/
5657 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5658 "wlan in power save", __func__);
5659 }
5660 }
5661
5662 EXIT();
5663 return 0;
5664}
5665
5666/**---------------------------------------------------------------------------
5667
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305668 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005669
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305670 This is called in response to ifconfig down
5671
5672 \param - dev Pointer to net_device structure
5673
5674 \return - 0 for success non-zero for failure
5675-----------------------------------------------------------------------------*/
5676int hdd_stop (struct net_device *dev)
5677{
5678 int ret;
5679
5680 vos_ssr_protect(__func__);
5681 ret = __hdd_stop(dev);
5682 vos_ssr_unprotect(__func__);
5683
5684 return ret;
5685}
5686
5687/**---------------------------------------------------------------------------
5688
5689 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005690
5691 \param - dev Pointer to net_device structure
5692
5693 \return - void
5694
5695 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305696static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005697{
5698 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305699 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005700 ENTER();
5701
5702 do
5703 {
5704 if (NULL == pAdapter)
5705 {
5706 hddLog(VOS_TRACE_LEVEL_FATAL,
5707 "%s: NULL pAdapter", __func__);
5708 break;
5709 }
5710
5711 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5712 {
5713 hddLog(VOS_TRACE_LEVEL_FATAL,
5714 "%s: Invalid magic", __func__);
5715 break;
5716 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305717 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5718 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005719 {
5720 hddLog(VOS_TRACE_LEVEL_FATAL,
5721 "%s: NULL pHddCtx", __func__);
5722 break;
5723 }
5724
5725 if (dev != pAdapter->dev)
5726 {
5727 hddLog(VOS_TRACE_LEVEL_FATAL,
5728 "%s: Invalid device reference", __func__);
5729 /* we haven't validated all cases so let this go for now */
5730 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305731#ifdef FEATURE_WLAN_TDLS
5732 mutex_lock(&pHddCtx->tdls_lock);
5733#endif
c_hpothu002231a2015-02-05 14:58:51 +05305734 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305735#ifdef FEATURE_WLAN_TDLS
5736 mutex_unlock(&pHddCtx->tdls_lock);
5737#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005738
5739 /* after uninit our adapter structure will no longer be valid */
5740 pAdapter->dev = NULL;
5741 pAdapter->magic = 0;
5742 } while (0);
5743
5744 EXIT();
5745}
5746
5747/**---------------------------------------------------------------------------
5748
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305749 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5750
5751 This is called during the netdev unregister to uninitialize all data
5752associated with the device
5753
5754 \param - dev Pointer to net_device structure
5755
5756 \return - void
5757
5758 --------------------------------------------------------------------------*/
5759static void hdd_uninit (struct net_device *dev)
5760{
5761 vos_ssr_protect(__func__);
5762 __hdd_uninit(dev);
5763 vos_ssr_unprotect(__func__);
5764}
5765
5766/**---------------------------------------------------------------------------
5767
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 \brief hdd_release_firmware() -
5769
5770 This function calls the release firmware API to free the firmware buffer.
5771
5772 \param - pFileName Pointer to the File Name.
5773 pCtx - Pointer to the adapter .
5774
5775
5776 \return - 0 for success, non zero for failure
5777
5778 --------------------------------------------------------------------------*/
5779
5780VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5781{
5782 VOS_STATUS status = VOS_STATUS_SUCCESS;
5783 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5784 ENTER();
5785
5786
5787 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5788
5789 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5790
5791 if(pHddCtx->fw) {
5792 release_firmware(pHddCtx->fw);
5793 pHddCtx->fw = NULL;
5794 }
5795 else
5796 status = VOS_STATUS_E_FAILURE;
5797 }
5798 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5799 if(pHddCtx->nv) {
5800 release_firmware(pHddCtx->nv);
5801 pHddCtx->nv = NULL;
5802 }
5803 else
5804 status = VOS_STATUS_E_FAILURE;
5805
5806 }
5807
5808 EXIT();
5809 return status;
5810}
5811
5812/**---------------------------------------------------------------------------
5813
5814 \brief hdd_request_firmware() -
5815
5816 This function reads the firmware file using the request firmware
5817 API and returns the the firmware data and the firmware file size.
5818
5819 \param - pfileName - Pointer to the file name.
5820 - pCtx - Pointer to the adapter .
5821 - ppfw_data - Pointer to the pointer of the firmware data.
5822 - pSize - Pointer to the file size.
5823
5824 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5825
5826 --------------------------------------------------------------------------*/
5827
5828
5829VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5830{
5831 int status;
5832 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5833 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5834 ENTER();
5835
5836 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5837
5838 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5839
5840 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5841 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5842 __func__, pfileName);
5843 retval = VOS_STATUS_E_FAILURE;
5844 }
5845
5846 else {
5847 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5848 *pSize = pHddCtx->fw->size;
5849 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5850 __func__, *pSize);
5851 }
5852 }
5853 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5854
5855 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5856
5857 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5858 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5859 __func__, pfileName);
5860 retval = VOS_STATUS_E_FAILURE;
5861 }
5862
5863 else {
5864 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5865 *pSize = pHddCtx->nv->size;
5866 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5867 __func__, *pSize);
5868 }
5869 }
5870
5871 EXIT();
5872 return retval;
5873}
5874/**---------------------------------------------------------------------------
5875 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5876
5877 This is the function invoked by SME to inform the result of a full power
5878 request issued by HDD
5879
5880 \param - callbackcontext - Pointer to cookie
5881 status - result of request
5882
5883 \return - None
5884
5885--------------------------------------------------------------------------*/
5886void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5887{
5888 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5889
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005890 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005891 if(&pHddCtx->full_pwr_comp_var)
5892 {
5893 complete(&pHddCtx->full_pwr_comp_var);
5894 }
5895}
5896
5897/**---------------------------------------------------------------------------
5898
5899 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5900
5901 This is the function invoked by SME to inform the result of BMPS
5902 request issued by HDD
5903
5904 \param - callbackcontext - Pointer to cookie
5905 status - result of request
5906
5907 \return - None
5908
5909--------------------------------------------------------------------------*/
5910void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5911{
5912
5913 struct completion *completion_var = (struct completion*) callbackContext;
5914
Arif Hussain6d2a3322013-11-17 19:50:10 -08005915 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 if(completion_var != NULL)
5917 {
5918 complete(completion_var);
5919 }
5920}
5921
5922/**---------------------------------------------------------------------------
5923
5924 \brief hdd_get_cfg_file_size() -
5925
5926 This function reads the configuration file using the request firmware
5927 API and returns the configuration file size.
5928
5929 \param - pCtx - Pointer to the adapter .
5930 - pFileName - Pointer to the file name.
5931 - pBufSize - Pointer to the buffer size.
5932
5933 \return - 0 for success, non zero for failure
5934
5935 --------------------------------------------------------------------------*/
5936
5937VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5938{
5939 int status;
5940 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5941
5942 ENTER();
5943
5944 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5945
5946 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5947 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5948 status = VOS_STATUS_E_FAILURE;
5949 }
5950 else {
5951 *pBufSize = pHddCtx->fw->size;
5952 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5953 release_firmware(pHddCtx->fw);
5954 pHddCtx->fw = NULL;
5955 }
5956
5957 EXIT();
5958 return VOS_STATUS_SUCCESS;
5959}
5960
5961/**---------------------------------------------------------------------------
5962
5963 \brief hdd_read_cfg_file() -
5964
5965 This function reads the configuration file using the request firmware
5966 API and returns the cfg data and the buffer size of the configuration file.
5967
5968 \param - pCtx - Pointer to the adapter .
5969 - pFileName - Pointer to the file name.
5970 - pBuffer - Pointer to the data buffer.
5971 - pBufSize - Pointer to the buffer size.
5972
5973 \return - 0 for success, non zero for failure
5974
5975 --------------------------------------------------------------------------*/
5976
5977VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5978 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5979{
5980 int status;
5981 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5982
5983 ENTER();
5984
5985 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5986
5987 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5988 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5989 return VOS_STATUS_E_FAILURE;
5990 }
5991 else {
5992 if(*pBufSize != pHddCtx->fw->size) {
5993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5994 "file size", __func__);
5995 release_firmware(pHddCtx->fw);
5996 pHddCtx->fw = NULL;
5997 return VOS_STATUS_E_FAILURE;
5998 }
5999 else {
6000 if(pBuffer) {
6001 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
6002 }
6003 release_firmware(pHddCtx->fw);
6004 pHddCtx->fw = NULL;
6005 }
6006 }
6007
6008 EXIT();
6009
6010 return VOS_STATUS_SUCCESS;
6011}
6012
6013/**---------------------------------------------------------------------------
6014
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306015 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006016
6017 This function sets the user specified mac address using
6018 the command ifconfig wlanX hw ether <mac adress>.
6019
6020 \param - dev - Pointer to the net device.
6021 - addr - Pointer to the sockaddr.
6022 \return - 0 for success, non zero for failure
6023
6024 --------------------------------------------------------------------------*/
6025
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306026static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006027{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306028 hdd_adapter_t *pAdapter;
6029 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 struct sockaddr *psta_mac_addr = addr;
6031 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306032 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006033
6034 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306035 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6036 if (NULL == pAdapter)
6037 {
6038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6039 "%s: Adapter is NULL",__func__);
6040 return -EINVAL;
6041 }
6042 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6043 ret = wlan_hdd_validate_context(pHddCtx);
6044 if (0 != ret)
6045 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306046 return ret;
6047 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006048
6049 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6051
6052 EXIT();
6053 return halStatus;
6054}
6055
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306056/**---------------------------------------------------------------------------
6057
6058 \brief hdd_set_mac_address() -
6059
6060 Wrapper function to protect __hdd_set_mac_address() function from ssr
6061
6062 \param - dev - Pointer to the net device.
6063 - addr - Pointer to the sockaddr.
6064 \return - 0 for success, non zero for failure
6065
6066 --------------------------------------------------------------------------*/
6067static int hdd_set_mac_address(struct net_device *dev, void *addr)
6068{
6069 int ret;
6070
6071 vos_ssr_protect(__func__);
6072 ret = __hdd_set_mac_address(dev, addr);
6073 vos_ssr_unprotect(__func__);
6074
6075 return ret;
6076}
6077
Jeff Johnson295189b2012-06-20 16:38:30 -07006078tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6079{
6080 int i;
6081 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6082 {
Abhishek Singheb183782014-02-06 13:37:21 +05306083 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006084 break;
6085 }
6086
6087 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6088 return NULL;
6089
6090 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6091 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6092}
6093
6094void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6095{
6096 int i;
6097 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6098 {
6099 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6100 {
6101 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6102 break;
6103 }
6104 }
6105 return;
6106}
6107
6108#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6109 static struct net_device_ops wlan_drv_ops = {
6110 .ndo_open = hdd_open,
6111 .ndo_stop = hdd_stop,
6112 .ndo_uninit = hdd_uninit,
6113 .ndo_start_xmit = hdd_hard_start_xmit,
6114 .ndo_tx_timeout = hdd_tx_timeout,
6115 .ndo_get_stats = hdd_stats,
6116 .ndo_do_ioctl = hdd_ioctl,
6117 .ndo_set_mac_address = hdd_set_mac_address,
6118 .ndo_select_queue = hdd_select_queue,
6119#ifdef WLAN_FEATURE_PACKET_FILTERING
6120#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6121 .ndo_set_rx_mode = hdd_set_multicast_list,
6122#else
6123 .ndo_set_multicast_list = hdd_set_multicast_list,
6124#endif //LINUX_VERSION_CODE
6125#endif
6126 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 static struct net_device_ops wlan_mon_drv_ops = {
6128 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306129 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006130 .ndo_uninit = hdd_uninit,
6131 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6132 .ndo_tx_timeout = hdd_tx_timeout,
6133 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306134 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006135 .ndo_set_mac_address = hdd_set_mac_address,
6136 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306137
Jeff Johnson295189b2012-06-20 16:38:30 -07006138#endif
6139
6140void hdd_set_station_ops( struct net_device *pWlanDev )
6141{
6142#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006143 pWlanDev->netdev_ops = &wlan_drv_ops;
6144#else
6145 pWlanDev->open = hdd_open;
6146 pWlanDev->stop = hdd_stop;
6147 pWlanDev->uninit = hdd_uninit;
6148 pWlanDev->hard_start_xmit = NULL;
6149 pWlanDev->tx_timeout = hdd_tx_timeout;
6150 pWlanDev->get_stats = hdd_stats;
6151 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 pWlanDev->set_mac_address = hdd_set_mac_address;
6153#endif
6154}
6155
Katya Nigam1fd24402015-02-16 14:52:19 +05306156void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6157{
6158 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6159 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6160 #else
6161 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6162 #endif
6163}
6164
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006165static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006166{
6167 struct net_device *pWlanDev = NULL;
6168 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006169 /*
6170 * cfg80211 initialization and registration....
6171 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05306172 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
6173#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
6174 NET_NAME_UNKNOWN,
6175#endif
6176 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 if(pWlanDev != NULL)
6178 {
6179
6180 //Save the pointer to the net_device in the HDD adapter
6181 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6182
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6184
6185 pAdapter->dev = pWlanDev;
6186 pAdapter->pHddCtx = pHddCtx;
6187 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306188 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006189
6190 init_completion(&pAdapter->session_open_comp_var);
6191 init_completion(&pAdapter->session_close_comp_var);
6192 init_completion(&pAdapter->disconnect_comp_var);
6193 init_completion(&pAdapter->linkup_event_var);
6194 init_completion(&pAdapter->cancel_rem_on_chan_var);
6195 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306196 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006197#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6198 init_completion(&pAdapter->offchannel_tx_event);
6199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006200 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006201#ifdef FEATURE_WLAN_TDLS
6202 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006203 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006204 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306205 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006206#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006207 init_completion(&pHddCtx->mc_sus_event_var);
6208 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306209 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006210 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006211 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006212
Rajeev79dbe4c2013-10-05 11:03:42 +05306213#ifdef FEATURE_WLAN_BATCH_SCAN
6214 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6215 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6216 pAdapter->pBatchScanRsp = NULL;
6217 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006218 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006219 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306220 mutex_init(&pAdapter->hdd_batch_scan_lock);
6221#endif
6222
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 pAdapter->isLinkUpSvcNeeded = FALSE;
6224 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6225 //Init the net_device structure
6226 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6227
6228 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6229 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6230 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6231 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6232
6233 hdd_set_station_ops( pAdapter->dev );
6234
6235 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6237 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6238 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006239 /* set pWlanDev's parent to underlying device */
6240 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006241
6242 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006243 }
6244
6245 return pAdapter;
6246}
6247
6248VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6249{
6250 struct net_device *pWlanDev = pAdapter->dev;
6251 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6252 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6253 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6254
6255 if( rtnl_lock_held )
6256 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006257 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6259 {
6260 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6261 return VOS_STATUS_E_FAILURE;
6262 }
6263 }
6264 if (register_netdevice(pWlanDev))
6265 {
6266 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6267 return VOS_STATUS_E_FAILURE;
6268 }
6269 }
6270 else
6271 {
6272 if(register_netdev(pWlanDev))
6273 {
6274 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6275 return VOS_STATUS_E_FAILURE;
6276 }
6277 }
6278 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6279
6280 return VOS_STATUS_SUCCESS;
6281}
6282
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006283static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006284{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006285 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006286
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006287 if (NULL == pAdapter)
6288 {
6289 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6290 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006292
6293 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6294 {
6295 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6296 return eHAL_STATUS_NOT_INITIALIZED;
6297 }
6298
6299 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6300
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006301#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006302 /* need to make sure all of our scheduled work has completed.
6303 * This callback is called from MC thread context, so it is safe to
6304 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006305 *
6306 * Even though this is called from MC thread context, if there is a faulty
6307 * work item in the system, that can hang this call forever. So flushing
6308 * this global work queue is not safe; and now we make sure that
6309 * individual work queues are stopped correctly. But the cancel work queue
6310 * is a GPL only API, so the proprietary version of the driver would still
6311 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006312 */
6313 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006314#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006315
6316 /* We can be blocked while waiting for scheduled work to be
6317 * flushed, and the adapter structure can potentially be freed, in
6318 * which case the magic will have been reset. So make sure the
6319 * magic is still good, and hence the adapter structure is still
6320 * valid, before signaling completion */
6321 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6322 {
6323 complete(&pAdapter->session_close_comp_var);
6324 }
6325
Jeff Johnson295189b2012-06-20 16:38:30 -07006326 return eHAL_STATUS_SUCCESS;
6327}
6328
6329VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6330{
6331 struct net_device *pWlanDev = pAdapter->dev;
6332 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6333 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6334 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6335 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306336 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006337
Nirav Shah7e3c8132015-06-22 23:51:42 +05306338 spin_lock_init( &pAdapter->sta_hash_lock);
6339 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6340
Jeff Johnson295189b2012-06-20 16:38:30 -07006341 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006342 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 //Open a SME session for future operation
6344 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006345 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6347 {
6348 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006349 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 halStatus, halStatus );
6351 status = VOS_STATUS_E_FAILURE;
6352 goto error_sme_open;
6353 }
6354
6355 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306356 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 &pAdapter->session_open_comp_var,
6358 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306359 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 {
6361 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306362 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 status = VOS_STATUS_E_FAILURE;
6364 goto error_sme_open;
6365 }
6366
6367 // Register wireless extensions
6368 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6369 {
6370 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006371 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 halStatus, halStatus );
6373 status = VOS_STATUS_E_FAILURE;
6374 goto error_register_wext;
6375 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306376
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306378 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6379 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6380 #else
6381 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6382 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006383
6384 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306385 hddLog(VOS_TRACE_LEVEL_INFO,
6386 "%s: Set HDD connState to eConnectionState_NotConnected",
6387 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006388 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6389
6390 //Set the default operation channel
6391 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6392
6393 /* Make the default Auth Type as OPEN*/
6394 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6395
6396 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6397 {
6398 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006399 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 status, status );
6401 goto error_init_txrx;
6402 }
6403
6404 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6405
6406 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6407 {
6408 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006409 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006410 status, status );
6411 goto error_wmm_init;
6412 }
6413
6414 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6415
6416 return VOS_STATUS_SUCCESS;
6417
6418error_wmm_init:
6419 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6420 hdd_deinit_tx_rx(pAdapter);
6421error_init_txrx:
6422 hdd_UnregisterWext(pWlanDev);
6423error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006424 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 {
6426 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006427 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306428 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006429 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306431 unsigned long rc;
6432
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306434 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006435 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006436 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306437 if (rc <= 0)
6438 hddLog(VOS_TRACE_LEVEL_ERROR,
6439 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006440 }
6441}
6442error_sme_open:
6443 return status;
6444}
6445
Jeff Johnson295189b2012-06-20 16:38:30 -07006446void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6447{
6448 hdd_cfg80211_state_t *cfgState;
6449
6450 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6451
6452 if( NULL != cfgState->buf )
6453 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306454 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6456 rc = wait_for_completion_interruptible_timeout(
6457 &pAdapter->tx_action_cnf_event,
6458 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306459 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006460 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306462 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6463 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 }
6465 }
6466 return;
6467}
Jeff Johnson295189b2012-06-20 16:38:30 -07006468
c_hpothu002231a2015-02-05 14:58:51 +05306469void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006470{
6471 ENTER();
6472 switch ( pAdapter->device_mode )
6473 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306474 case WLAN_HDD_IBSS:
6475 {
6476 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6477 {
6478 hdd_ibss_deinit_tx_rx( pAdapter );
6479 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6480 }
6481 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 case WLAN_HDD_INFRA_STATION:
6483 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006484 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 {
6486 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6487 {
6488 hdd_deinit_tx_rx( pAdapter );
6489 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6490 }
6491
6492 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6493 {
6494 hdd_wmm_adapter_close( pAdapter );
6495 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6496 }
6497
Jeff Johnson295189b2012-06-20 16:38:30 -07006498 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 break;
6500 }
6501
6502 case WLAN_HDD_SOFTAP:
6503 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306505
6506 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6507 {
6508 hdd_wmm_adapter_close( pAdapter );
6509 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6510 }
6511
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006513
c_hpothu002231a2015-02-05 14:58:51 +05306514 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006515 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 break;
6517 }
6518
6519 case WLAN_HDD_MONITOR:
6520 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006521 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6522 {
6523 hdd_deinit_tx_rx( pAdapter );
6524 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6525 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006526 break;
6527 }
6528
6529
6530 default:
6531 break;
6532 }
6533
6534 EXIT();
6535}
6536
6537void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6538{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006539 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306540
6541 ENTER();
6542 if (NULL == pAdapter)
6543 {
6544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6545 "%s: HDD adapter is Null", __func__);
6546 return;
6547 }
6548
6549 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006550
Rajeev79dbe4c2013-10-05 11:03:42 +05306551#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306552 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6553 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006554 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306555 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6556 )
6557 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006558 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306559 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006560 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6561 {
6562 hdd_deinit_batch_scan(pAdapter);
6563 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306564 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006565 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306566#endif
6567
Jeff Johnson295189b2012-06-20 16:38:30 -07006568 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6569 if( rtnl_held )
6570 {
6571 unregister_netdevice(pWlanDev);
6572 }
6573 else
6574 {
6575 unregister_netdev(pWlanDev);
6576 }
6577 // note that the pAdapter is no longer valid at this point
6578 // since the memory has been reclaimed
6579 }
6580
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306581 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006582}
6583
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006584void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6585{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306586 VOS_STATUS status;
6587 hdd_adapter_t *pAdapter = NULL;
6588 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006589
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306590 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006591
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306592 /*loop through all adapters.*/
6593 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006594 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306595 pAdapter = pAdapterNode->pAdapter;
6596 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6597 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006598
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306599 { // we skip this registration for modes other than STA and P2P client modes.
6600 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6601 pAdapterNode = pNext;
6602 continue;
6603 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006604
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306605 //Apply Dynamic DTIM For P2P
6606 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6607 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6608 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6609 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6610 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6611 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6612 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6613 (eConnectionState_Associated ==
6614 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6615 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6616 {
6617 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006618
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306619 powerRequest.uIgnoreDTIM = 1;
6620 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6621
6622 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6623 {
6624 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6625 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6626 }
6627 else
6628 {
6629 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6630 }
6631
6632 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6633 * specified during Enter/Exit BMPS when LCD off*/
6634 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6635 NULL, eANI_BOOLEAN_FALSE);
6636 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6637 NULL, eANI_BOOLEAN_FALSE);
6638
6639 /* switch to the DTIM specified in cfg.ini */
6640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6641 "Switch to DTIM %d", powerRequest.uListenInterval);
6642 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6643 break;
6644
6645 }
6646
6647 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6648 pAdapterNode = pNext;
6649 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006650}
6651
6652void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6653{
6654 /*Switch back to DTIM 1*/
6655 tSirSetPowerParamsReq powerRequest = { 0 };
6656
6657 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6658 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006659 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006660
6661 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6662 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6663 NULL, eANI_BOOLEAN_FALSE);
6664 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6665 NULL, eANI_BOOLEAN_FALSE);
6666
6667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6668 "Switch to DTIM%d",powerRequest.uListenInterval);
6669 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6670
6671}
6672
Jeff Johnson295189b2012-06-20 16:38:30 -07006673VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6674{
6675 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306676 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6677 {
6678 hddLog( LOGE, FL("Wlan Unload in progress"));
6679 return VOS_STATUS_E_PERM;
6680 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006681 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6682 {
6683 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6684 }
6685
6686 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6687 {
6688 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6689 }
6690
6691 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6692 {
6693 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6694 }
6695
6696 return status;
6697}
6698
6699VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6700{
6701 hdd_adapter_t *pAdapter = NULL;
6702 eHalStatus halStatus;
6703 VOS_STATUS status = VOS_STATUS_E_INVAL;
6704 v_BOOL_t disableBmps = FALSE;
6705 v_BOOL_t disableImps = FALSE;
6706
6707 switch(session_type)
6708 {
6709 case WLAN_HDD_INFRA_STATION:
6710 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006711 case WLAN_HDD_P2P_CLIENT:
6712 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006713 //Exit BMPS -> Is Sta/P2P Client is already connected
6714 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6715 if((NULL != pAdapter)&&
6716 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6717 {
6718 disableBmps = TRUE;
6719 }
6720
6721 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6722 if((NULL != pAdapter)&&
6723 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6724 {
6725 disableBmps = TRUE;
6726 }
6727
6728 //Exit both Bmps and Imps incase of Go/SAP Mode
6729 if((WLAN_HDD_SOFTAP == session_type) ||
6730 (WLAN_HDD_P2P_GO == session_type))
6731 {
6732 disableBmps = TRUE;
6733 disableImps = TRUE;
6734 }
6735
6736 if(TRUE == disableImps)
6737 {
6738 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6739 {
6740 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6741 }
6742 }
6743
6744 if(TRUE == disableBmps)
6745 {
6746 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6747 {
6748 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
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 Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006754 VOS_ASSERT(0);
6755 return status;
6756 }
6757 }
6758
6759 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6760 {
6761 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6762
6763 if(eHAL_STATUS_SUCCESS != halStatus)
6764 {
6765 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006766 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006767 VOS_ASSERT(0);
6768 return status;
6769 }
6770 }
6771 }
6772
6773 if((TRUE == disableBmps) ||
6774 (TRUE == disableImps))
6775 {
6776 /* Now, get the chip into Full Power now */
6777 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6778 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6779 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6780
6781 if(halStatus != eHAL_STATUS_SUCCESS)
6782 {
6783 if(halStatus == eHAL_STATUS_PMC_PENDING)
6784 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306785 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306787 ret = wait_for_completion_interruptible_timeout(
6788 &pHddCtx->full_pwr_comp_var,
6789 msecs_to_jiffies(1000));
6790 if (ret <= 0)
6791 {
6792 hddLog(VOS_TRACE_LEVEL_ERROR,
6793 "%s: wait on full_pwr_comp_var failed %ld",
6794 __func__, ret);
6795 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006796 }
6797 else
6798 {
6799 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006800 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006801 VOS_ASSERT(0);
6802 return status;
6803 }
6804 }
6805
6806 status = VOS_STATUS_SUCCESS;
6807 }
6808
6809 break;
6810 }
6811 return status;
6812}
Katya Nigame7b69a82015-04-28 15:24:06 +05306813void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6814 {
6815 hdd_mon_ctx_t *pMonCtx = NULL;
6816 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6817
6818 pMonCtx->state = 0;
6819 pMonCtx->ChannelNo = 1;
6820 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306821 pMonCtx->crcCheckEnabled = 1;
6822 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6823 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306824 pMonCtx->numOfMacFilters = 0;
6825 }
6826
Jeff Johnson295189b2012-06-20 16:38:30 -07006827
6828hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006829 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006830 tANI_U8 rtnl_held )
6831{
6832 hdd_adapter_t *pAdapter = NULL;
6833 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6834 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6835 VOS_STATUS exitbmpsStatus;
6836
Arif Hussain6d2a3322013-11-17 19:50:10 -08006837 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006838
Nirav Shah436658f2014-02-28 17:05:45 +05306839 if(macAddr == NULL)
6840 {
6841 /* Not received valid macAddr */
6842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6843 "%s:Unable to add virtual intf: Not able to get"
6844 "valid mac address",__func__);
6845 return NULL;
6846 }
6847
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 //Disable BMPS incase of Concurrency
6849 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6850
6851 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6852 {
6853 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306854 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 VOS_ASSERT(0);
6856 return NULL;
6857 }
6858
6859 switch(session_type)
6860 {
6861 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006863 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 {
6865 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6866
6867 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306868 {
6869 hddLog(VOS_TRACE_LEVEL_FATAL,
6870 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306872 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006873
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306874#ifdef FEATURE_WLAN_TDLS
6875 /* A Mutex Lock is introduced while changing/initializing the mode to
6876 * protect the concurrent access for the Adapters by TDLS module.
6877 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306878 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306879#endif
6880
Jeff Johnsone7245742012-09-05 17:12:55 -07006881 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6882 NL80211_IFTYPE_P2P_CLIENT:
6883 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006884
Jeff Johnson295189b2012-06-20 16:38:30 -07006885 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306886#ifdef FEATURE_WLAN_TDLS
6887 mutex_unlock(&pHddCtx->tdls_lock);
6888#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306889
6890 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006891 if( VOS_STATUS_SUCCESS != status )
6892 goto err_free_netdev;
6893
6894 status = hdd_register_interface( pAdapter, rtnl_held );
6895 if( VOS_STATUS_SUCCESS != status )
6896 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306897#ifdef FEATURE_WLAN_TDLS
6898 mutex_lock(&pHddCtx->tdls_lock);
6899#endif
c_hpothu002231a2015-02-05 14:58:51 +05306900 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306901#ifdef FEATURE_WLAN_TDLS
6902 mutex_unlock(&pHddCtx->tdls_lock);
6903#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006904 goto err_free_netdev;
6905 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306906
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306907 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306908 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306909
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306910#ifdef WLAN_NS_OFFLOAD
6911 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306912 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306913#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006914 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306915 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 netif_tx_disable(pAdapter->dev);
6917 //netif_tx_disable(pWlanDev);
6918 netif_carrier_off(pAdapter->dev);
6919
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306920 if (WLAN_HDD_P2P_CLIENT == session_type ||
6921 WLAN_HDD_P2P_DEVICE == session_type)
6922 {
6923 /* Initialize the work queue to defer the
6924 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306925 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306926 hdd_p2p_roc_work_queue);
6927 }
6928
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 break;
6930 }
6931
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 case WLAN_HDD_SOFTAP:
6934 {
6935 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6936 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306937 {
6938 hddLog(VOS_TRACE_LEVEL_FATAL,
6939 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306941 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006942
Jeff Johnson295189b2012-06-20 16:38:30 -07006943 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6944 NL80211_IFTYPE_AP:
6945 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006946 pAdapter->device_mode = session_type;
6947
6948 status = hdd_init_ap_mode(pAdapter);
6949 if( VOS_STATUS_SUCCESS != status )
6950 goto err_free_netdev;
6951
Nirav Shah7e3c8132015-06-22 23:51:42 +05306952 status = hdd_sta_id_hash_attach(pAdapter);
6953 if (VOS_STATUS_SUCCESS != status)
6954 {
6955 hddLog(VOS_TRACE_LEVEL_FATAL,
6956 FL("failed to attach hash for session %d"), session_type);
6957 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6958 goto err_free_netdev;
6959 }
6960
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 status = hdd_register_hostapd( pAdapter, rtnl_held );
6962 if( VOS_STATUS_SUCCESS != status )
6963 {
c_hpothu002231a2015-02-05 14:58:51 +05306964 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006965 goto err_free_netdev;
6966 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306967 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 netif_tx_disable(pAdapter->dev);
6969 netif_carrier_off(pAdapter->dev);
6970
6971 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306972
6973 if (WLAN_HDD_P2P_GO == session_type)
6974 {
6975 /* Initialize the work queue to
6976 * defer the back to back RoC request */
6977 INIT_DELAYED_WORK(&pAdapter->roc_work,
6978 hdd_p2p_roc_work_queue);
6979 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006980 break;
6981 }
6982 case WLAN_HDD_MONITOR:
6983 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6985 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306986 {
6987 hddLog(VOS_TRACE_LEVEL_FATAL,
6988 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006989 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306990 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006991
Katya Nigame7b69a82015-04-28 15:24:06 +05306992 // Register wireless extensions
6993 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6994 {
6995 hddLog(VOS_TRACE_LEVEL_FATAL,
6996 "hdd_register_wext() failed with status code %08d [x%08x]",
6997 status, status );
6998 status = VOS_STATUS_E_FAILURE;
6999 }
7000
Jeff Johnson295189b2012-06-20 16:38:30 -07007001 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
7002 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07007003#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
7004 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
7005#else
7006 pAdapter->dev->open = hdd_mon_open;
7007 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05307008 pAdapter->dev->stop = hdd_mon_stop;
7009 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007010#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307011 status = hdd_register_interface( pAdapter, rtnl_held );
7012 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007013 hdd_init_tx_rx( pAdapter );
7014 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307015 //Stop the Interface TX queue.
7016 netif_tx_disable(pAdapter->dev);
7017 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 }
7019 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007020 case WLAN_HDD_FTM:
7021 {
7022 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7023
7024 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307025 {
7026 hddLog(VOS_TRACE_LEVEL_FATAL,
7027 FL("failed to allocate adapter for session %d"), session_type);
7028 return NULL;
7029 }
7030
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7032 * message while loading driver in FTM mode. */
7033 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7034 pAdapter->device_mode = session_type;
7035 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307036
7037 hdd_init_tx_rx( pAdapter );
7038
7039 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307040 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307041 netif_tx_disable(pAdapter->dev);
7042 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 }
7044 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007045 default:
7046 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307047 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7048 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 VOS_ASSERT(0);
7050 return NULL;
7051 }
7052 }
7053
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 if( VOS_STATUS_SUCCESS == status )
7055 {
7056 //Add it to the hdd's session list.
7057 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7058 if( NULL == pHddAdapterNode )
7059 {
7060 status = VOS_STATUS_E_NOMEM;
7061 }
7062 else
7063 {
7064 pHddAdapterNode->pAdapter = pAdapter;
7065 status = hdd_add_adapter_back ( pHddCtx,
7066 pHddAdapterNode );
7067 }
7068 }
7069
7070 if( VOS_STATUS_SUCCESS != status )
7071 {
7072 if( NULL != pAdapter )
7073 {
7074 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7075 pAdapter = NULL;
7076 }
7077 if( NULL != pHddAdapterNode )
7078 {
7079 vos_mem_free( pHddAdapterNode );
7080 }
7081
7082 goto resume_bmps;
7083 }
7084
7085 if(VOS_STATUS_SUCCESS == status)
7086 {
7087 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7088
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007089 //Initialize the WoWL service
7090 if(!hdd_init_wowl(pAdapter))
7091 {
7092 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7093 goto err_free_netdev;
7094 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007095 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007096 return pAdapter;
7097
7098err_free_netdev:
7099 free_netdev(pAdapter->dev);
7100 wlan_hdd_release_intf_addr( pHddCtx,
7101 pAdapter->macAddressCurrent.bytes );
7102
7103resume_bmps:
7104 //If bmps disabled enable it
7105 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7106 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307107 if (pHddCtx->hdd_wlan_suspended)
7108 {
7109 hdd_set_pwrparams(pHddCtx);
7110 }
7111 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 }
7113 return NULL;
7114}
7115
7116VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7117 tANI_U8 rtnl_held )
7118{
7119 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7120 VOS_STATUS status;
7121
7122 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7123 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307124 {
7125 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7126 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007127 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307128 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007129
7130 while ( pCurrent->pAdapter != pAdapter )
7131 {
7132 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7133 if( VOS_STATUS_SUCCESS != status )
7134 break;
7135
7136 pCurrent = pNext;
7137 }
7138 pAdapterNode = pCurrent;
7139 if( VOS_STATUS_SUCCESS == status )
7140 {
7141 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7142 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307143
7144#ifdef FEATURE_WLAN_TDLS
7145
7146 /* A Mutex Lock is introduced while changing/initializing the mode to
7147 * protect the concurrent access for the Adapters by TDLS module.
7148 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307149 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307150#endif
7151
Jeff Johnson295189b2012-06-20 16:38:30 -07007152 hdd_remove_adapter( pHddCtx, pAdapterNode );
7153 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007154 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007155
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307156#ifdef FEATURE_WLAN_TDLS
7157 mutex_unlock(&pHddCtx->tdls_lock);
7158#endif
7159
Jeff Johnson295189b2012-06-20 16:38:30 -07007160
7161 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307162 if ((!vos_concurrent_open_sessions_running()) &&
7163 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7164 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007165 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307166 if (pHddCtx->hdd_wlan_suspended)
7167 {
7168 hdd_set_pwrparams(pHddCtx);
7169 }
7170 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007171 }
7172
7173 return VOS_STATUS_SUCCESS;
7174 }
7175
7176 return VOS_STATUS_E_FAILURE;
7177}
7178
7179VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7180{
7181 hdd_adapter_list_node_t *pHddAdapterNode;
7182 VOS_STATUS status;
7183
7184 ENTER();
7185
7186 do
7187 {
7188 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7189 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7190 {
7191 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7192 vos_mem_free( pHddAdapterNode );
7193 }
7194 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7195
7196 EXIT();
7197
7198 return VOS_STATUS_SUCCESS;
7199}
7200
7201void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7202{
7203 v_U8_t addIE[1] = {0};
7204
7205 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7206 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7207 eANI_BOOLEAN_FALSE) )
7208 {
7209 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007210 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007211 }
7212
7213 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7214 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7215 eANI_BOOLEAN_FALSE) )
7216 {
7217 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007218 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 }
7220
7221 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7222 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7223 eANI_BOOLEAN_FALSE) )
7224 {
7225 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007226 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 }
7228}
7229
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307230VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7231 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007232{
7233 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7234 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307235 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007236 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307237 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307238 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307239 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007240
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307241 if (pHddCtx->isLogpInProgress) {
7242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7243 "%s:LOGP in Progress. Ignore!!!",__func__);
7244 return VOS_STATUS_E_FAILURE;
7245 }
7246
Jeff Johnson295189b2012-06-20 16:38:30 -07007247 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307248
Bhargav Shah784e6a52015-07-22 16:52:35 +05307249 if ( VOS_TRUE == bCloseSession )
7250 {
7251 status = hdd_sta_id_hash_detach(pAdapter);
7252 if (status != VOS_STATUS_SUCCESS)
7253 hddLog(VOS_TRACE_LEVEL_ERROR,
7254 FL("sta id hash detach failed"));
7255 }
Nirav Shah7e3c8132015-06-22 23:51:42 +05307256
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307257 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 switch(pAdapter->device_mode)
7259 {
7260 case WLAN_HDD_INFRA_STATION:
7261 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007262 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307263 {
7264 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307265#ifdef FEATURE_WLAN_TDLS
7266 mutex_lock(&pHddCtx->tdls_lock);
7267 wlan_hdd_tdls_exit(pAdapter, TRUE);
7268 mutex_unlock(&pHddCtx->tdls_lock);
7269#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307270 if( hdd_connIsConnected(pstation) ||
7271 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007272 {
7273 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7274 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7275 pAdapter->sessionId,
7276 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7277 else
7278 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7279 pAdapter->sessionId,
7280 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7281 //success implies disconnect command got queued up successfully
7282 if(halStatus == eHAL_STATUS_SUCCESS)
7283 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307284 ret = wait_for_completion_interruptible_timeout(
7285 &pAdapter->disconnect_comp_var,
7286 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7287 if (ret <= 0)
7288 {
7289 hddLog(VOS_TRACE_LEVEL_ERROR,
7290 "%s: wait on disconnect_comp_var failed %ld",
7291 __func__, ret);
7292 }
7293 }
7294 else
7295 {
7296 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7297 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007298 }
7299 memset(&wrqu, '\0', sizeof(wrqu));
7300 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7301 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7302 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7303 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307304 else if(pstation->conn_info.connState ==
7305 eConnectionState_Disconnecting)
7306 {
7307 ret = wait_for_completion_interruptible_timeout(
7308 &pAdapter->disconnect_comp_var,
7309 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7310 if (ret <= 0)
7311 {
7312 hddLog(VOS_TRACE_LEVEL_ERROR,
7313 FL("wait on disconnect_comp_var failed %ld"), ret);
7314 }
7315 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307316 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007317 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307318 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307319 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007320 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307321 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7322 {
7323 while (pAdapter->is_roc_inprogress)
7324 {
7325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7326 "%s: ROC in progress for session %d!!!",
7327 __func__, pAdapter->sessionId);
7328 // waiting for ROC to expire
7329 msleep(500);
7330 /* In GO present case , if retry exceeds 3,
7331 it means something went wrong. */
7332 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7333 {
7334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7335 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307336 if (eHAL_STATUS_SUCCESS !=
7337 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7338 pAdapter->sessionId ))
7339 {
7340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7341 FL("Failed to Cancel Remain on Channel"));
7342 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307343 wait_for_completion_interruptible_timeout(
7344 &pAdapter->cancel_rem_on_chan_var,
7345 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7346 break;
7347 }
7348 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307349 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307350 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307351#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307352 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307353#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307354
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307355 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307356
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307357 /* It is possible that the caller of this function does not
7358 * wish to close the session
7359 */
7360 if (VOS_TRUE == bCloseSession &&
7361 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 {
7363 INIT_COMPLETION(pAdapter->session_close_comp_var);
7364 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307365 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307366 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007367 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307368 unsigned long ret;
7369
Jeff Johnson295189b2012-06-20 16:38:30 -07007370 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307371 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307372 &pAdapter->session_close_comp_var,
7373 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307374 if ( 0 >= ret)
7375 {
7376 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307377 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307378 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007379 }
7380 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307381 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007382 break;
7383
7384 case WLAN_HDD_SOFTAP:
7385 case WLAN_HDD_P2P_GO:
7386 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307387 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7388 while (pAdapter->is_roc_inprogress) {
7389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7390 "%s: ROC in progress for session %d!!!",
7391 __func__, pAdapter->sessionId);
7392 msleep(500);
7393 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7395 "%s: ROC completion is not received.!!!", __func__);
7396 WLANSAP_CancelRemainOnChannel(
7397 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7398 wait_for_completion_interruptible_timeout(
7399 &pAdapter->cancel_rem_on_chan_var,
7400 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7401 break;
7402 }
7403 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307404
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307405 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307406 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007407 mutex_lock(&pHddCtx->sap_lock);
7408 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7409 {
7410 VOS_STATUS status;
7411 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7412
7413 //Stop Bss.
7414 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7415 if (VOS_IS_STATUS_SUCCESS(status))
7416 {
7417 hdd_hostapd_state_t *pHostapdState =
7418 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7419
7420 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7421
7422 if (!VOS_IS_STATUS_SUCCESS(status))
7423 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307424 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7425 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 }
7427 }
7428 else
7429 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007430 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 }
7432 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307433 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007434
7435 if (eHAL_STATUS_FAILURE ==
7436 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7437 0, NULL, eANI_BOOLEAN_FALSE))
7438 {
7439 hddLog(LOGE,
7440 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007441 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 }
7443
7444 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7445 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7446 eANI_BOOLEAN_FALSE) )
7447 {
7448 hddLog(LOGE,
7449 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7450 }
7451
7452 // Reset WNI_CFG_PROBE_RSP Flags
7453 wlan_hdd_reset_prob_rspies(pAdapter);
7454 kfree(pAdapter->sessionCtx.ap.beacon);
7455 pAdapter->sessionCtx.ap.beacon = NULL;
7456 }
7457 mutex_unlock(&pHddCtx->sap_lock);
7458 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007459
Jeff Johnson295189b2012-06-20 16:38:30 -07007460 case WLAN_HDD_MONITOR:
7461 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007462
Jeff Johnson295189b2012-06-20 16:38:30 -07007463 default:
7464 break;
7465 }
7466
7467 EXIT();
7468 return VOS_STATUS_SUCCESS;
7469}
7470
7471VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7472{
7473 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7474 VOS_STATUS status;
7475 hdd_adapter_t *pAdapter;
7476
7477 ENTER();
7478
7479 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7480
7481 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7482 {
7483 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007484
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307485 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007486
7487 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7488 pAdapterNode = pNext;
7489 }
7490
7491 EXIT();
7492
7493 return VOS_STATUS_SUCCESS;
7494}
7495
Rajeev Kumarf999e582014-01-09 17:33:29 -08007496
7497#ifdef FEATURE_WLAN_BATCH_SCAN
7498/**---------------------------------------------------------------------------
7499
7500 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7501 structures
7502
7503 \param - pAdapter Pointer to HDD adapter
7504
7505 \return - None
7506
7507 --------------------------------------------------------------------------*/
7508void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7509{
7510 tHddBatchScanRsp *pNode;
7511 tHddBatchScanRsp *pPrev;
7512
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307513 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007514 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307515 hddLog(VOS_TRACE_LEVEL_ERROR,
7516 "%s: Adapter context is Null", __func__);
7517 return;
7518 }
7519
7520 pNode = pAdapter->pBatchScanRsp;
7521 while (pNode)
7522 {
7523 pPrev = pNode;
7524 pNode = pNode->pNext;
7525 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007526 }
7527
7528 pAdapter->pBatchScanRsp = NULL;
7529 pAdapter->numScanList = 0;
7530 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7531 pAdapter->prev_batch_id = 0;
7532
7533 return;
7534}
7535#endif
7536
7537
Jeff Johnson295189b2012-06-20 16:38:30 -07007538VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7539{
7540 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7541 VOS_STATUS status;
7542 hdd_adapter_t *pAdapter;
7543
7544 ENTER();
7545
7546 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7547
7548 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7549 {
7550 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307551 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007552 netif_tx_disable(pAdapter->dev);
7553 netif_carrier_off(pAdapter->dev);
7554
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007555 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7556
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307558
Katya Nigam1fd24402015-02-16 14:52:19 +05307559 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7560 hdd_ibss_deinit_tx_rx(pAdapter);
7561
Nirav Shah7e3c8132015-06-22 23:51:42 +05307562 status = hdd_sta_id_hash_detach(pAdapter);
7563 if (status != VOS_STATUS_SUCCESS)
7564 hddLog(VOS_TRACE_LEVEL_ERROR,
7565 FL("sta id hash detach failed for session id %d"),
7566 pAdapter->sessionId);
7567
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307568 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7569
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307570 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7571 {
7572 hdd_wmm_adapter_close( pAdapter );
7573 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7574 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007575
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307576 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7577 {
7578 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7579 }
7580
Rajeev Kumarf999e582014-01-09 17:33:29 -08007581#ifdef FEATURE_WLAN_BATCH_SCAN
7582 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7583 {
7584 hdd_deinit_batch_scan(pAdapter);
7585 }
7586#endif
7587
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307588#ifdef FEATURE_WLAN_TDLS
7589 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307590 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307591 mutex_unlock(&pHddCtx->tdls_lock);
7592#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007593 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7594 pAdapterNode = pNext;
7595 }
7596
7597 EXIT();
7598
7599 return VOS_STATUS_SUCCESS;
7600}
7601
7602VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7603{
7604 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7605 VOS_STATUS status;
7606 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307607 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007608
7609 ENTER();
7610
7611 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7612
7613 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7614 {
7615 pAdapter = pAdapterNode->pAdapter;
7616
Kumar Anand82c009f2014-05-29 00:29:42 -07007617 hdd_wmm_init( pAdapter );
7618
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 switch(pAdapter->device_mode)
7620 {
7621 case WLAN_HDD_INFRA_STATION:
7622 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007623 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307624
7625 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7626
Jeff Johnson295189b2012-06-20 16:38:30 -07007627 hdd_init_station_mode(pAdapter);
7628 /* Open the gates for HDD to receive Wext commands */
7629 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007630 pHddCtx->scan_info.mScanPending = FALSE;
7631 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007632
7633 //Trigger the initial scan
7634 hdd_wlan_initial_scan(pAdapter);
7635
7636 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307637 if (eConnectionState_Associated == connState ||
7638 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007639 {
7640 union iwreq_data wrqu;
7641 memset(&wrqu, '\0', sizeof(wrqu));
7642 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7643 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7644 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007645 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007646
Jeff Johnson295189b2012-06-20 16:38:30 -07007647 /* indicate disconnected event to nl80211 */
7648 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7649 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307651 else if (eConnectionState_Connecting == connState)
7652 {
7653 /*
7654 * Indicate connect failure to supplicant if we were in the
7655 * process of connecting
7656 */
7657 cfg80211_connect_result(pAdapter->dev, NULL,
7658 NULL, 0, NULL, 0,
7659 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7660 GFP_KERNEL);
7661 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007662 break;
7663
7664 case WLAN_HDD_SOFTAP:
7665 /* softAP can handle SSR */
7666 break;
7667
7668 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007669 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007670 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007671 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 break;
7673
7674 case WLAN_HDD_MONITOR:
7675 /* monitor interface start */
7676 break;
7677 default:
7678 break;
7679 }
7680
7681 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7682 pAdapterNode = pNext;
7683 }
7684
7685 EXIT();
7686
7687 return VOS_STATUS_SUCCESS;
7688}
7689
7690VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7691{
7692 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7693 hdd_adapter_t *pAdapter;
7694 VOS_STATUS status;
7695 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307696 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007697
7698 ENTER();
7699
7700 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7701
7702 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7703 {
7704 pAdapter = pAdapterNode->pAdapter;
7705
7706 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7707 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7708 {
7709 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7710 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7711
Abhishek Singhf4669da2014-05-26 15:07:49 +05307712 hddLog(VOS_TRACE_LEVEL_INFO,
7713 "%s: Set HDD connState to eConnectionState_NotConnected",
7714 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7716 init_completion(&pAdapter->disconnect_comp_var);
7717 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7718 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7719
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307720 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007721 &pAdapter->disconnect_comp_var,
7722 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307723 if (0 >= ret)
7724 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7725 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007726
7727 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7728 pHddCtx->isAmpAllowed = VOS_FALSE;
7729 sme_RoamConnect(pHddCtx->hHal,
7730 pAdapter->sessionId, &(pWextState->roamProfile),
7731 &roamId);
7732 }
7733
7734 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7735 pAdapterNode = pNext;
7736 }
7737
7738 EXIT();
7739
7740 return VOS_STATUS_SUCCESS;
7741}
7742
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007743void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7744{
7745 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7746 VOS_STATUS status;
7747 hdd_adapter_t *pAdapter;
7748 hdd_station_ctx_t *pHddStaCtx;
7749 hdd_ap_ctx_t *pHddApCtx;
7750 hdd_hostapd_state_t * pHostapdState;
7751 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7752 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7753 const char *p2pMode = "DEV";
7754 const char *ccMode = "Standalone";
7755 int n;
7756
7757 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7758 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7759 {
7760 pAdapter = pAdapterNode->pAdapter;
7761 switch (pAdapter->device_mode) {
7762 case WLAN_HDD_INFRA_STATION:
7763 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7764 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7765 staChannel = pHddStaCtx->conn_info.operationChannel;
7766 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7767 }
7768 break;
7769 case WLAN_HDD_P2P_CLIENT:
7770 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7771 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7772 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7773 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7774 p2pMode = "CLI";
7775 }
7776 break;
7777 case WLAN_HDD_P2P_GO:
7778 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7779 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7780 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7781 p2pChannel = pHddApCtx->operatingChannel;
7782 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7783 }
7784 p2pMode = "GO";
7785 break;
7786 case WLAN_HDD_SOFTAP:
7787 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7788 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7789 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7790 apChannel = pHddApCtx->operatingChannel;
7791 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7792 }
7793 break;
7794 default:
7795 break;
7796 }
7797 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7798 pAdapterNode = pNext;
7799 }
7800 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7801 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7802 }
7803 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7804 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7805 if (p2pChannel > 0) {
7806 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7807 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7808 }
7809 if (apChannel > 0) {
7810 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7811 apChannel, MAC_ADDR_ARRAY(apBssid));
7812 }
7813
7814 if (p2pChannel > 0 && apChannel > 0) {
7815 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7816 }
7817}
7818
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007819bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007820{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007821 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007822}
7823
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007824/* Once SSR is disabled then it cannot be set. */
7825void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007826{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007827 if (HDD_SSR_DISABLED == isSsrRequired)
7828 return;
7829
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 isSsrRequired = value;
7831}
7832
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307833void hdd_set_pre_close( hdd_context_t *pHddCtx)
7834{
7835 sme_PreClose(pHddCtx->hHal);
7836}
7837
Jeff Johnson295189b2012-06-20 16:38:30 -07007838VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7839 hdd_adapter_list_node_t** ppAdapterNode)
7840{
7841 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307842 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007843 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7844 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307845 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 return status;
7847}
7848
7849VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7850 hdd_adapter_list_node_t* pAdapterNode,
7851 hdd_adapter_list_node_t** pNextAdapterNode)
7852{
7853 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307854 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007855 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7856 (hdd_list_node_t*) pAdapterNode,
7857 (hdd_list_node_t**)pNextAdapterNode );
7858
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307859 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 return status;
7861}
7862
7863VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7864 hdd_adapter_list_node_t* pAdapterNode)
7865{
7866 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307867 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007868 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7869 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307870 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 return status;
7872}
7873
7874VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7875 hdd_adapter_list_node_t** ppAdapterNode)
7876{
7877 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307878 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007879 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7880 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307881 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 return status;
7883}
7884
7885VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7886 hdd_adapter_list_node_t* pAdapterNode)
7887{
7888 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307889 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7891 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307892 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007893 return status;
7894}
7895
7896VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7897 hdd_adapter_list_node_t* pAdapterNode)
7898{
7899 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307900 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7902 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307903 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007904 return status;
7905}
7906
7907hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7908 tSirMacAddr macAddr )
7909{
7910 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7911 hdd_adapter_t *pAdapter;
7912 VOS_STATUS status;
7913
7914 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7915
7916 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7917 {
7918 pAdapter = pAdapterNode->pAdapter;
7919
7920 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7921 macAddr, sizeof(tSirMacAddr) ) )
7922 {
7923 return pAdapter;
7924 }
7925 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7926 pAdapterNode = pNext;
7927 }
7928
7929 return NULL;
7930
7931}
7932
7933hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7934{
7935 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7936 hdd_adapter_t *pAdapter;
7937 VOS_STATUS status;
7938
7939 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7940
7941 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7942 {
7943 pAdapter = pAdapterNode->pAdapter;
7944
7945 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7946 IFNAMSIZ ) )
7947 {
7948 return pAdapter;
7949 }
7950 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7951 pAdapterNode = pNext;
7952 }
7953
7954 return NULL;
7955
7956}
7957
7958hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7959{
7960 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7961 hdd_adapter_t *pAdapter;
7962 VOS_STATUS status;
7963
7964 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7965
7966 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7967 {
7968 pAdapter = pAdapterNode->pAdapter;
7969
7970 if( pAdapter && (mode == pAdapter->device_mode) )
7971 {
7972 return pAdapter;
7973 }
7974 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7975 pAdapterNode = pNext;
7976 }
7977
7978 return NULL;
7979
7980}
7981
7982//Remove this function later
7983hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7984{
7985 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7986 hdd_adapter_t *pAdapter;
7987 VOS_STATUS status;
7988
7989 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7990
7991 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7992 {
7993 pAdapter = pAdapterNode->pAdapter;
7994
7995 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7996 {
7997 return pAdapter;
7998 }
7999
8000 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8001 pAdapterNode = pNext;
8002 }
8003
8004 return NULL;
8005
8006}
8007
Jeff Johnson295189b2012-06-20 16:38:30 -07008008/**---------------------------------------------------------------------------
8009
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308010 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008011
8012 This API returns the operating channel of the requested device mode
8013
8014 \param - pHddCtx - Pointer to the HDD context.
8015 - mode - Device mode for which operating channel is required
8016 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8017 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8018 \return - channel number. "0" id the requested device is not found OR it is not connected.
8019 --------------------------------------------------------------------------*/
8020v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8021{
8022 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8023 VOS_STATUS status;
8024 hdd_adapter_t *pAdapter;
8025 v_U8_t operatingChannel = 0;
8026
8027 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8028
8029 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8030 {
8031 pAdapter = pAdapterNode->pAdapter;
8032
8033 if( mode == pAdapter->device_mode )
8034 {
8035 switch(pAdapter->device_mode)
8036 {
8037 case WLAN_HDD_INFRA_STATION:
8038 case WLAN_HDD_P2P_CLIENT:
8039 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8040 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8041 break;
8042 case WLAN_HDD_SOFTAP:
8043 case WLAN_HDD_P2P_GO:
8044 /*softap connection info */
8045 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8046 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8047 break;
8048 default:
8049 break;
8050 }
8051
8052 break; //Found the device of interest. break the loop
8053 }
8054
8055 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8056 pAdapterNode = pNext;
8057 }
8058 return operatingChannel;
8059}
8060
8061#ifdef WLAN_FEATURE_PACKET_FILTERING
8062/**---------------------------------------------------------------------------
8063
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308064 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008065
8066 This used to set the multicast address list.
8067
8068 \param - dev - Pointer to the WLAN device.
8069 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308070 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008071
8072 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308073static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008074{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308075 hdd_adapter_t *pAdapter;
8076 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008077 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308078 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308080
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308081 ENTER();
8082
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308083 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308084 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 {
8086 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308087 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008088 return;
8089 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308090 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8091 ret = wlan_hdd_validate_context(pHddCtx);
8092 if (0 != ret)
8093 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308094 return;
8095 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008096 if (dev->flags & IFF_ALLMULTI)
8097 {
8098 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008099 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308100 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008101 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308102 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008103 {
8104 mc_count = netdev_mc_count(dev);
8105 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008106 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8108 {
8109 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008110 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308111 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008112 return;
8113 }
8114
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308115 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008116
8117 netdev_for_each_mc_addr(ha, dev) {
8118 if (i == mc_count)
8119 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308120 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8121 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008122 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308123 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308124 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 i++;
8126 }
8127 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308128
8129 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008130 return;
8131}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308132
8133static void hdd_set_multicast_list(struct net_device *dev)
8134{
8135 vos_ssr_protect(__func__);
8136 __hdd_set_multicast_list(dev);
8137 vos_ssr_unprotect(__func__);
8138}
Jeff Johnson295189b2012-06-20 16:38:30 -07008139#endif
8140
8141/**---------------------------------------------------------------------------
8142
8143 \brief hdd_select_queue() -
8144
8145 This function is registered with the Linux OS for network
8146 core to decide which queue to use first.
8147
8148 \param - dev - Pointer to the WLAN device.
8149 - skb - Pointer to OS packet (sk_buff).
8150 \return - ac, Queue Index/access category corresponding to UP in IP header
8151
8152 --------------------------------------------------------------------------*/
8153v_U16_t hdd_select_queue(struct net_device *dev,
8154 struct sk_buff *skb)
8155{
8156 return hdd_wmm_select_queue(dev, skb);
8157}
8158
8159
8160/**---------------------------------------------------------------------------
8161
8162 \brief hdd_wlan_initial_scan() -
8163
8164 This function triggers the initial scan
8165
8166 \param - pAdapter - Pointer to the HDD adapter.
8167
8168 --------------------------------------------------------------------------*/
8169void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8170{
8171 tCsrScanRequest scanReq;
8172 tCsrChannelInfo channelInfo;
8173 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008174 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8176
8177 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8178 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8179 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8180
8181 if(sme_Is11dSupported(pHddCtx->hHal))
8182 {
8183 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8184 if ( HAL_STATUS_SUCCESS( halStatus ) )
8185 {
8186 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8187 if( !scanReq.ChannelInfo.ChannelList )
8188 {
8189 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8190 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008191 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008192 return;
8193 }
8194 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8195 channelInfo.numOfChannels);
8196 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8197 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008198 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008199 }
8200
8201 scanReq.scanType = eSIR_PASSIVE_SCAN;
8202 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8203 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8204 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8205 }
8206 else
8207 {
8208 scanReq.scanType = eSIR_ACTIVE_SCAN;
8209 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8210 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8211 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8212 }
8213
8214 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8215 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8216 {
8217 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8218 __func__, halStatus );
8219 }
8220
8221 if(sme_Is11dSupported(pHddCtx->hHal))
8222 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8223}
8224
mukul sharmabab477d2015-06-11 17:14:55 +05308225void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8226{
8227 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8228 VOS_STATUS status;
8229 hdd_adapter_t *pAdapter;
8230
8231 ENTER();
8232
8233 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8234
8235 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8236 {
8237 pAdapter = pAdapterNode->pAdapter;
8238
8239 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8240 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8241 pAdapterNode = pNext;
8242 }
8243
8244 EXIT();
8245}
Jeff Johnson295189b2012-06-20 16:38:30 -07008246/**---------------------------------------------------------------------------
8247
8248 \brief hdd_full_power_callback() - HDD full power callback function
8249
8250 This is the function invoked by SME to inform the result of a full power
8251 request issued by HDD
8252
8253 \param - callbackcontext - Pointer to cookie
8254 \param - status - result of request
8255
8256 \return - None
8257
8258 --------------------------------------------------------------------------*/
8259static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8260{
Jeff Johnson72a40512013-12-19 10:14:15 -08008261 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008262
8263 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308264 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008265
8266 if (NULL == callbackContext)
8267 {
8268 hddLog(VOS_TRACE_LEVEL_ERROR,
8269 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008270 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008271 return;
8272 }
8273
Jeff Johnson72a40512013-12-19 10:14:15 -08008274 /* there is a race condition that exists between this callback
8275 function and the caller since the caller could time out either
8276 before or while this code is executing. we use a spinlock to
8277 serialize these actions */
8278 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008279
8280 if (POWER_CONTEXT_MAGIC != pContext->magic)
8281 {
8282 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008283 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 hddLog(VOS_TRACE_LEVEL_WARN,
8285 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008286 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 return;
8288 }
8289
Jeff Johnson72a40512013-12-19 10:14:15 -08008290 /* context is valid so caller is still waiting */
8291
8292 /* paranoia: invalidate the magic */
8293 pContext->magic = 0;
8294
8295 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008296 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008297
8298 /* serialization is complete */
8299 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008300}
8301
Katya Nigamf0511f62015-05-05 16:40:57 +05308302void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8303{
8304 pMonCtx->typeSubtypeBitmap = 0;
8305 if( type%10 ) /* Management Packets */
8306 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8307 type/=10;
8308 if( type%10 ) /* Control Packets */
8309 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8310 type/=10;
8311 if( type%10 ) /* Data Packets */
8312 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8313}
8314
8315VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8316{
8317 vos_msg_t monMsg;
8318
8319 monMsg.type = WDA_MON_START_REQ;
8320 monMsg.reserved = 0;
8321 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8322 monMsg.bodyval = 0;
8323
8324 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8325 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8326 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8327 return VOS_STATUS_E_FAILURE;
8328 }
8329
8330 return VOS_STATUS_SUCCESS;
8331}
8332
8333void wlan_hdd_mon_poststopmsg(void)
8334{
8335 vos_msg_t monMsg;
8336
8337 monMsg.type = WDA_MON_STOP_REQ;
8338 monMsg.reserved = 0;
8339 monMsg.bodyptr = NULL;
8340 monMsg.bodyval = 0;
8341
8342 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8343 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8344 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8345 }
8346}
8347
Katya Nigame7b69a82015-04-28 15:24:06 +05308348void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8349{
8350 VOS_STATUS vosStatus;
8351 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8352 struct wiphy *wiphy = pHddCtx->wiphy;
8353
8354 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8355 if(pAdapter == NULL || pVosContext == NULL)
8356 {
8357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8358 return ;
8359 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308360
8361 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308362 hdd_UnregisterWext(pAdapter->dev);
8363
8364 vos_mon_stop( pVosContext );
8365
8366 vosStatus = vos_sched_close( pVosContext );
8367 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8368 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8369 "%s: Failed to close VOSS Scheduler",__func__);
8370 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8371 }
8372
8373 vosStatus = vos_nv_close();
8374 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8375 {
8376 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8377 "%s: Failed to close NV", __func__);
8378 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8379 }
8380
8381 vos_close(pVosContext);
8382
8383 #ifdef WLAN_KD_READY_NOTIFIER
8384 nl_srv_exit(pHddCtx->ptt_pid);
8385 #else
8386 nl_srv_exit();
8387 #endif
8388
8389 if (pHddCtx->cfg_ini)
8390 {
8391 kfree(pHddCtx->cfg_ini);
8392 pHddCtx->cfg_ini= NULL;
8393 }
8394 hdd_close_all_adapters( pHddCtx );
8395
8396 wiphy_free(wiphy) ;
8397
8398}
Jeff Johnson295189b2012-06-20 16:38:30 -07008399/**---------------------------------------------------------------------------
8400
8401 \brief hdd_wlan_exit() - HDD WLAN exit function
8402
8403 This is the driver exit point (invoked during rmmod)
8404
8405 \param - pHddCtx - Pointer to the HDD Context
8406
8407 \return - None
8408
8409 --------------------------------------------------------------------------*/
8410void hdd_wlan_exit(hdd_context_t *pHddCtx)
8411{
8412 eHalStatus halStatus;
8413 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8414 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308415 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008416 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008417 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008418 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308419 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008420
8421 ENTER();
8422
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308423
Katya Nigame7b69a82015-04-28 15:24:06 +05308424 if (VOS_MONITOR_MODE == hdd_get_conparam())
8425 {
8426 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8427 wlan_hdd_mon_close(pHddCtx);
8428 return;
8429 }
8430 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008431 {
8432 // Unloading, restart logic is no more required.
8433 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008434
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308435#ifdef FEATURE_WLAN_TDLS
8436 /* At the time of driver unloading; if tdls connection is present;
8437 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8438 * wlan_hdd_tdls_find_peer always checks for valid context;
8439 * as load/unload in progress there can be a race condition.
8440 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8441 * when tdls state is enabled.
8442 * As soon as driver set load/unload flag; tdls flag also needs
8443 * to be disabled so that hdd_rx_packet_cbk won't call
8444 * wlan_hdd_tdls_find_peer.
8445 */
8446 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8447#endif
8448
c_hpothu5ab05e92014-06-13 17:34:05 +05308449 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8450 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308452 pAdapter = pAdapterNode->pAdapter;
8453 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308455 /* Disable TX on the interface, after this hard_start_xmit() will
8456 * not be called on that interface
8457 */
8458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8459 netif_tx_disable(pAdapter->dev);
8460
8461 /* Mark the interface status as "down" for outside world */
8462 netif_carrier_off(pAdapter->dev);
8463
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308464 /* DeInit the adapter. This ensures that all data packets
8465 * are freed.
8466 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308467#ifdef FEATURE_WLAN_TDLS
8468 mutex_lock(&pHddCtx->tdls_lock);
8469#endif
c_hpothu002231a2015-02-05 14:58:51 +05308470 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308471#ifdef FEATURE_WLAN_TDLS
8472 mutex_unlock(&pHddCtx->tdls_lock);
8473#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308474
c_hpothu5ab05e92014-06-13 17:34:05 +05308475 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8476 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8477 {
8478 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8479 hdd_UnregisterWext(pAdapter->dev);
8480 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308481
Jeff Johnson295189b2012-06-20 16:38:30 -07008482 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308483 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8484 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008485 }
mukul sharmabab477d2015-06-11 17:14:55 +05308486
8487 //Purge all sme cmd's for all interface
8488 hdd_purge_cmd_list_all_adapters(pHddCtx);
8489
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308490 // Cancel any outstanding scan requests. We are about to close all
8491 // of our adapters, but an adapter structure is what SME passes back
8492 // to our callback function. Hence if there are any outstanding scan
8493 // requests then there is a race condition between when the adapter
8494 // is closed and when the callback is invoked.We try to resolve that
8495 // race condition here by canceling any outstanding scans before we
8496 // close the adapters.
8497 // Note that the scans may be cancelled in an asynchronous manner,
8498 // so ideally there needs to be some kind of synchronization. Rather
8499 // than introduce a new synchronization here, we will utilize the
8500 // fact that we are about to Request Full Power, and since that is
8501 // synchronized, the expectation is that by the time Request Full
8502 // Power has completed all scans will be cancelled.
8503 if (pHddCtx->scan_info.mScanPending)
8504 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308505 if(NULL != pAdapter)
8506 {
8507 hddLog(VOS_TRACE_LEVEL_INFO,
8508 FL("abort scan mode: %d sessionId: %d"),
8509 pAdapter->device_mode,
8510 pAdapter->sessionId);
8511 }
8512 hdd_abort_mac_scan(pHddCtx,
8513 pHddCtx->scan_info.sessionId,
8514 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308515 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308517 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008518 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308519 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308520 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8521 {
8522 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8524 "%s: in middle of FTM START", __func__);
8525 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8526 msecs_to_jiffies(20000));
8527 if(!lrc)
8528 {
8529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8530 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8531 }
8532 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008533 wlan_hdd_ftm_close(pHddCtx);
8534 goto free_hdd_ctx;
8535 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308536
Jeff Johnson295189b2012-06-20 16:38:30 -07008537 /* DeRegister with platform driver as client for Suspend/Resume */
8538 vosStatus = hddDeregisterPmOps(pHddCtx);
8539 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8540 {
8541 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8542 VOS_ASSERT(0);
8543 }
8544
8545 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8546 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8547 {
8548 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8549 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008550
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008551 //Stop the traffic monitor timer
8552 if ( VOS_TIMER_STATE_RUNNING ==
8553 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8554 {
8555 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8556 }
8557
8558 // Destroy the traffic monitor timer
8559 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8560 &pHddCtx->tx_rx_trafficTmr)))
8561 {
8562 hddLog(VOS_TRACE_LEVEL_ERROR,
8563 "%s: Cannot deallocate Traffic monitor timer", __func__);
8564 }
8565
Jeff Johnson295189b2012-06-20 16:38:30 -07008566 //Disable IMPS/BMPS as we do not want the device to enter any power
8567 //save mode during shutdown
8568 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8569 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8570 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8571
8572 //Ensure that device is in full power as we will touch H/W during vos_Stop
8573 init_completion(&powerContext.completion);
8574 powerContext.magic = POWER_CONTEXT_MAGIC;
8575
8576 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8577 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8578
8579 if (eHAL_STATUS_SUCCESS != halStatus)
8580 {
8581 if (eHAL_STATUS_PMC_PENDING == halStatus)
8582 {
8583 /* request was sent -- wait for the response */
8584 lrc = wait_for_completion_interruptible_timeout(
8585 &powerContext.completion,
8586 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008587 if (lrc <= 0)
8588 {
8589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008590 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 }
8592 }
8593 else
8594 {
8595 hddLog(VOS_TRACE_LEVEL_ERROR,
8596 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008597 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008598 /* continue -- need to clean up as much as possible */
8599 }
8600 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308601 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8602 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8603 {
8604 /* This will issue a dump command which will clean up
8605 BTQM queues and unblock MC thread */
8606 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8607 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008608
Jeff Johnson72a40512013-12-19 10:14:15 -08008609 /* either we never sent a request, we sent a request and received a
8610 response or we sent a request and timed out. if we never sent a
8611 request or if we sent a request and got a response, we want to
8612 clear the magic out of paranoia. if we timed out there is a
8613 race condition such that the callback function could be
8614 executing at the same time we are. of primary concern is if the
8615 callback function had already verified the "magic" but had not
8616 yet set the completion variable when a timeout occurred. we
8617 serialize these activities by invalidating the magic while
8618 holding a shared spinlock which will cause us to block if the
8619 callback is currently executing */
8620 spin_lock(&hdd_context_lock);
8621 powerContext.magic = 0;
8622 spin_unlock(&hdd_context_lock);
8623
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308624 /* If Device is shutdown, no point for SME to wait for responses
8625 from device. Pre Close SME */
8626 if(wcnss_device_is_shutdown())
8627 {
8628 sme_PreClose(pHddCtx->hHal);
8629 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008630 hdd_debugfs_exit(pHddCtx);
8631
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308632#ifdef WLAN_NS_OFFLOAD
8633 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8634 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8635#endif
8636 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8637 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8638
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 // Unregister the Net Device Notifier
8640 unregister_netdevice_notifier(&hdd_netdev_notifier);
8641
Jeff Johnson295189b2012-06-20 16:38:30 -07008642 hdd_stop_all_adapters( pHddCtx );
8643
Jeff Johnson295189b2012-06-20 16:38:30 -07008644#ifdef WLAN_BTAMP_FEATURE
8645 vosStatus = WLANBAP_Stop(pVosContext);
8646 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8647 {
8648 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8649 "%s: Failed to stop BAP",__func__);
8650 }
8651#endif //WLAN_BTAMP_FEATURE
8652
8653 //Stop all the modules
8654 vosStatus = vos_stop( pVosContext );
8655 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8656 {
8657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8658 "%s: Failed to stop VOSS",__func__);
8659 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8660 }
8661
Jeff Johnson295189b2012-06-20 16:38:30 -07008662 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008664
8665 //Close the scheduler before calling vos_close to make sure no thread is
8666 // scheduled after the each module close is called i.e after all the data
8667 // structures are freed.
8668 vosStatus = vos_sched_close( pVosContext );
8669 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8670 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8671 "%s: Failed to close VOSS Scheduler",__func__);
8672 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8673 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008674#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8675 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308676 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008677#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008678 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308679 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008680
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308681#ifdef CONFIG_ENABLE_LINUX_REG
8682 vosStatus = vos_nv_close();
8683 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8684 {
8685 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8686 "%s: Failed to close NV", __func__);
8687 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8688 }
8689#endif
8690
Jeff Johnson295189b2012-06-20 16:38:30 -07008691 //Close VOSS
8692 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8693 vos_close(pVosContext);
8694
Jeff Johnson295189b2012-06-20 16:38:30 -07008695 //Close Watchdog
8696 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8697 vos_watchdog_close(pVosContext);
8698
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308699 //Clean up HDD Nlink Service
8700 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308701
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308702#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308703 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308704 {
8705 wlan_logging_sock_deactivate_svc();
8706 }
8707#endif
8708
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308709#ifdef WLAN_KD_READY_NOTIFIER
8710 nl_srv_exit(pHddCtx->ptt_pid);
8711#else
8712 nl_srv_exit();
8713#endif /* WLAN_KD_READY_NOTIFIER */
8714
8715
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 hdd_close_all_adapters( pHddCtx );
8717
Jeff Johnson295189b2012-06-20 16:38:30 -07008718 /* free the power on lock from platform driver */
8719 if (free_riva_power_on_lock("wlan"))
8720 {
8721 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8722 __func__);
8723 }
8724
Jeff Johnson88ba7742013-02-27 14:36:02 -08008725free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308726
8727 //Free up dynamically allocated members inside HDD Adapter
8728 if (pHddCtx->cfg_ini)
8729 {
8730 kfree(pHddCtx->cfg_ini);
8731 pHddCtx->cfg_ini= NULL;
8732 }
8733
Leo Changf04ddad2013-09-18 13:46:38 -07008734 /* FTM mode, WIPHY did not registered
8735 If un-register here, system crash will happen */
8736 if (VOS_FTM_MODE != hdd_get_conparam())
8737 {
8738 wiphy_unregister(wiphy) ;
8739 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008740 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008741 if (hdd_is_ssr_required())
8742 {
8743 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008744 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 msleep(5000);
8746 }
8747 hdd_set_ssr_required (VOS_FALSE);
8748}
8749
8750
8751/**---------------------------------------------------------------------------
8752
8753 \brief hdd_update_config_from_nv() - Function to update the contents of
8754 the running configuration with parameters taken from NV storage
8755
8756 \param - pHddCtx - Pointer to the HDD global context
8757
8758 \return - VOS_STATUS_SUCCESS if successful
8759
8760 --------------------------------------------------------------------------*/
8761static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8762{
Jeff Johnson295189b2012-06-20 16:38:30 -07008763 v_BOOL_t itemIsValid = VOS_FALSE;
8764 VOS_STATUS status;
8765 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8766 v_U8_t macLoop;
8767
8768 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8769 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8770 if(status != VOS_STATUS_SUCCESS)
8771 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008772 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008773 return VOS_STATUS_E_FAILURE;
8774 }
8775
8776 if (itemIsValid == VOS_TRUE)
8777 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008778 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008779 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8780 VOS_MAX_CONCURRENCY_PERSONA);
8781 if(status != VOS_STATUS_SUCCESS)
8782 {
8783 /* Get MAC from NV fail, not update CFG info
8784 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008785 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 return VOS_STATUS_E_FAILURE;
8787 }
8788
8789 /* If first MAC is not valid, treat all others are not valid
8790 * Then all MACs will be got from ini file */
8791 if(vos_is_macaddr_zero(&macFromNV[0]))
8792 {
8793 /* MAC address in NV file is not configured yet */
8794 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8795 return VOS_STATUS_E_INVAL;
8796 }
8797
8798 /* Get MAC address from NV, update CFG info */
8799 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8800 {
8801 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8802 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308803 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008804 /* This MAC is not valid, skip it
8805 * This MAC will be got from ini file */
8806 }
8807 else
8808 {
8809 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8810 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8811 VOS_MAC_ADDR_SIZE);
8812 }
8813 }
8814 }
8815 else
8816 {
8817 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8818 return VOS_STATUS_E_FAILURE;
8819 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008820
Jeff Johnson295189b2012-06-20 16:38:30 -07008821
8822 return VOS_STATUS_SUCCESS;
8823}
8824
8825/**---------------------------------------------------------------------------
8826
8827 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8828
8829 \param - pAdapter - Pointer to the HDD
8830
8831 \return - None
8832
8833 --------------------------------------------------------------------------*/
8834VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8835{
8836 eHalStatus halStatus;
8837 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308838 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008839
Jeff Johnson295189b2012-06-20 16:38:30 -07008840
8841 // Send ready indication to the HDD. This will kick off the MAC
8842 // into a 'running' state and should kick off an initial scan.
8843 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8844 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8845 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308846 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008847 "code %08d [x%08x]",__func__, halStatus, halStatus );
8848 return VOS_STATUS_E_FAILURE;
8849 }
8850
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308851 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008852 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8853 // And RIVA will crash
8854 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8855 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308856 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8857 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8858
8859
Jeff Johnson295189b2012-06-20 16:38:30 -07008860 return VOS_STATUS_SUCCESS;
8861}
8862
Jeff Johnson295189b2012-06-20 16:38:30 -07008863/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308864void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008865{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308866
8867 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8868
Jeff Johnson295189b2012-06-20 16:38:30 -07008869}
8870
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308871void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008872{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308873
8874 vos_wake_lock_release(&wlan_wake_lock, reason);
8875
Jeff Johnson295189b2012-06-20 16:38:30 -07008876}
8877
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308878void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008879{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308880
8881 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8882 reason);
8883
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008884}
8885
Jeff Johnson295189b2012-06-20 16:38:30 -07008886/**---------------------------------------------------------------------------
8887
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008888 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8889 information between Host and Riva
8890
8891 This function gets reported version of FW
8892 It also finds the version of Riva headers used to compile the host
8893 It compares the above two and prints a warning if they are different
8894 It gets the SW and HW version string
8895 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8896 indicating the features they support through a bitmap
8897
8898 \param - pHddCtx - Pointer to HDD context
8899
8900 \return - void
8901
8902 --------------------------------------------------------------------------*/
8903
8904void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8905{
8906
8907 tSirVersionType versionCompiled;
8908 tSirVersionType versionReported;
8909 tSirVersionString versionString;
8910 tANI_U8 fwFeatCapsMsgSupported = 0;
8911 VOS_STATUS vstatus;
8912
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008913 memset(&versionCompiled, 0, sizeof(versionCompiled));
8914 memset(&versionReported, 0, sizeof(versionReported));
8915
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008916 /* retrieve and display WCNSS version information */
8917 do {
8918
8919 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8920 &versionCompiled);
8921 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8922 {
8923 hddLog(VOS_TRACE_LEVEL_FATAL,
8924 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008925 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008926 break;
8927 }
8928
8929 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8930 &versionReported);
8931 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8932 {
8933 hddLog(VOS_TRACE_LEVEL_FATAL,
8934 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008935 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008936 break;
8937 }
8938
8939 if ((versionCompiled.major != versionReported.major) ||
8940 (versionCompiled.minor != versionReported.minor) ||
8941 (versionCompiled.version != versionReported.version) ||
8942 (versionCompiled.revision != versionReported.revision))
8943 {
8944 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8945 "Host expected %u.%u.%u.%u\n",
8946 WLAN_MODULE_NAME,
8947 (int)versionReported.major,
8948 (int)versionReported.minor,
8949 (int)versionReported.version,
8950 (int)versionReported.revision,
8951 (int)versionCompiled.major,
8952 (int)versionCompiled.minor,
8953 (int)versionCompiled.version,
8954 (int)versionCompiled.revision);
8955 }
8956 else
8957 {
8958 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8959 WLAN_MODULE_NAME,
8960 (int)versionReported.major,
8961 (int)versionReported.minor,
8962 (int)versionReported.version,
8963 (int)versionReported.revision);
8964 }
8965
8966 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8967 versionString,
8968 sizeof(versionString));
8969 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8970 {
8971 hddLog(VOS_TRACE_LEVEL_FATAL,
8972 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008973 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008974 break;
8975 }
8976
8977 pr_info("%s: WCNSS software version %s\n",
8978 WLAN_MODULE_NAME, versionString);
8979
8980 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8981 versionString,
8982 sizeof(versionString));
8983 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8984 {
8985 hddLog(VOS_TRACE_LEVEL_FATAL,
8986 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008987 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008988 break;
8989 }
8990
8991 pr_info("%s: WCNSS hardware version %s\n",
8992 WLAN_MODULE_NAME, versionString);
8993
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008994 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8995 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008996 send the message only if it the riva is 1.1
8997 minor numbers for different riva branches:
8998 0 -> (1.0)Mainline Build
8999 1 -> (1.1)Mainline Build
9000 2->(1.04) Stability Build
9001 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009002 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009003 ((versionReported.minor>=1) && (versionReported.version>=1)))
9004 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
9005 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009006
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009007 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08009008 {
9009#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9010 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
9011 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9012#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009013 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9014 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9015 {
9016 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9017 }
9018
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009019 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009020 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009021
9022 } while (0);
9023
9024}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309025void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9026{
9027 struct sk_buff *skb;
9028 struct nlmsghdr *nlh;
9029 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309030 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309031
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309032 if (in_interrupt() || irqs_disabled() || in_atomic())
9033 flags = GFP_ATOMIC;
9034
9035 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309036
9037 if(skb == NULL) {
9038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9039 "%s: alloc_skb failed", __func__);
9040 return;
9041 }
9042
9043 nlh = (struct nlmsghdr *)skb->data;
9044 nlh->nlmsg_pid = 0; /* from kernel */
9045 nlh->nlmsg_flags = 0;
9046 nlh->nlmsg_seq = 0;
9047 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9048
9049 ani_hdr = NLMSG_DATA(nlh);
9050 ani_hdr->type = type;
9051
9052 switch(type) {
9053 case WLAN_SVC_SAP_RESTART_IND:
9054 ani_hdr->length = 0;
9055 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9056 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9057 break;
9058 default:
9059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9060 "Attempt to send unknown nlink message %d", type);
9061 kfree_skb(skb);
9062 return;
9063 }
9064
9065 nl_srv_bcast(skb);
9066
9067 return;
9068}
9069
9070
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009071
9072/**---------------------------------------------------------------------------
9073
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309074 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9075
9076 \param - pHddCtx - Pointer to the hdd context
9077
9078 \return - true if hardware supports 5GHz
9079
9080 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309081boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309082{
9083 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9084 * then hardware support 5Ghz.
9085 */
9086 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9087 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309089 return true;
9090 }
9091 else
9092 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309093 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309094 __func__);
9095 return false;
9096 }
9097}
9098
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309099/**---------------------------------------------------------------------------
9100
9101 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9102 generate function
9103
9104 This is generate the random mac address for WLAN interface
9105
9106 \param - pHddCtx - Pointer to HDD context
9107 idx - Start interface index to get auto
9108 generated mac addr.
9109 mac_addr - Mac address
9110
9111 \return - 0 for success, < 0 for failure
9112
9113 --------------------------------------------------------------------------*/
9114
9115static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9116 int idx, v_MACADDR_t mac_addr)
9117{
9118 int i;
9119 unsigned int serialno;
9120 serialno = wcnss_get_serial_number();
9121
9122 if (0 != serialno)
9123 {
9124 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9125 bytes of the serial number that can be used to generate
9126 the other 3 bytes of the MAC address. Mask off all but
9127 the lower 3 bytes (this will also make sure we don't
9128 overflow in the next step) */
9129 serialno &= 0x00FFFFFF;
9130
9131 /* we need a unique address for each session */
9132 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9133
9134 /* autogen other Mac addresses */
9135 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9136 {
9137 /* start with the entire default address */
9138 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9139 /* then replace the lower 3 bytes */
9140 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9141 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9142 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9143
9144 serialno++;
9145 hddLog(VOS_TRACE_LEVEL_ERROR,
9146 "%s: Derived Mac Addr: "
9147 MAC_ADDRESS_STR, __func__,
9148 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9149 }
9150
9151 }
9152 else
9153 {
9154 hddLog(LOGE, FL("Failed to Get Serial NO"));
9155 return -1;
9156 }
9157 return 0;
9158}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309159
Katya Nigame7b69a82015-04-28 15:24:06 +05309160int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9161{
9162 VOS_STATUS status;
9163 v_CONTEXT_t pVosContext= NULL;
9164 hdd_adapter_t *pAdapter= NULL;
9165
9166 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9167
9168 if (NULL == pVosContext)
9169 {
9170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9171 "%s: Trying to open VOSS without a PreOpen", __func__);
9172 VOS_ASSERT(0);
9173 return VOS_STATUS_E_FAILURE;
9174 }
9175
9176 status = vos_nv_open();
9177 if (!VOS_IS_STATUS_SUCCESS(status))
9178 {
9179 /* NV module cannot be initialized */
9180 hddLog( VOS_TRACE_LEVEL_FATAL,
9181 "%s: vos_nv_open failed", __func__);
9182 return VOS_STATUS_E_FAILURE;
9183 }
9184
9185 status = vos_init_wiphy_from_nv_bin();
9186 if (!VOS_IS_STATUS_SUCCESS(status))
9187 {
9188 /* NV module cannot be initialized */
9189 hddLog( VOS_TRACE_LEVEL_FATAL,
9190 "%s: vos_init_wiphy failed", __func__);
9191 goto err_vos_nv_close;
9192 }
9193
9194 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9195 if ( !VOS_IS_STATUS_SUCCESS( status ))
9196 {
9197 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9198 goto err_vos_nv_close;
9199 }
9200
9201 status = vos_mon_start( pVosContext );
9202 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9203 {
9204 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9205 goto err_vosclose;
9206 }
9207
9208 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9209 WDA_featureCapsExchange(pVosContext);
9210 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9211
9212 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9213 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9214 if( pAdapter == NULL )
9215 {
9216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9217 goto err_close_adapter;
9218 }
9219
9220 //Initialize the nlink service
9221 if(nl_srv_init() != 0)
9222 {
9223 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9224 goto err_close_adapter;
9225 }
9226 return VOS_STATUS_SUCCESS;
9227
9228err_close_adapter:
9229 hdd_close_all_adapters( pHddCtx );
9230 vos_mon_stop( pVosContext );
9231err_vosclose:
9232 status = vos_sched_close( pVosContext );
9233 if (!VOS_IS_STATUS_SUCCESS(status)) {
9234 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9235 "%s: Failed to close VOSS Scheduler", __func__);
9236 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9237 }
9238 vos_close(pVosContext );
9239
9240err_vos_nv_close:
9241 vos_nv_close();
9242
9243return status;
9244}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309245/**---------------------------------------------------------------------------
9246
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309247 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9248 completed to flush out the scan results
9249
9250 11d scan is done during driver load and is a passive scan on all
9251 channels supported by the device, 11d scans may find some APs on
9252 frequencies which are forbidden to be used in the regulatory domain
9253 the device is operating in. If these APs are notified to the supplicant
9254 it may try to connect to these APs, thus flush out all the scan results
9255 which are present in SME after 11d scan is done.
9256
9257 \return - eHalStatus
9258
9259 --------------------------------------------------------------------------*/
9260static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9261 tANI_U32 scanId, eCsrScanStatus status)
9262{
9263 ENTER();
9264
9265 sme_ScanFlushResult(halHandle, 0);
9266
9267 EXIT();
9268
9269 return eHAL_STATUS_SUCCESS;
9270}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309271/**---------------------------------------------------------------------------
9272
9273 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9274 logging is completed successfully.
9275
9276 \return - None
9277
9278 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309279void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309280{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309281 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309282
9283 if (NULL == pHddCtx)
9284 {
9285 hddLog(VOS_TRACE_LEVEL_ERROR,
9286 "%s: HDD context is NULL",__func__);
9287 return;
9288 }
9289
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309290 if ((VOS_STATUS_SUCCESS == status) &&
9291 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309292 {
9293 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9294 pHddCtx->mgmt_frame_logging = TRUE;
9295 }
9296 else
9297 {
9298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9299 pHddCtx->mgmt_frame_logging = FALSE;
9300 }
9301
9302 return;
9303}
9304/**---------------------------------------------------------------------------
9305
9306 \brief hdd_init_frame_logging - function to initialize frame logging.
9307 Currently only Mgmt Frames are logged in both TX
9308 and Rx direction and are sent to userspace
9309 application using logger thread when queried.
9310
9311 \return - None
9312
9313 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309314void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309315{
9316 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309317 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309318
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309319 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9320 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309321 {
9322 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9323 return;
9324 }
9325
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309326 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9327 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309328 {
9329 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9330 return;
9331 }
9332
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309333 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309334
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9336 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9337 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9338 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309339
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309340 if (pHddCtx->cfg_ini->enableFWLogging ||
9341 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309342 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309343 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309344 }
9345
Sushant Kaushik46804902015-07-08 14:46:03 +05309346 if (pHddCtx->cfg_ini->enableMgmtLogging)
9347 {
9348 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9349 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309350 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9351 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309352 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309353 }
9354
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309355 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9356 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9357 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9358 wlanFWLoggingInitParam->continuousFrameLogging =
9359 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309360
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309361 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309362
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309363 wlanFWLoggingInitParam->minLogBufferSize =
9364 pHddCtx->cfg_ini->minLoggingBufferSize;
9365 wlanFWLoggingInitParam->maxLogBufferSize =
9366 pHddCtx->cfg_ini->maxLoggingBufferSize;
9367 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9368 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309369
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309370 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309371
9372 if (eHAL_STATUS_SUCCESS != halStatus)
9373 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309374 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309375 }
9376
9377 return;
9378}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309379
9380/**---------------------------------------------------------------------------
9381
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 \brief hdd_wlan_startup() - HDD init function
9383
9384 This is the driver startup code executed once a WLAN device has been detected
9385
9386 \param - dev - Pointer to the underlying device
9387
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009388 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009389
9390 --------------------------------------------------------------------------*/
9391
9392int hdd_wlan_startup(struct device *dev )
9393{
9394 VOS_STATUS status;
9395 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009396 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 hdd_context_t *pHddCtx = NULL;
9398 v_CONTEXT_t pVosContext= NULL;
9399#ifdef WLAN_BTAMP_FEATURE
9400 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9401 WLANBAP_ConfigType btAmpConfig;
9402 hdd_config_t *pConfig;
9403#endif
9404 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309406 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009407
9408 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 /*
9410 * cfg80211: wiphy allocation
9411 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309412 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009413
9414 if(wiphy == NULL)
9415 {
9416 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009417 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 pHddCtx = wiphy_priv(wiphy);
9420
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 //Initialize the adapter context to zeros.
9422 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9423
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309425 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309426 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009427
9428 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9429
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309430 /* register for riva power on lock to platform driver
9431 * Locking power early to ensure FW doesn't reset by kernel while
9432 * host driver is busy initializing itself */
9433 if (req_riva_power_on_lock("wlan"))
9434 {
9435 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9436 __func__);
9437 goto err_free_hdd_context;
9438 }
9439
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 /*Get vos context here bcoz vos_open requires it*/
9441 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9442
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009443 if(pVosContext == NULL)
9444 {
9445 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9446 goto err_free_hdd_context;
9447 }
9448
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 //Save the Global VOSS context in adapter context for future.
9450 pHddCtx->pvosContext = pVosContext;
9451
9452 //Save the adapter context in global context for future.
9453 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9454
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 pHddCtx->parent_dev = dev;
9456
9457 init_completion(&pHddCtx->full_pwr_comp_var);
9458 init_completion(&pHddCtx->standby_comp_var);
9459 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009460 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009461 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309462 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309463 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009464
9465#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009466 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009467#else
9468 init_completion(&pHddCtx->driver_crda_req);
9469#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009470
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309471 spin_lock_init(&pHddCtx->schedScan_lock);
9472
Jeff Johnson295189b2012-06-20 16:38:30 -07009473 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9474
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309475#ifdef FEATURE_WLAN_TDLS
9476 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9477 * invoked by other instances also) to protect the concurrent
9478 * access for the Adapters by TDLS module.
9479 */
9480 mutex_init(&pHddCtx->tdls_lock);
9481#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309482 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309483 mutex_init(&pHddCtx->wmmLock);
9484
Agarwal Ashish1f422872014-07-22 00:11:55 +05309485 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309486
Agarwal Ashish1f422872014-07-22 00:11:55 +05309487 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009488 // Load all config first as TL config is needed during vos_open
9489 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9490 if(pHddCtx->cfg_ini == NULL)
9491 {
9492 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9493 goto err_free_hdd_context;
9494 }
9495
9496 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9497
9498 // Read and parse the qcom_cfg.ini file
9499 status = hdd_parse_config_ini( pHddCtx );
9500 if ( VOS_STATUS_SUCCESS != status )
9501 {
9502 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9503 __func__, WLAN_INI_FILE);
9504 goto err_config;
9505 }
Arif Hussaind5218912013-12-05 01:10:55 -08009506#ifdef MEMORY_DEBUG
9507 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9508 vos_mem_init();
9509
9510 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9511 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9512#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009513
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309514 /* INI has been read, initialise the configuredMcastBcastFilter with
9515 * INI value as this will serve as the default value
9516 */
9517 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9518 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9519 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309520
9521 if (false == hdd_is_5g_supported(pHddCtx))
9522 {
9523 //5Ghz is not supported.
9524 if (1 != pHddCtx->cfg_ini->nBandCapability)
9525 {
9526 hddLog(VOS_TRACE_LEVEL_INFO,
9527 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9528 pHddCtx->cfg_ini->nBandCapability = 1;
9529 }
9530 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309531
9532 /* If SNR Monitoring is enabled, FW has to parse all beacons
9533 * for calcaluting and storing the average SNR, so set Nth beacon
9534 * filter to 1 to enable FW to parse all the beaocons
9535 */
9536 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9537 {
9538 /* The log level is deliberately set to WARN as overriding
9539 * nthBeaconFilter to 1 will increase power cosumption and this
9540 * might just prove helpful to detect the power issue.
9541 */
9542 hddLog(VOS_TRACE_LEVEL_WARN,
9543 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9544 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009546 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309547 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009549 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009550 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009551 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9552 {
9553 hddLog(VOS_TRACE_LEVEL_FATAL,
9554 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9555 goto err_config;
9556 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009558
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009559 // Update VOS trace levels based upon the cfg.ini
9560 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9561 pHddCtx->cfg_ini->vosTraceEnableBAP);
9562 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9563 pHddCtx->cfg_ini->vosTraceEnableTL);
9564 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9565 pHddCtx->cfg_ini->vosTraceEnableWDI);
9566 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9567 pHddCtx->cfg_ini->vosTraceEnableHDD);
9568 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9569 pHddCtx->cfg_ini->vosTraceEnableSME);
9570 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9571 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309572 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9573 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009574 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9575 pHddCtx->cfg_ini->vosTraceEnableWDA);
9576 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9577 pHddCtx->cfg_ini->vosTraceEnableSYS);
9578 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9579 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009580 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9581 pHddCtx->cfg_ini->vosTraceEnableSAP);
9582 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9583 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009584
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 // Update WDI trace levels based upon the cfg.ini
9586 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9587 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9588 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9589 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9590 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9591 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9592 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9593 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009594
Jeff Johnson88ba7742013-02-27 14:36:02 -08009595 if (VOS_FTM_MODE == hdd_get_conparam())
9596 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9598 {
9599 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9600 goto err_free_hdd_context;
9601 }
9602 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309603 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309604 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009605 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009606 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009607
Katya Nigame7b69a82015-04-28 15:24:06 +05309608 if( VOS_MONITOR_MODE == hdd_get_conparam())
9609 {
9610 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9611 {
9612 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9613 goto err_free_hdd_context;
9614 }
9615 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9616 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9617 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9618 return VOS_STATUS_SUCCESS;
9619 }
9620
Jeff Johnson88ba7742013-02-27 14:36:02 -08009621 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9623 {
9624 status = vos_watchdog_open(pVosContext,
9625 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9626
9627 if(!VOS_IS_STATUS_SUCCESS( status ))
9628 {
9629 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309630 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009631 }
9632 }
9633
9634 pHddCtx->isLogpInProgress = FALSE;
9635 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9636
Amar Singhala49cbc52013-10-08 18:37:44 -07009637#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009638 /* initialize the NV module. This is required so that
9639 we can initialize the channel information in wiphy
9640 from the NV.bin data. The channel information in
9641 wiphy needs to be initialized before wiphy registration */
9642
9643 status = vos_nv_open();
9644 if (!VOS_IS_STATUS_SUCCESS(status))
9645 {
9646 /* NV module cannot be initialized */
9647 hddLog( VOS_TRACE_LEVEL_FATAL,
9648 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309649 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009650 }
9651
9652 status = vos_init_wiphy_from_nv_bin();
9653 if (!VOS_IS_STATUS_SUCCESS(status))
9654 {
9655 /* NV module cannot be initialized */
9656 hddLog( VOS_TRACE_LEVEL_FATAL,
9657 "%s: vos_init_wiphy failed", __func__);
9658 goto err_vos_nv_close;
9659 }
9660
Amar Singhala49cbc52013-10-08 18:37:44 -07009661#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309662 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309663 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 if ( !VOS_IS_STATUS_SUCCESS( status ))
9665 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009666 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309667 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009668 }
9669
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9671
9672 if ( NULL == pHddCtx->hHal )
9673 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009674 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 goto err_vosclose;
9676 }
9677
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009678 status = vos_preStart( pHddCtx->pvosContext );
9679 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9680 {
9681 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309682 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009683 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009684
Arif Hussaineaf68602013-12-30 23:10:44 -08009685 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9686 {
9687 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9688 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9689 __func__, enable_dfs_chan_scan);
9690 }
9691 if (0 == enable_11d || 1 == enable_11d)
9692 {
9693 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9694 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9695 __func__, enable_11d);
9696 }
9697
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009698 /* Note that the vos_preStart() sequence triggers the cfg download.
9699 The cfg download must occur before we update the SME config
9700 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 status = hdd_set_sme_config( pHddCtx );
9702
9703 if ( VOS_STATUS_SUCCESS != status )
9704 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009705 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309706 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009707 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009708
Jeff Johnson295189b2012-06-20 16:38:30 -07009709 /* In the integrated architecture we update the configuration from
9710 the INI file and from NV before vOSS has been started so that
9711 the final contents are available to send down to the cCPU */
9712
9713 // Apply the cfg.ini to cfg.dat
9714 if (FALSE == hdd_update_config_dat(pHddCtx))
9715 {
9716 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309717 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009718 }
9719
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309720 // Get mac addr from platform driver
9721 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9722
9723 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009724 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309725 /* Store the mac addr for first interface */
9726 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9727
9728 hddLog(VOS_TRACE_LEVEL_ERROR,
9729 "%s: WLAN Mac Addr: "
9730 MAC_ADDRESS_STR, __func__,
9731 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9732
9733 /* Here, passing Arg2 as 1 because we do not want to change the
9734 last 3 bytes (means non OUI bytes) of first interface mac
9735 addr.
9736 */
9737 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9738 {
9739 hddLog(VOS_TRACE_LEVEL_ERROR,
9740 "%s: Failed to generate wlan interface mac addr "
9741 "using MAC from ini file ", __func__);
9742 }
9743 }
9744 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9745 {
9746 // Apply the NV to cfg.dat
9747 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009748#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9749 /* There was not a valid set of MAC Addresses in NV. See if the
9750 default addresses were modified by the cfg.ini settings. If so,
9751 we'll use them, but if not, we'll autogenerate a set of MAC
9752 addresses based upon the device serial number */
9753
9754 static const v_MACADDR_t default_address =
9755 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009756
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309757 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9758 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 {
9760 /* cfg.ini has the default address, invoke autogen logic */
9761
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309762 /* Here, passing Arg2 as 0 because we want to change the
9763 last 3 bytes (means non OUI bytes) of all the interfaces
9764 mac addr.
9765 */
9766 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9767 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309769 hddLog(VOS_TRACE_LEVEL_ERROR,
9770 "%s: Failed to generate wlan interface mac addr "
9771 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9772 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009773 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 }
9775 else
9776#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9777 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009778 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 "%s: Invalid MAC address in NV, using MAC from ini file "
9780 MAC_ADDRESS_STR, __func__,
9781 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9782 }
9783 }
9784 {
9785 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309786
9787 /* Set the MAC Address Currently this is used by HAL to
9788 * add self sta. Remove this once self sta is added as
9789 * part of session open.
9790 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009791 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9792 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9793 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309794
Jeff Johnson295189b2012-06-20 16:38:30 -07009795 if (!HAL_STATUS_SUCCESS( halStatus ))
9796 {
9797 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9798 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309799 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 }
9801 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009802
9803 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9804 Note: Firmware image will be read and downloaded inside vos_start API */
9805 status = vos_start( pHddCtx->pvosContext );
9806 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9807 {
9808 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309809 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009810 }
9811
Leo Chang6cec3e22014-01-21 15:33:49 -08009812#ifdef FEATURE_WLAN_CH_AVOID
9813 /* Plug in avoid channel notification callback
9814 * This should happen before ADD_SELF_STA
9815 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309816
9817 /* check the Channel Avoidance is enabled */
9818 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9819 {
9820 sme_AddChAvoidCallback(pHddCtx->hHal,
9821 hdd_hostapd_ch_avoid_cb);
9822 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009823#endif /* FEATURE_WLAN_CH_AVOID */
9824
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009825 /* Exchange capability info between Host and FW and also get versioning info from FW */
9826 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009827
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309828#ifdef CONFIG_ENABLE_LINUX_REG
9829 status = wlan_hdd_init_channels(pHddCtx);
9830 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9831 {
9832 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9833 __func__);
9834 goto err_vosstop;
9835 }
9836#endif
9837
Jeff Johnson295189b2012-06-20 16:38:30 -07009838 status = hdd_post_voss_start_config( pHddCtx );
9839 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9840 {
9841 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9842 __func__);
9843 goto err_vosstop;
9844 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009845
9846#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309847 wlan_hdd_cfg80211_update_reg_info( wiphy );
9848
9849 /* registration of wiphy dev with cfg80211 */
9850 if (0 > wlan_hdd_cfg80211_register(wiphy))
9851 {
9852 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9853 goto err_vosstop;
9854 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009855#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009856
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309857#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309858 /* registration of wiphy dev with cfg80211 */
9859 if (0 > wlan_hdd_cfg80211_register(wiphy))
9860 {
9861 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9862 goto err_vosstop;
9863 }
9864
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309865 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309866 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9867 {
9868 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9869 __func__);
9870 goto err_unregister_wiphy;
9871 }
9872#endif
9873
c_hpothu4a298be2014-12-22 21:12:51 +05309874 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9875
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9877 {
9878 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9879 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9880 }
9881 else
9882 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9884 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9885 if (pAdapter != NULL)
9886 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309887 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309889 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9890 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9891 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009892
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309893 /* Generate the P2P Device Address. This consists of the device's
9894 * primary MAC address with the locally administered bit set.
9895 */
9896 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009897 }
9898 else
9899 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309900 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9901 if (p2p_dev_addr != NULL)
9902 {
9903 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9904 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9905 }
9906 else
9907 {
9908 hddLog(VOS_TRACE_LEVEL_FATAL,
9909 "%s: Failed to allocate mac_address for p2p_device",
9910 __func__);
9911 goto err_close_adapter;
9912 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009914
9915 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9916 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9917 if ( NULL == pP2pAdapter )
9918 {
9919 hddLog(VOS_TRACE_LEVEL_FATAL,
9920 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009921 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009922 goto err_close_adapter;
9923 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009925 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009926
9927 if( pAdapter == NULL )
9928 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009929 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9930 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009932
Arif Hussain66559122013-11-21 10:11:40 -08009933 if (country_code)
9934 {
9935 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009936 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009937 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9938#ifndef CONFIG_ENABLE_LINUX_REG
9939 hdd_checkandupdate_phymode(pAdapter, country_code);
9940#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009941 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9942 (void *)(tSmeChangeCountryCallback)
9943 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009944 country_code,
9945 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309946 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009947 if (eHAL_STATUS_SUCCESS == ret)
9948 {
Arif Hussaincb607082013-12-20 11:57:42 -08009949 ret = wait_for_completion_interruptible_timeout(
9950 &pAdapter->change_country_code,
9951 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9952
9953 if (0 >= ret)
9954 {
9955 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9956 "%s: SME while setting country code timed out", __func__);
9957 }
Arif Hussain66559122013-11-21 10:11:40 -08009958 }
9959 else
9960 {
Arif Hussaincb607082013-12-20 11:57:42 -08009961 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9962 "%s: SME Change Country code from module param fail ret=%d",
9963 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009964 }
9965 }
9966
Jeff Johnson295189b2012-06-20 16:38:30 -07009967#ifdef WLAN_BTAMP_FEATURE
9968 vStatus = WLANBAP_Open(pVosContext);
9969 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9970 {
9971 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9972 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009973 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 }
9975
9976 vStatus = BSL_Init(pVosContext);
9977 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9978 {
9979 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9980 "%s: Failed to Init BSL",__func__);
9981 goto err_bap_close;
9982 }
9983 vStatus = WLANBAP_Start(pVosContext);
9984 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9985 {
9986 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9987 "%s: Failed to start TL",__func__);
9988 goto err_bap_close;
9989 }
9990
9991 pConfig = pHddCtx->cfg_ini;
9992 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9993 status = WLANBAP_SetConfig(&btAmpConfig);
9994
9995#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009996
Mihir Shete9c238772014-10-15 14:35:16 +05309997 /*
9998 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9999 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
10000 * which is greater than 0xf. So the below check is safe to make
10001 * sure that there is no entry for UapsdMask in the ini
10002 */
10003 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
10004 {
10005 if(IS_DYNAMIC_WMM_PS_ENABLED)
10006 {
10007 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
10008 __func__);
10009 pHddCtx->cfg_ini->UapsdMask =
10010 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
10011 }
10012 else
10013 {
10014 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10015 __func__);
10016 pHddCtx->cfg_ini->UapsdMask =
10017 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10018 }
10019 }
10020
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010021#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10022 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10023 {
10024 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10025 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10026 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10027 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10028 }
10029#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010030
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010031 wlan_hdd_tdls_init(pHddCtx);
10032
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010033 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10034
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 /* Register with platform driver as client for Suspend/Resume */
10036 status = hddRegisterPmOps(pHddCtx);
10037 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10038 {
10039 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10040#ifdef WLAN_BTAMP_FEATURE
10041 goto err_bap_stop;
10042#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010043 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010044#endif //WLAN_BTAMP_FEATURE
10045 }
10046
Yue Ma0d4891e2013-08-06 17:01:45 -070010047 /* Open debugfs interface */
10048 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10049 {
10050 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10051 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010052 }
10053
Jeff Johnson295189b2012-06-20 16:38:30 -070010054 /* Register TM level change handler function to the platform */
10055 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10056 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10057 {
10058 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10059 goto err_unregister_pmops;
10060 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010061
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 // register net device notifier for device change notification
10063 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10064
10065 if(ret < 0)
10066 {
10067 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010068 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 }
10070
10071 //Initialize the nlink service
10072 if(nl_srv_init() != 0)
10073 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010074 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010075 goto err_reg_netdev;
10076 }
10077
Leo Chang4ce1cc52013-10-21 18:27:15 -070010078#ifdef WLAN_KD_READY_NOTIFIER
10079 pHddCtx->kd_nl_init = 1;
10080#endif /* WLAN_KD_READY_NOTIFIER */
10081
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 //Initialize the BTC service
10083 if(btc_activate_service(pHddCtx) != 0)
10084 {
10085 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10086 goto err_nl_srv;
10087 }
10088
10089#ifdef PTT_SOCK_SVC_ENABLE
10090 //Initialize the PTT service
10091 if(ptt_sock_activate_svc(pHddCtx) != 0)
10092 {
10093 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10094 goto err_nl_srv;
10095 }
10096#endif
10097
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010098#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10099 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10100 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010101 if(wlan_logging_sock_activate_svc(
10102 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10103 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10104 {
10105 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10106 " failed", __func__);
10107 goto err_nl_srv;
10108 }
10109 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10110 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010111 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10112 pHddCtx->cfg_ini->gEnableDebugLog =
10113 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010114 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010115
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010116 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10117 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010118 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010119 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010120 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010121 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010122 }
10123 else
10124 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010125 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010126 }
10127
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010128#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010129
10130
Sushant Kaushik215778f2015-05-21 14:05:36 +053010131 if (vos_is_multicast_logging())
10132 wlan_logging_set_log_level();
10133
Jeff Johnson295189b2012-06-20 16:38:30 -070010134 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010135 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010136 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010137 /* Action frame registered in one adapter which will
10138 * applicable to all interfaces
10139 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010140 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010141 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010142
10143 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010144 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010145
Jeff Johnsone7245742012-09-05 17:12:55 -070010146#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10147 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010148 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010149 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010150
Jeff Johnsone7245742012-09-05 17:12:55 -070010151#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010152 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010153 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010154 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010155
Jeff Johnsone7245742012-09-05 17:12:55 -070010156
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010157 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10158 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010159
Katya Nigam5c306ea2014-06-19 15:39:54 +053010160 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010161 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010162 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010163
10164#ifdef FEATURE_WLAN_SCAN_PNO
10165 /*SME must send channel update configuration to RIVA*/
10166 sme_UpdateChannelConfig(pHddCtx->hHal);
10167#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010168 /* Send the update default channel list to the FW*/
10169 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010170
10171 /* Fwr capabilities received, Set the Dot11 mode */
10172 sme_SetDefDot11Mode(pHddCtx->hHal);
10173
Abhishek Singha306a442013-11-07 18:39:01 +053010174#ifndef CONFIG_ENABLE_LINUX_REG
10175 /*updating wiphy so that regulatory user hints can be processed*/
10176 if (wiphy)
10177 {
10178 regulatory_hint(wiphy, "00");
10179 }
10180#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010181 // Initialize the restart logic
10182 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010183
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010184 //Register the traffic monitor timer now
10185 if ( pHddCtx->cfg_ini->dynSplitscan)
10186 {
10187 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10188 VOS_TIMER_TYPE_SW,
10189 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10190 (void *)pHddCtx);
10191 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010192 wlan_hdd_cfg80211_nan_init(pHddCtx);
10193
Dino Mycle6fb96c12014-06-10 11:52:40 +053010194#ifdef WLAN_FEATURE_EXTSCAN
10195 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10196 wlan_hdd_cfg80211_extscan_callback,
10197 pHddCtx);
10198#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010199
10200#ifdef WLAN_NS_OFFLOAD
10201 // Register IPv6 notifier to notify if any change in IP
10202 // So that we can reconfigure the offload parameters
10203 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10204 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10205 if (ret)
10206 {
10207 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10208 }
10209 else
10210 {
10211 hddLog(LOGE, FL("Registered IPv6 notifier"));
10212 }
10213#endif
10214
10215 // Register IPv4 notifier to notify if any change in IP
10216 // So that we can reconfigure the offload parameters
10217 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10218 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10219 if (ret)
10220 {
10221 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10222 }
10223 else
10224 {
10225 hddLog(LOGE, FL("Registered IPv4 notifier"));
10226 }
10227
Jeff Johnson295189b2012-06-20 16:38:30 -070010228 goto success;
10229
10230err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010231#ifdef WLAN_KD_READY_NOTIFIER
10232 nl_srv_exit(pHddCtx->ptt_pid);
10233#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010234 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010235#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010236err_reg_netdev:
10237 unregister_netdevice_notifier(&hdd_netdev_notifier);
10238
Jeff Johnson295189b2012-06-20 16:38:30 -070010239err_unregister_pmops:
10240 hddDevTmUnregisterNotifyCallback(pHddCtx);
10241 hddDeregisterPmOps(pHddCtx);
10242
Yue Ma0d4891e2013-08-06 17:01:45 -070010243 hdd_debugfs_exit(pHddCtx);
10244
Jeff Johnson295189b2012-06-20 16:38:30 -070010245#ifdef WLAN_BTAMP_FEATURE
10246err_bap_stop:
10247 WLANBAP_Stop(pVosContext);
10248#endif
10249
10250#ifdef WLAN_BTAMP_FEATURE
10251err_bap_close:
10252 WLANBAP_Close(pVosContext);
10253#endif
10254
Jeff Johnson295189b2012-06-20 16:38:30 -070010255err_close_adapter:
10256 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010257#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010258err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010259#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010260 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010261err_vosstop:
10262 vos_stop(pVosContext);
10263
Amar Singhala49cbc52013-10-08 18:37:44 -070010264err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 status = vos_sched_close( pVosContext );
10266 if (!VOS_IS_STATUS_SUCCESS(status)) {
10267 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10268 "%s: Failed to close VOSS Scheduler", __func__);
10269 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10270 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010271 vos_close(pVosContext );
10272
Amar Singhal0a402232013-10-11 20:57:16 -070010273err_vos_nv_close:
10274
c_hpothue6a36282014-03-19 12:27:38 +053010275#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010276 vos_nv_close();
10277
c_hpothu70f8d812014-03-22 22:59:23 +053010278#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010279
10280err_wdclose:
10281 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10282 vos_watchdog_close(pVosContext);
10283
Jeff Johnson295189b2012-06-20 16:38:30 -070010284err_config:
10285 kfree(pHddCtx->cfg_ini);
10286 pHddCtx->cfg_ini= NULL;
10287
10288err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010289 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010290 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010291 wiphy_free(wiphy) ;
10292 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 VOS_BUG(1);
10294
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010295 if (hdd_is_ssr_required())
10296 {
10297 /* WDI timeout had happened during load, so SSR is needed here */
10298 subsystem_restart("wcnss");
10299 msleep(5000);
10300 }
10301 hdd_set_ssr_required (VOS_FALSE);
10302
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010303 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010304
10305success:
10306 EXIT();
10307 return 0;
10308}
10309
10310/**---------------------------------------------------------------------------
10311
Jeff Johnson32d95a32012-09-10 13:15:23 -070010312 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010313
Jeff Johnson32d95a32012-09-10 13:15:23 -070010314 This is the driver entry point - called in different timeline depending
10315 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010316
10317 \param - None
10318
10319 \return - 0 for success, non zero for failure
10320
10321 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010322static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010323{
10324 VOS_STATUS status;
10325 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 struct device *dev = NULL;
10327 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010328#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10329 int max_retries = 0;
10330#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010331#ifdef HAVE_CBC_DONE
10332 int max_cbc_retries = 0;
10333#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010334
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010335#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10336 wlan_logging_sock_init_svc();
10337#endif
10338
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 ENTER();
10340
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010341 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010342
10343 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10344 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10345
Jeff Johnson295189b2012-06-20 16:38:30 -070010346#ifdef ANI_BUS_TYPE_PCI
10347
10348 dev = wcnss_wlan_get_device();
10349
10350#endif // ANI_BUS_TYPE_PCI
10351
10352#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010353
10354#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10355 /* wait until WCNSS driver downloads NV */
10356 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10357 msleep(1000);
10358 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010359
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010360 if (max_retries >= 5) {
10361 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010362 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010363#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10364 wlan_logging_sock_deinit_svc();
10365#endif
10366
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010367 return -ENODEV;
10368 }
10369#endif
10370
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010371#ifdef HAVE_CBC_DONE
10372 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10373 msleep(1000);
10374 }
10375 if (max_cbc_retries >= 10) {
10376 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10377 }
10378#endif
10379
Jeff Johnson295189b2012-06-20 16:38:30 -070010380 dev = wcnss_wlan_get_device();
10381#endif // ANI_BUS_TYPE_PLATFORM
10382
10383
10384 do {
10385 if (NULL == dev) {
10386 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10387 ret_status = -1;
10388 break;
10389 }
10390
Jeff Johnson295189b2012-06-20 16:38:30 -070010391#ifdef TIMER_MANAGER
10392 vos_timer_manager_init();
10393#endif
10394
10395 /* Preopen VOSS so that it is ready to start at least SAL */
10396 status = vos_preOpen(&pVosContext);
10397
10398 if (!VOS_IS_STATUS_SUCCESS(status))
10399 {
10400 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10401 ret_status = -1;
10402 break;
10403 }
10404
Sushant Kaushik02beb352015-06-04 15:15:01 +053010405 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010406#ifndef MODULE
10407 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10408 */
10409 hdd_set_conparam((v_UINT_t)con_mode);
10410#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010411
10412 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010413 if (hdd_wlan_startup(dev))
10414 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010416 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010417 vos_preClose( &pVosContext );
10418 ret_status = -1;
10419 break;
10420 }
10421
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 } while (0);
10423
10424 if (0 != ret_status)
10425 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010426#ifdef TIMER_MANAGER
10427 vos_timer_exit();
10428#endif
10429#ifdef MEMORY_DEBUG
10430 vos_mem_exit();
10431#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010432 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010433#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10434 wlan_logging_sock_deinit_svc();
10435#endif
10436
Jeff Johnson295189b2012-06-20 16:38:30 -070010437 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10438 }
10439 else
10440 {
10441 //Send WLAN UP indication to Nlink Service
10442 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10443
10444 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010445 }
10446
10447 EXIT();
10448
10449 return ret_status;
10450}
10451
Jeff Johnson32d95a32012-09-10 13:15:23 -070010452/**---------------------------------------------------------------------------
10453
10454 \brief hdd_module_init() - Init Function
10455
10456 This is the driver entry point (invoked when module is loaded using insmod)
10457
10458 \param - None
10459
10460 \return - 0 for success, non zero for failure
10461
10462 --------------------------------------------------------------------------*/
10463#ifdef MODULE
10464static int __init hdd_module_init ( void)
10465{
10466 return hdd_driver_init();
10467}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010468#else /* #ifdef MODULE */
10469static int __init hdd_module_init ( void)
10470{
10471 /* Driver initialization is delayed to fwpath_changed_handler */
10472 return 0;
10473}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010474#endif /* #ifdef MODULE */
10475
Jeff Johnson295189b2012-06-20 16:38:30 -070010476
10477/**---------------------------------------------------------------------------
10478
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010479 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010480
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010481 This is the driver exit point (invoked when module is unloaded using rmmod
10482 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010483
10484 \param - None
10485
10486 \return - None
10487
10488 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010489static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010490{
10491 hdd_context_t *pHddCtx = NULL;
10492 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010493 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010494 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010495
10496 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10497
10498 //Get the global vos context
10499 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10500
10501 if(!pVosContext)
10502 {
10503 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10504 goto done;
10505 }
10506
10507 //Get the HDD context.
10508 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10509
10510 if(!pHddCtx)
10511 {
10512 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10513 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010514 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10515 {
10516 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10517 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10518 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10519 hdd_wlan_exit(pHddCtx);
10520 vos_preClose( &pVosContext );
10521 goto done;
10522 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010523 else
10524 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010525 /* We wait for active entry threads to exit from driver
10526 * by waiting until rtnl_lock is available.
10527 */
10528 rtnl_lock();
10529 rtnl_unlock();
10530
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010531 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10532 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10533 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10534 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010536 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010537 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10538 msecs_to_jiffies(30000));
10539 if(!rc)
10540 {
10541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10542 "%s:SSR timedout, fatal error", __func__);
10543 VOS_BUG(0);
10544 }
10545 }
10546
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010547 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10548 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010549
c_hpothu8adb97b2014-12-08 19:38:20 +053010550 /* Driver Need to send country code 00 in below condition
10551 * 1) If gCountryCodePriority is set to 1; and last country
10552 * code set is through 11d. This needs to be done in case
10553 * when NV country code is 00.
10554 * This Needs to be done as when kernel store last country
10555 * code and if stored country code is not through 11d,
10556 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10557 * in next load/unload as soon as we get any country through
10558 * 11d. In sme_HandleChangeCountryCodeByUser
10559 * pMsg->countryCode will be last countryCode and
10560 * pMac->scan.countryCode11d will be country through 11d so
10561 * due to mismatch driver will disable 11d.
10562 *
10563 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010564
c_hpothu8adb97b2014-12-08 19:38:20 +053010565 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010566 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010567 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010568 {
10569 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010570 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010571 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10572 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010573
c_hpothu8adb97b2014-12-08 19:38:20 +053010574 //Do all the cleanup before deregistering the driver
10575 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010576 }
10577
Jeff Johnson295189b2012-06-20 16:38:30 -070010578 vos_preClose( &pVosContext );
10579
10580#ifdef TIMER_MANAGER
10581 vos_timer_exit();
10582#endif
10583#ifdef MEMORY_DEBUG
10584 vos_mem_exit();
10585#endif
10586
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010587#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10588 wlan_logging_sock_deinit_svc();
10589#endif
10590
Jeff Johnson295189b2012-06-20 16:38:30 -070010591done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010592 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010593
Jeff Johnson295189b2012-06-20 16:38:30 -070010594 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10595}
10596
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010597/**---------------------------------------------------------------------------
10598
10599 \brief hdd_module_exit() - Exit function
10600
10601 This is the driver exit point (invoked when module is unloaded using rmmod)
10602
10603 \param - None
10604
10605 \return - None
10606
10607 --------------------------------------------------------------------------*/
10608static void __exit hdd_module_exit(void)
10609{
10610 hdd_driver_exit();
10611}
10612
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010613#ifdef MODULE
10614static int fwpath_changed_handler(const char *kmessage,
10615 struct kernel_param *kp)
10616{
Jeff Johnson76052702013-04-16 13:55:05 -070010617 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010618}
10619
10620static int con_mode_handler(const char *kmessage,
10621 struct kernel_param *kp)
10622{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010623 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010624}
10625#else /* #ifdef MODULE */
10626/**---------------------------------------------------------------------------
10627
Jeff Johnson76052702013-04-16 13:55:05 -070010628 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010629
Jeff Johnson76052702013-04-16 13:55:05 -070010630 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010631 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010632 - invoked when module parameter fwpath is modified from userspace to signal
10633 initializing the WLAN driver or when con_mode is modified from userspace
10634 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010635
10636 \return - 0 for success, non zero for failure
10637
10638 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010639static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010640{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010641 int ret_status;
10642
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010643 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010644 ret_status = hdd_driver_init();
10645 wlan_hdd_inited = ret_status ? 0 : 1;
10646 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010647 }
10648
10649 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010650
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010651 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010652
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010653 ret_status = hdd_driver_init();
10654 wlan_hdd_inited = ret_status ? 0 : 1;
10655 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010656}
10657
Jeff Johnson295189b2012-06-20 16:38:30 -070010658/**---------------------------------------------------------------------------
10659
Jeff Johnson76052702013-04-16 13:55:05 -070010660 \brief fwpath_changed_handler() - Handler Function
10661
10662 Handle changes to the fwpath parameter
10663
10664 \return - 0 for success, non zero for failure
10665
10666 --------------------------------------------------------------------------*/
10667static int fwpath_changed_handler(const char *kmessage,
10668 struct kernel_param *kp)
10669{
10670 int ret;
10671
10672 ret = param_set_copystring(kmessage, kp);
10673 if (0 == ret)
10674 ret = kickstart_driver();
10675 return ret;
10676}
10677
10678/**---------------------------------------------------------------------------
10679
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010680 \brief con_mode_handler() -
10681
10682 Handler function for module param con_mode when it is changed by userspace
10683 Dynamically linked - do nothing
10684 Statically linked - exit and init driver, as in rmmod and insmod
10685
Jeff Johnson76052702013-04-16 13:55:05 -070010686 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010687
Jeff Johnson76052702013-04-16 13:55:05 -070010688 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010689
10690 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010691static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010692{
Jeff Johnson76052702013-04-16 13:55:05 -070010693 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010694
Jeff Johnson76052702013-04-16 13:55:05 -070010695 ret = param_set_int(kmessage, kp);
10696 if (0 == ret)
10697 ret = kickstart_driver();
10698 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010699}
10700#endif /* #ifdef MODULE */
10701
10702/**---------------------------------------------------------------------------
10703
Jeff Johnson295189b2012-06-20 16:38:30 -070010704 \brief hdd_get_conparam() -
10705
10706 This is the driver exit point (invoked when module is unloaded using rmmod)
10707
10708 \param - None
10709
10710 \return - tVOS_CON_MODE
10711
10712 --------------------------------------------------------------------------*/
10713tVOS_CON_MODE hdd_get_conparam ( void )
10714{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010715#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010717#else
10718 return (tVOS_CON_MODE)curr_con_mode;
10719#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010720}
10721void hdd_set_conparam ( v_UINT_t newParam )
10722{
10723 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010724#ifndef MODULE
10725 curr_con_mode = con_mode;
10726#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010727}
10728/**---------------------------------------------------------------------------
10729
10730 \brief hdd_softap_sta_deauth() - function
10731
10732 This to take counter measure to handle deauth req from HDD
10733
10734 \param - pAdapter - Pointer to the HDD
10735
10736 \param - enable - boolean value
10737
10738 \return - None
10739
10740 --------------------------------------------------------------------------*/
10741
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010742VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10743 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010744{
Jeff Johnson295189b2012-06-20 16:38:30 -070010745 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010746 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010747
10748 ENTER();
10749
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010750 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10751 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010752
10753 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010754 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010755 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010756
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010757 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010758
10759 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010760 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010761}
10762
10763/**---------------------------------------------------------------------------
10764
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010765 \brief hdd_del_all_sta() - function
10766
10767 This function removes all the stations associated on stopping AP/P2P GO.
10768
10769 \param - pAdapter - Pointer to the HDD
10770
10771 \return - None
10772
10773 --------------------------------------------------------------------------*/
10774
10775int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10776{
10777 v_U16_t i;
10778 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010779 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10780 ptSapContext pSapCtx = NULL;
10781 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10782 if(pSapCtx == NULL){
10783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10784 FL("psapCtx is NULL"));
10785 return 1;
10786 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010787 ENTER();
10788
10789 hddLog(VOS_TRACE_LEVEL_INFO,
10790 "%s: Delete all STAs associated.",__func__);
10791 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10792 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10793 )
10794 {
10795 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10796 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010797 if ((pSapCtx->aStaInfo[i].isUsed) &&
10798 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010799 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010800 struct tagCsrDelStaParams delStaParams;
10801
10802 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010803 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010804 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10805 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010806 &delStaParams);
10807 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010808 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010809 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010810 }
10811 }
10812 }
10813
10814 EXIT();
10815 return 0;
10816}
10817
10818/**---------------------------------------------------------------------------
10819
Jeff Johnson295189b2012-06-20 16:38:30 -070010820 \brief hdd_softap_sta_disassoc() - function
10821
10822 This to take counter measure to handle deauth req from HDD
10823
10824 \param - pAdapter - Pointer to the HDD
10825
10826 \param - enable - boolean value
10827
10828 \return - None
10829
10830 --------------------------------------------------------------------------*/
10831
10832void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10833{
10834 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10835
10836 ENTER();
10837
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010838 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010839
10840 //Ignore request to disassoc bcmc station
10841 if( pDestMacAddress[0] & 0x1 )
10842 return;
10843
10844 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10845}
10846
10847void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10848{
10849 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10850
10851 ENTER();
10852
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010853 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010854
10855 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10856}
10857
Jeff Johnson295189b2012-06-20 16:38:30 -070010858/**---------------------------------------------------------------------------
10859 *
10860 * \brief hdd_get__concurrency_mode() -
10861 *
10862 *
10863 * \param - None
10864 *
10865 * \return - CONCURRENCY MODE
10866 *
10867 * --------------------------------------------------------------------------*/
10868tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10869{
10870 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10871 hdd_context_t *pHddCtx;
10872
10873 if (NULL != pVosContext)
10874 {
10875 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10876 if (NULL != pHddCtx)
10877 {
10878 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10879 }
10880 }
10881
10882 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010883 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010884 return VOS_STA;
10885}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010886v_BOOL_t
10887wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10888{
10889 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010890
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010891 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10892 if (pAdapter == NULL)
10893 {
10894 hddLog(VOS_TRACE_LEVEL_INFO,
10895 FL("GO doesn't exist"));
10896 return TRUE;
10897 }
10898 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10899 {
10900 hddLog(VOS_TRACE_LEVEL_INFO,
10901 FL("GO started"));
10902 return TRUE;
10903 }
10904 else
10905 /* wait till GO changes its interface to p2p device */
10906 hddLog(VOS_TRACE_LEVEL_INFO,
10907 FL("Del_bss called, avoid apps suspend"));
10908 return FALSE;
10909
10910}
Jeff Johnson295189b2012-06-20 16:38:30 -070010911/* Decide whether to allow/not the apps power collapse.
10912 * Allow apps power collapse if we are in connected state.
10913 * if not, allow only if we are in IMPS */
10914v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10915{
10916 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010917 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010918 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010919 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10920 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10921 hdd_adapter_t *pAdapter = NULL;
10922 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010923 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010924
Jeff Johnson295189b2012-06-20 16:38:30 -070010925 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10926 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010927
Yathish9f22e662012-12-10 14:21:35 -080010928 concurrent_state = hdd_get_concurrency_mode();
10929
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010930 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10931 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10932 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010933#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010934
Yathish9f22e662012-12-10 14:21:35 -080010935 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010936 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010937 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10938 return TRUE;
10939#endif
10940
Jeff Johnson295189b2012-06-20 16:38:30 -070010941 /*loop through all adapters. TBD fix for Concurrency */
10942 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10943 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10944 {
10945 pAdapter = pAdapterNode->pAdapter;
10946 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10947 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10948 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010949 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010950 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010951 && pmcState != STOPPED && pmcState != STANDBY &&
10952 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010953 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10954 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010955 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010956 if(pmcState == FULL_POWER &&
10957 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10958 {
10959 /*
10960 * When SCO indication comes from Coex module , host will
10961 * enter in to full power mode, but this should not prevent
10962 * apps processor power collapse.
10963 */
10964 hddLog(LOG1,
10965 FL("Allow apps power collapse"
10966 "even when sco indication is set"));
10967 return TRUE;
10968 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010969 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010970 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10971 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010972 return FALSE;
10973 }
10974 }
10975 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10976 pAdapterNode = pNext;
10977 }
10978 return TRUE;
10979}
10980
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010981/* Decides whether to send suspend notification to Riva
10982 * if any adapter is in BMPS; then it is required */
10983v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10984{
10985 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10986 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10987
10988 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10989 {
10990 return TRUE;
10991 }
10992 return FALSE;
10993}
10994
Jeff Johnson295189b2012-06-20 16:38:30 -070010995void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10996{
10997 switch(mode)
10998 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010999 case VOS_STA_MODE:
11000 case VOS_P2P_CLIENT_MODE:
11001 case VOS_P2P_GO_MODE:
11002 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070011003 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011004 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 break;
11006 default:
11007 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011009 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11010 "Number of open sessions for mode %d = %d"),
11011 pHddCtx->concurrency_mode, mode,
11012 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011013}
11014
11015
11016void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11017{
11018 switch(mode)
11019 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011020 case VOS_STA_MODE:
11021 case VOS_P2P_CLIENT_MODE:
11022 case VOS_P2P_GO_MODE:
11023 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011024 pHddCtx->no_of_open_sessions[mode]--;
11025 if (!(pHddCtx->no_of_open_sessions[mode]))
11026 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011027 break;
11028 default:
11029 break;
11030 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011031 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11032 "Number of open sessions for mode %d = %d"),
11033 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11034
11035}
11036/**---------------------------------------------------------------------------
11037 *
11038 * \brief wlan_hdd_incr_active_session()
11039 *
11040 * This function increments the number of active sessions
11041 * maintained per device mode
11042 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11043 * Incase of SAP/P2P GO upon bss start it is incremented
11044 *
11045 * \param pHddCtx - HDD Context
11046 * \param mode - device mode
11047 *
11048 * \return - None
11049 *
11050 * --------------------------------------------------------------------------*/
11051void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11052{
11053 switch (mode) {
11054 case VOS_STA_MODE:
11055 case VOS_P2P_CLIENT_MODE:
11056 case VOS_P2P_GO_MODE:
11057 case VOS_STA_SAP_MODE:
11058 pHddCtx->no_of_active_sessions[mode]++;
11059 break;
11060 default:
11061 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11062 break;
11063 }
11064 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11065 mode,
11066 pHddCtx->no_of_active_sessions[mode]);
11067}
11068
11069/**---------------------------------------------------------------------------
11070 *
11071 * \brief wlan_hdd_decr_active_session()
11072 *
11073 * This function decrements the number of active sessions
11074 * maintained per device mode
11075 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11076 * Incase of SAP/P2P GO upon bss stop it is decremented
11077 *
11078 * \param pHddCtx - HDD Context
11079 * \param mode - device mode
11080 *
11081 * \return - None
11082 *
11083 * --------------------------------------------------------------------------*/
11084void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11085{
11086 switch (mode) {
11087 case VOS_STA_MODE:
11088 case VOS_P2P_CLIENT_MODE:
11089 case VOS_P2P_GO_MODE:
11090 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011091 if (pHddCtx->no_of_active_sessions[mode] > 0)
11092 pHddCtx->no_of_active_sessions[mode]--;
11093 else
11094 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11095 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011096 break;
11097 default:
11098 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11099 break;
11100 }
11101 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11102 mode,
11103 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011104}
11105
Jeff Johnsone7245742012-09-05 17:12:55 -070011106/**---------------------------------------------------------------------------
11107 *
11108 * \brief wlan_hdd_restart_init
11109 *
11110 * This function initalizes restart timer/flag. An internal function.
11111 *
11112 * \param - pHddCtx
11113 *
11114 * \return - None
11115 *
11116 * --------------------------------------------------------------------------*/
11117
11118static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11119{
11120 /* Initialize */
11121 pHddCtx->hdd_restart_retries = 0;
11122 atomic_set(&pHddCtx->isRestartInProgress, 0);
11123 vos_timer_init(&pHddCtx->hdd_restart_timer,
11124 VOS_TIMER_TYPE_SW,
11125 wlan_hdd_restart_timer_cb,
11126 pHddCtx);
11127}
11128/**---------------------------------------------------------------------------
11129 *
11130 * \brief wlan_hdd_restart_deinit
11131 *
11132 * This function cleans up the resources used. An internal function.
11133 *
11134 * \param - pHddCtx
11135 *
11136 * \return - None
11137 *
11138 * --------------------------------------------------------------------------*/
11139
11140static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11141{
11142
11143 VOS_STATUS vos_status;
11144 /* Block any further calls */
11145 atomic_set(&pHddCtx->isRestartInProgress, 1);
11146 /* Cleanup */
11147 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11148 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011149 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011150 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11151 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011152 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011153
11154}
11155
11156/**---------------------------------------------------------------------------
11157 *
11158 * \brief wlan_hdd_framework_restart
11159 *
11160 * This function uses a cfg80211 API to start a framework initiated WLAN
11161 * driver module unload/load.
11162 *
11163 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11164 *
11165 *
11166 * \param - pHddCtx
11167 *
11168 * \return - VOS_STATUS_SUCCESS: Success
11169 * VOS_STATUS_E_EMPTY: Adapter is Empty
11170 * VOS_STATUS_E_NOMEM: No memory
11171
11172 * --------------------------------------------------------------------------*/
11173
11174static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11175{
11176 VOS_STATUS status = VOS_STATUS_SUCCESS;
11177 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011178 int len = (sizeof (struct ieee80211_mgmt));
11179 struct ieee80211_mgmt *mgmt = NULL;
11180
11181 /* Prepare the DEAUTH managment frame with reason code */
11182 mgmt = kzalloc(len, GFP_KERNEL);
11183 if(mgmt == NULL)
11184 {
11185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11186 "%s: memory allocation failed (%d bytes)", __func__, len);
11187 return VOS_STATUS_E_NOMEM;
11188 }
11189 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011190
11191 /* Iterate over all adapters/devices */
11192 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011193 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11194 {
11195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11196 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11197 goto end;
11198 }
11199
Jeff Johnsone7245742012-09-05 17:12:55 -070011200 do
11201 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011202 if(pAdapterNode->pAdapter &&
11203 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011204 {
11205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11206 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11207 pAdapterNode->pAdapter->dev->name,
11208 pAdapterNode->pAdapter->device_mode,
11209 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011210 /*
11211 * CFG80211 event to restart the driver
11212 *
11213 * 'cfg80211_send_unprot_deauth' sends a
11214 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11215 * of SME(Linux Kernel) state machine.
11216 *
11217 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11218 * the driver.
11219 *
11220 */
11221
11222 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011223 }
11224 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11225 pAdapterNode = pNext;
11226 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11227
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011228 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011229 /* Free the allocated management frame */
11230 kfree(mgmt);
11231
Jeff Johnsone7245742012-09-05 17:12:55 -070011232 /* Retry until we unload or reach max count */
11233 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11234 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11235
11236 return status;
11237
11238}
11239/**---------------------------------------------------------------------------
11240 *
11241 * \brief wlan_hdd_restart_timer_cb
11242 *
11243 * Restart timer callback. An internal function.
11244 *
11245 * \param - User data:
11246 *
11247 * \return - None
11248 *
11249 * --------------------------------------------------------------------------*/
11250
11251void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11252{
11253 hdd_context_t *pHddCtx = usrDataForCallback;
11254 wlan_hdd_framework_restart(pHddCtx);
11255 return;
11256
11257}
11258
11259
11260/**---------------------------------------------------------------------------
11261 *
11262 * \brief wlan_hdd_restart_driver
11263 *
11264 * This function sends an event to supplicant to restart the WLAN driver.
11265 *
11266 * This function is called from vos_wlanRestart.
11267 *
11268 * \param - pHddCtx
11269 *
11270 * \return - VOS_STATUS_SUCCESS: Success
11271 * VOS_STATUS_E_EMPTY: Adapter is Empty
11272 * VOS_STATUS_E_ALREADY: Request already in progress
11273
11274 * --------------------------------------------------------------------------*/
11275VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11276{
11277 VOS_STATUS status = VOS_STATUS_SUCCESS;
11278
11279 /* A tight check to make sure reentrancy */
11280 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11281 {
Mihir Shetefd528652014-06-23 19:07:50 +053011282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011283 "%s: WLAN restart is already in progress", __func__);
11284
11285 return VOS_STATUS_E_ALREADY;
11286 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011287 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011288#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011289 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011290#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011291
Jeff Johnsone7245742012-09-05 17:12:55 -070011292 return status;
11293}
11294
Mihir Shetee1093ba2014-01-21 20:13:32 +053011295/**---------------------------------------------------------------------------
11296 *
11297 * \brief wlan_hdd_init_channels
11298 *
11299 * This function is used to initialize the channel list in CSR
11300 *
11301 * This function is called from hdd_wlan_startup
11302 *
11303 * \param - pHddCtx: HDD context
11304 *
11305 * \return - VOS_STATUS_SUCCESS: Success
11306 * VOS_STATUS_E_FAULT: Failure reported by SME
11307
11308 * --------------------------------------------------------------------------*/
11309static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11310{
11311 eHalStatus status;
11312
11313 status = sme_InitChannels(pHddCtx->hHal);
11314 if (HAL_STATUS_SUCCESS(status))
11315 {
11316 return VOS_STATUS_SUCCESS;
11317 }
11318 else
11319 {
11320 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11321 __func__, status);
11322 return VOS_STATUS_E_FAULT;
11323 }
11324}
11325
Mihir Shete04206452014-11-20 17:50:58 +053011326#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011327VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011328{
11329 eHalStatus status;
11330
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011331 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011332 if (HAL_STATUS_SUCCESS(status))
11333 {
11334 return VOS_STATUS_SUCCESS;
11335 }
11336 else
11337 {
11338 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11339 __func__, status);
11340 return VOS_STATUS_E_FAULT;
11341 }
11342}
Mihir Shete04206452014-11-20 17:50:58 +053011343#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011344/*
11345 * API to find if there is any STA or P2P-Client is connected
11346 */
11347VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11348{
11349 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11350}
Jeff Johnsone7245742012-09-05 17:12:55 -070011351
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011352
11353/*
11354 * API to find if the firmware will send logs using DXE channel
11355 */
11356v_U8_t hdd_is_fw_logging_enabled(void)
11357{
11358 hdd_context_t *pHddCtx;
11359
11360 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11361 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11362
Sachin Ahuja084313e2015-05-21 17:57:10 +053011363 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011364}
11365
Agarwal Ashish57e84372014-12-05 18:26:53 +053011366/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011367 * API to find if the firmware will send trace logs using DXE channel
11368 */
11369v_U8_t hdd_is_fw_ev_logging_enabled(void)
11370{
11371 hdd_context_t *pHddCtx;
11372
11373 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11374 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11375
11376 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11377}
11378/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011379 * API to find if there is any session connected
11380 */
11381VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11382{
11383 return sme_is_any_session_connected(pHddCtx->hHal);
11384}
11385
11386
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011387int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11388{
11389 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11390 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011391 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011392 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011393
11394 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011395 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011396 if (pScanInfo->mScanPending)
11397 {
c_hpothua3d45d52015-01-05 14:11:17 +053011398 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11399 eCSR_SCAN_ABORT_DEFAULT);
11400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11401 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011402
c_hpothua3d45d52015-01-05 14:11:17 +053011403 /* If there is active scan command lets wait for the completion else
11404 * there is no need to wait as scan command might be in the SME pending
11405 * command list.
11406 */
11407 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11408 {
c_hpothua3d45d52015-01-05 14:11:17 +053011409 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011410 &pScanInfo->abortscan_event_var,
11411 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011412 if (0 >= status)
11413 {
11414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011415 "%s: Timeout or Interrupt occurred while waiting for abort"
11416 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011417 return -ETIMEDOUT;
11418 }
11419 }
11420 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11421 {
11422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11423 FL("hdd_abort_mac_scan failed"));
11424 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011425 }
11426 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011427 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011428}
11429
c_hpothu225aa7c2014-10-22 17:45:13 +053011430VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11431{
11432 hdd_adapter_t *pAdapter;
11433 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11434 VOS_STATUS vosStatus;
11435
11436 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11437 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11438 {
11439 pAdapter = pAdapterNode->pAdapter;
11440 if (NULL != pAdapter)
11441 {
11442 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11443 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11444 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11445 {
11446 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11447 pAdapter->device_mode);
11448 if (VOS_STATUS_SUCCESS !=
11449 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11450 {
11451 hddLog(LOGE, FL("failed to abort ROC"));
11452 return VOS_STATUS_E_FAILURE;
11453 }
11454 }
11455 }
11456 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11457 pAdapterNode = pNext;
11458 }
11459 return VOS_STATUS_SUCCESS;
11460}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011461
Mihir Shete0be28772015-02-17 18:42:14 +053011462hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11463{
11464 hdd_adapter_t *pAdapter;
11465 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11466 hdd_cfg80211_state_t *cfgState;
11467 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11468 VOS_STATUS vosStatus;
11469
11470 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11471 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11472 {
11473 pAdapter = pAdapterNode->pAdapter;
11474 if (NULL != pAdapter)
11475 {
11476 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11477 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11478 if (pRemainChanCtx)
11479 break;
11480 }
11481 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11482 pAdapterNode = pNext;
11483 }
11484 return pRemainChanCtx;
11485}
11486
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011487/**
11488 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11489 *
11490 * @pHddCtx: HDD context within host driver
11491 * @dfsScanMode: dfsScanMode passed from ioctl
11492 *
11493 */
11494
11495VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11496 tANI_U8 dfsScanMode)
11497{
11498 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11499 hdd_adapter_t *pAdapter;
11500 VOS_STATUS vosStatus;
11501 hdd_station_ctx_t *pHddStaCtx;
11502 eHalStatus status = eHAL_STATUS_SUCCESS;
11503
11504 if(!pHddCtx)
11505 {
11506 hddLog(LOGE, FL("HDD context is Null"));
11507 return eHAL_STATUS_FAILURE;
11508 }
11509
11510 if (pHddCtx->scan_info.mScanPending)
11511 {
11512 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11513 pHddCtx->scan_info.sessionId);
11514 hdd_abort_mac_scan(pHddCtx,
11515 pHddCtx->scan_info.sessionId,
11516 eCSR_SCAN_ABORT_DEFAULT);
11517 }
11518
11519 if (!dfsScanMode)
11520 {
11521 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11522 while ((NULL != pAdapterNode) &&
11523 (VOS_STATUS_SUCCESS == vosStatus))
11524 {
11525 pAdapter = pAdapterNode->pAdapter;
11526
11527 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11528 {
11529 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11530
11531 if(!pHddStaCtx)
11532 {
11533 hddLog(LOGE, FL("HDD STA context is Null"));
11534 return eHAL_STATUS_FAILURE;
11535 }
11536
11537 /* if STA is already connected on DFS channel,
11538 disconnect immediately*/
11539 if (hdd_connIsConnected(pHddStaCtx) &&
11540 (NV_CHANNEL_DFS ==
11541 vos_nv_getChannelEnabledState(
11542 pHddStaCtx->conn_info.operationChannel)))
11543 {
11544 status = sme_RoamDisconnect(pHddCtx->hHal,
11545 pAdapter->sessionId,
11546 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11547 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11548 "sme_RoamDisconnect returned with status: %d"
11549 "for sessionid: %d"), pHddStaCtx->conn_info.
11550 operationChannel, status, pAdapter->sessionId);
11551 }
11552 }
11553
11554 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11555 &pNext);
11556 pAdapterNode = pNext;
11557 }
11558 }
11559
11560 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11561 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11562 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11563
11564 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11565 if (!HAL_STATUS_SUCCESS(status))
11566 {
11567 hddLog(LOGE,
11568 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11569 return status;
11570 }
11571
11572 return status;
11573}
11574
Nirav Shah7e3c8132015-06-22 23:51:42 +053011575static int hdd_log2_ceil(unsigned value)
11576{
11577 /* need to switch to unsigned math so that negative values
11578 * will right-shift towards 0 instead of -1
11579 */
11580 unsigned tmp = value;
11581 int log2 = -1;
11582
11583 if (value == 0)
11584 return 0;
11585
11586 while (tmp) {
11587 log2++;
11588 tmp >>= 1;
11589 }
11590 if (1U << log2 != value)
11591 log2++;
11592
11593 return log2;
11594}
11595
11596/**
11597 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11598 * @pAdapter: adapter handle
11599 *
11600 * Return: vos status
11601 */
11602VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11603{
11604 int hash_elem, log2, i;
11605
11606 spin_lock_bh( &pAdapter->sta_hash_lock);
11607 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11608 spin_unlock_bh( &pAdapter->sta_hash_lock);
11609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11610 "%s: hash already attached for session id %d",
11611 __func__, pAdapter->sessionId);
11612 return VOS_STATUS_SUCCESS;
11613 }
11614 spin_unlock_bh( &pAdapter->sta_hash_lock);
11615
11616 hash_elem = WLAN_MAX_STA_COUNT;
11617 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11618 log2 = hdd_log2_ceil(hash_elem);
11619 hash_elem = 1 << log2;
11620
11621 pAdapter->sta_id_hash.mask = hash_elem - 1;
11622 pAdapter->sta_id_hash.idx_bits = log2;
11623 pAdapter->sta_id_hash.bins =
11624 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11625 if (!pAdapter->sta_id_hash.bins) {
11626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11627 "%s: malloc failed for session %d",
11628 __func__, pAdapter->sessionId);
11629 return VOS_STATUS_E_NOMEM;
11630 }
11631
11632 for (i = 0; i < hash_elem; i++)
11633 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11634
11635 spin_lock_bh( &pAdapter->sta_hash_lock);
11636 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11637 spin_unlock_bh( &pAdapter->sta_hash_lock);
11638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11639 "%s: Station ID Hash attached for session id %d",
11640 __func__, pAdapter->sessionId);
11641
11642 return VOS_STATUS_SUCCESS;
11643}
11644
11645/**
11646 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11647 * @pAdapter: adapter handle
11648 *
11649 * Return: vos status
11650 */
11651VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11652{
11653 int hash_elem, i;
11654 v_SIZE_t size;
11655
11656 spin_lock_bh( &pAdapter->sta_hash_lock);
11657 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11658 spin_unlock_bh( &pAdapter->sta_hash_lock);
11659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11660 "%s: hash not initialized for session id %d",
11661 __func__, pAdapter->sessionId);
11662 return VOS_STATUS_SUCCESS;
11663 }
11664
11665 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11666 spin_unlock_bh( &pAdapter->sta_hash_lock);
11667
11668 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11669
11670 /* free all station info*/
11671 for (i = 0; i < hash_elem; i++) {
11672 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11673 if (size != 0) {
11674 VOS_STATUS status;
11675 hdd_staid_hash_node_t *sta_info_node = NULL;
11676 hdd_staid_hash_node_t *next_node = NULL;
11677 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11678 (hdd_list_node_t**) &sta_info_node );
11679
11680 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11681 {
11682 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11683 &sta_info_node->node);
11684 vos_mem_free(sta_info_node);
11685
11686 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11687 (hdd_list_node_t*)sta_info_node,
11688 (hdd_list_node_t**)&next_node);
11689 sta_info_node = next_node;
11690 }
11691 }
11692 }
11693
11694 vos_mem_free(pAdapter->sta_id_hash.bins);
11695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11696 "%s: Station ID Hash detached for session id %d",
11697 __func__, pAdapter->sessionId);
11698 return VOS_STATUS_SUCCESS;
11699}
11700
11701/**
11702 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11703 * @pAdapter: adapter handle
11704 * @mac_addr_in: input mac address
11705 *
11706 * Return: index derived from mac address
11707 */
11708int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11709 v_MACADDR_t *mac_addr_in)
11710{
11711 uint16 index;
11712 struct hdd_align_mac_addr_t * mac_addr =
11713 (struct hdd_align_mac_addr_t *)mac_addr_in;
11714
11715 index = mac_addr->bytes_ab ^
11716 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11717 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11718 index &= pAdapter->sta_id_hash.mask;
11719 return index;
11720}
11721
11722/**
11723 * hdd_sta_id_hash_add_entry() - add entry in hash
11724 * @pAdapter: adapter handle
11725 * @sta_id: station id
11726 * @mac_addr: mac address
11727 *
11728 * Return: vos status
11729 */
11730VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11731 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11732{
11733 uint16 index;
11734 hdd_staid_hash_node_t *sta_info_node = NULL;
11735
11736 spin_lock_bh( &pAdapter->sta_hash_lock);
11737 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11738 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shah784e6a52015-07-22 16:52:35 +053011739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053011740 "%s: hash is not initialized for session id %d",
11741 __func__, pAdapter->sessionId);
11742 return VOS_STATUS_E_FAILURE;
11743 }
11744
11745 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11746 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11747 if (!sta_info_node) {
11748 spin_unlock_bh( &pAdapter->sta_hash_lock);
11749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11750 "%s: malloc failed", __func__);
11751 return VOS_STATUS_E_NOMEM;
11752 }
11753
11754 sta_info_node->sta_id = sta_id;
11755 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11756
11757 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11758 (hdd_list_node_t*) sta_info_node );
11759 spin_unlock_bh( &pAdapter->sta_hash_lock);
11760 return VOS_STATUS_SUCCESS;
11761}
11762
11763/**
11764 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11765 * @pAdapter: adapter handle
11766 * @sta_id: station id
11767 * @mac_addr: mac address
11768 *
11769 * Return: vos status
11770 */
11771VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11772 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11773{
11774 uint16 index;
11775 VOS_STATUS status;
11776 hdd_staid_hash_node_t *sta_info_node = NULL;
11777 hdd_staid_hash_node_t *next_node = NULL;
11778
11779 spin_lock_bh( &pAdapter->sta_hash_lock);
11780 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11781 spin_unlock_bh( &pAdapter->sta_hash_lock);
11782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11783 "%s: hash is not initialized for session id %d",
11784 __func__, pAdapter->sessionId);
11785 return VOS_STATUS_E_FAILURE;
11786 }
11787
11788 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11789 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11790 (hdd_list_node_t**) &sta_info_node );
11791
11792 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11793 {
11794 if (sta_info_node->sta_id == sta_id) {
11795 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11796 &sta_info_node->node);
11797 vos_mem_free(sta_info_node);
11798 break;
11799 }
11800 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11801 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11802 sta_info_node = next_node;
11803 }
11804 spin_unlock_bh( &pAdapter->sta_hash_lock);
11805 return status;
11806}
11807
11808/**
11809 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11810 * @pAdapter: adapter handle
11811 * @mac_addr_in: mac address
11812 *
11813 * Return: station id
11814 */
11815int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11816 v_MACADDR_t *mac_addr_in)
11817{
11818 uint8 is_found = 0;
11819 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11820 uint16 index;
11821 VOS_STATUS status;
11822 hdd_staid_hash_node_t *sta_info_node = NULL;
11823 hdd_staid_hash_node_t *next_node = NULL;
11824
11825 spin_lock_bh( &pAdapter->sta_hash_lock);
11826 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11827 spin_unlock_bh( &pAdapter->sta_hash_lock);
11828 hddLog(VOS_TRACE_LEVEL_ERROR,
11829 FL("hash is not initialized for session id %d"),
11830 pAdapter->sessionId);
11831 return HDD_WLAN_INVALID_STA_ID;
11832 }
11833
11834 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11835 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11836 (hdd_list_node_t**) &sta_info_node );
11837
11838 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11839 {
11840 if (vos_mem_compare(&sta_info_node->mac_addr,
11841 mac_addr_in, sizeof(v_MACADDR_t))) {
11842 is_found = 1;
11843 sta_id = sta_info_node->sta_id;
11844 break;
11845 }
11846 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11847 (hdd_list_node_t*)sta_info_node,
11848 (hdd_list_node_t**)&next_node);
11849 sta_info_node = next_node;
11850 }
11851 spin_unlock_bh( &pAdapter->sta_hash_lock);
11852 return sta_id;
11853}
11854
Jeff Johnson295189b2012-06-20 16:38:30 -070011855//Register the module init/exit functions
11856module_init(hdd_module_init);
11857module_exit(hdd_module_exit);
11858
11859MODULE_LICENSE("Dual BSD/GPL");
11860MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11861MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11862
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011863module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11864 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011865
Jeff Johnson76052702013-04-16 13:55:05 -070011866module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011867 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011868
11869module_param(enable_dfs_chan_scan, int,
11870 S_IRUSR | S_IRGRP | S_IROTH);
11871
11872module_param(enable_11d, int,
11873 S_IRUSR | S_IRGRP | S_IROTH);
11874
11875module_param(country_code, charp,
11876 S_IRUSR | S_IRGRP | S_IROTH);