blob: 94672052400b81e2712715bcd921cecfb866070e [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}
2195
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002196static int hdd_driver_command(hdd_adapter_t *pAdapter,
2197 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002198{
Jeff Johnson295189b2012-06-20 16:38:30 -07002199 hdd_priv_data_t priv_data;
2200 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302201 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2202 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002203 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302204 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302205
2206 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002207 /*
2208 * Note that valid pointers are provided by caller
2209 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002210
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002211 /* copy to local struct to avoid numerous changes to legacy code */
2212 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002213
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002214 if (priv_data.total_len <= 0 ||
2215 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002216 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002217 hddLog(VOS_TRACE_LEVEL_WARN,
2218 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2219 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002220 ret = -EINVAL;
2221 goto exit;
2222 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302223 status = wlan_hdd_validate_context(pHddCtx);
2224 if (0 != status)
2225 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302226 ret = -EINVAL;
2227 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302228 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002229 /* Allocate +1 for '\0' */
2230 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 if (!command)
2232 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002233 hddLog(VOS_TRACE_LEVEL_ERROR,
2234 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002235 ret = -ENOMEM;
2236 goto exit;
2237 }
2238
2239 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2240 {
2241 ret = -EFAULT;
2242 goto exit;
2243 }
2244
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002245 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002246 command[priv_data.total_len] = '\0';
2247
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002248 /* at one time the following block of code was conditional. braces
2249 * have been retained to avoid re-indenting the legacy code
2250 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002251 {
2252 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2253
2254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002255 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002256
2257 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2258 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302259 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2260 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2261 pAdapter->sessionId, (unsigned)
2262 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2263 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2264 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2265 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002266 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2267 sizeof(tSirMacAddr)))
2268 {
2269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002270 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002271 ret = -EFAULT;
2272 }
2273 }
Amar Singhal0974e402013-02-12 14:27:46 -08002274 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002275 {
Amar Singhal0974e402013-02-12 14:27:46 -08002276 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002277
Jeff Johnson295189b2012-06-20 16:38:30 -07002278 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002279
2280 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002281 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002283 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07002284 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002285 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302286 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302287 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002288 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002289 }
Kiet Lamf040f472013-11-20 21:15:23 +05302290 else if(strncmp(command, "SETWMMPS", 8) == 0)
2291 {
2292 tANI_U8 *ptr = command;
2293 ret = hdd_wmmps_helper(pAdapter, ptr);
2294 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302295
2296 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2297 {
2298 tANI_U8 *ptr = command;
2299 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2300 }
2301
Jeff Johnson32d95a32012-09-10 13:15:23 -07002302 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2303 {
2304 char *country_code;
2305
2306 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002307
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002308 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002309 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002310#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302311 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002312#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002313 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2314 (void *)(tSmeChangeCountryCallback)
2315 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302316 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002317 if (eHAL_STATUS_SUCCESS == ret)
2318 {
2319 ret = wait_for_completion_interruptible_timeout(
2320 &pAdapter->change_country_code,
2321 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2322 if (0 >= ret)
2323 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302325 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002326 }
2327 }
2328 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002329 {
2330 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002331 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002332 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002333 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002334
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002335 }
2336 /*
2337 command should be a string having format
2338 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2339 */
Amar Singhal0974e402013-02-12 14:27:46 -08002340 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002341 {
Amar Singhal0974e402013-02-12 14:27:46 -08002342 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002343
2344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002345 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002346
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002347 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002348 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002349 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2350 {
2351 int suspend = 0;
2352 tANI_U8 *ptr = (tANI_U8*)command + 15;
2353
2354 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302355 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2356 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2357 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002358 hdd_set_wlan_suspend_mode(suspend);
2359 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002360#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2361 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2362 {
2363 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002364 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002365 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2366 eHalStatus status = eHAL_STATUS_SUCCESS;
2367
2368 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2369 value = value + 15;
2370
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002371 /* Convert the value from ascii to integer */
2372 ret = kstrtos8(value, 10, &rssi);
2373 if (ret < 0)
2374 {
2375 /* If the input value is greater than max value of datatype, then also
2376 kstrtou8 fails */
2377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2378 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002379 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002380 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2381 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2382 ret = -EINVAL;
2383 goto exit;
2384 }
2385
Srinivas Girigowdade697412013-02-14 16:31:48 -08002386 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002387
Srinivas Girigowdade697412013-02-14 16:31:48 -08002388 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2389 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2390 {
2391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2392 "Neighbor lookup threshold value %d is out of range"
2393 " (Min: %d Max: %d)", lookUpThreshold,
2394 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2395 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2396 ret = -EINVAL;
2397 goto exit;
2398 }
2399
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302400 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2401 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2402 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2404 "%s: Received Command to Set Roam trigger"
2405 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2406
2407 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2408 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2409 if (eHAL_STATUS_SUCCESS != status)
2410 {
2411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2412 "%s: Failed to set roam trigger, try again", __func__);
2413 ret = -EPERM;
2414 goto exit;
2415 }
2416
2417 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302418 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002419 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2420 }
2421 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2422 {
2423 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2424 int rssi = (-1) * lookUpThreshold;
2425 char extra[32];
2426 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302427 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2428 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2429 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002430 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002431 if (copy_to_user(priv_data.buf, &extra, len + 1))
2432 {
2433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2434 "%s: failed to copy data to user buffer", __func__);
2435 ret = -EFAULT;
2436 goto exit;
2437 }
2438 }
2439 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2440 {
2441 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002442 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002443 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002444
Srinivas Girigowdade697412013-02-14 16:31:48 -08002445 /* input refresh period is in terms of seconds */
2446 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2447 value = value + 18;
2448 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002449 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002450 if (ret < 0)
2451 {
2452 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002453 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002455 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002456 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002457 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2458 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002459 ret = -EINVAL;
2460 goto exit;
2461 }
2462
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002463 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2464 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002465 {
2466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002467 "Roam scan period value %d is out of range"
2468 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002469 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2470 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002471 ret = -EINVAL;
2472 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302473 }
2474 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2475 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2476 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002477 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478
2479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2480 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002481 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002482
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002483 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2484 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002485 }
2486 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2487 {
2488 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2489 char extra[32];
2490 tANI_U8 len = 0;
2491
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2493 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2494 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002495 len = scnprintf(extra, sizeof(extra), "%s %d",
2496 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002497 /* Returned value is in units of seconds */
2498 if (copy_to_user(priv_data.buf, &extra, len + 1))
2499 {
2500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2501 "%s: failed to copy data to user buffer", __func__);
2502 ret = -EFAULT;
2503 goto exit;
2504 }
2505 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002506 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2507 {
2508 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002509 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002510 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002511
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002512 /* input refresh period is in terms of seconds */
2513 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2514 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002515
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002516 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002517 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002518 if (ret < 0)
2519 {
2520 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002521 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002523 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002524 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002525 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2526 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2527 ret = -EINVAL;
2528 goto exit;
2529 }
2530
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002531 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2532 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2533 {
2534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2535 "Neighbor scan results refresh period value %d is out of range"
2536 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2537 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2538 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2539 ret = -EINVAL;
2540 goto exit;
2541 }
2542 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2543
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2545 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002546 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002547
2548 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2549 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2550 }
2551 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2552 {
2553 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2554 char extra[32];
2555 tANI_U8 len = 0;
2556
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002557 len = scnprintf(extra, sizeof(extra), "%s %d",
2558 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002559 /* Returned value is in units of seconds */
2560 if (copy_to_user(priv_data.buf, &extra, len + 1))
2561 {
2562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2563 "%s: failed to copy data to user buffer", __func__);
2564 ret = -EFAULT;
2565 goto exit;
2566 }
2567 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002568#ifdef FEATURE_WLAN_LFR
2569 /* SETROAMMODE */
2570 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2571 {
2572 tANI_U8 *value = command;
2573 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2574
2575 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2576 value = value + SIZE_OF_SETROAMMODE + 1;
2577
2578 /* Convert the value from ascii to integer */
2579 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2580 if (ret < 0)
2581 {
2582 /* If the input value is greater than max value of datatype, then also
2583 kstrtou8 fails */
2584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2585 "%s: kstrtou8 failed range [%d - %d]", __func__,
2586 CFG_LFR_FEATURE_ENABLED_MIN,
2587 CFG_LFR_FEATURE_ENABLED_MAX);
2588 ret = -EINVAL;
2589 goto exit;
2590 }
2591 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2592 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2593 {
2594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2595 "Roam Mode value %d is out of range"
2596 " (Min: %d Max: %d)", roamMode,
2597 CFG_LFR_FEATURE_ENABLED_MIN,
2598 CFG_LFR_FEATURE_ENABLED_MAX);
2599 ret = -EINVAL;
2600 goto exit;
2601 }
2602
2603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2604 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2605 /*
2606 * Note that
2607 * SETROAMMODE 0 is to enable LFR while
2608 * SETROAMMODE 1 is to disable LFR, but
2609 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2610 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2611 */
2612 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2613 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2614 else
2615 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2616
2617 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2618 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2619 }
2620 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302621 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002622 {
2623 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2624 char extra[32];
2625 tANI_U8 len = 0;
2626
2627 /*
2628 * roamMode value shall be inverted because the sementics is different.
2629 */
2630 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2631 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2632 else
2633 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2634
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002635 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002636 if (copy_to_user(priv_data.buf, &extra, len + 1))
2637 {
2638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2639 "%s: failed to copy data to user buffer", __func__);
2640 ret = -EFAULT;
2641 goto exit;
2642 }
2643 }
2644#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002645#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002646#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002647 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2648 {
2649 tANI_U8 *value = command;
2650 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2651
2652 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2653 value = value + 13;
2654 /* Convert the value from ascii to integer */
2655 ret = kstrtou8(value, 10, &roamRssiDiff);
2656 if (ret < 0)
2657 {
2658 /* If the input value is greater than max value of datatype, then also
2659 kstrtou8 fails */
2660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2661 "%s: kstrtou8 failed range [%d - %d]", __func__,
2662 CFG_ROAM_RSSI_DIFF_MIN,
2663 CFG_ROAM_RSSI_DIFF_MAX);
2664 ret = -EINVAL;
2665 goto exit;
2666 }
2667
2668 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2669 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2670 {
2671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2672 "Roam rssi diff value %d is out of range"
2673 " (Min: %d Max: %d)", roamRssiDiff,
2674 CFG_ROAM_RSSI_DIFF_MIN,
2675 CFG_ROAM_RSSI_DIFF_MAX);
2676 ret = -EINVAL;
2677 goto exit;
2678 }
2679
2680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2681 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2682
2683 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2684 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2685 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302686 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002687 {
2688 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2689 char extra[32];
2690 tANI_U8 len = 0;
2691
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302692 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2693 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2694 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002695 len = scnprintf(extra, sizeof(extra), "%s %d",
2696 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002697 if (copy_to_user(priv_data.buf, &extra, len + 1))
2698 {
2699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2700 "%s: failed to copy data to user buffer", __func__);
2701 ret = -EFAULT;
2702 goto exit;
2703 }
2704 }
2705#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002706#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002707 else if (strncmp(command, "GETBAND", 7) == 0)
2708 {
2709 int band = -1;
2710 char extra[32];
2711 tANI_U8 len = 0;
2712 hdd_getBand_helper(pHddCtx, &band);
2713
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302714 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2715 TRACE_CODE_HDD_GETBAND_IOCTL,
2716 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002717 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002718 if (copy_to_user(priv_data.buf, &extra, len + 1))
2719 {
2720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2721 "%s: failed to copy data to user buffer", __func__);
2722 ret = -EFAULT;
2723 goto exit;
2724 }
2725 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002726 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2727 {
2728 tANI_U8 *value = command;
2729 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2730 tANI_U8 numChannels = 0;
2731 eHalStatus status = eHAL_STATUS_SUCCESS;
2732
2733 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2734 if (eHAL_STATUS_SUCCESS != status)
2735 {
2736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2737 "%s: Failed to parse channel list information", __func__);
2738 ret = -EINVAL;
2739 goto exit;
2740 }
2741
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302742 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2743 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2744 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002745 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2746 {
2747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2748 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2749 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2750 ret = -EINVAL;
2751 goto exit;
2752 }
2753 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2754 numChannels);
2755 if (eHAL_STATUS_SUCCESS != status)
2756 {
2757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2758 "%s: Failed to update channel list information", __func__);
2759 ret = -EINVAL;
2760 goto exit;
2761 }
2762 }
2763 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2764 {
2765 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2766 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002767 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002768 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002769 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002770
2771 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2772 ChannelList, &numChannels ))
2773 {
2774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2775 "%s: failed to get roam scan channel list", __func__);
2776 ret = -EFAULT;
2777 goto exit;
2778 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302779 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2780 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2781 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002782 /* output channel list is of the format
2783 [Number of roam scan channels][Channel1][Channel2]... */
2784 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002785 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002786 for (j = 0; (j < numChannels); j++)
2787 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002788 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2789 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002790 }
2791
2792 if (copy_to_user(priv_data.buf, &extra, len + 1))
2793 {
2794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2795 "%s: failed to copy data to user buffer", __func__);
2796 ret = -EFAULT;
2797 goto exit;
2798 }
2799 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002800 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2801 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002802 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002803 char extra[32];
2804 tANI_U8 len = 0;
2805
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002806 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002807 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002808 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002809 hdd_is_okc_mode_enabled(pHddCtx) &&
2810 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2811 {
2812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002813 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002814 " hence this operation is not permitted!", __func__);
2815 ret = -EPERM;
2816 goto exit;
2817 }
2818
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002819 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002820 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002821 if (copy_to_user(priv_data.buf, &extra, len + 1))
2822 {
2823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2824 "%s: failed to copy data to user buffer", __func__);
2825 ret = -EFAULT;
2826 goto exit;
2827 }
2828 }
2829 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2830 {
2831 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2832 char extra[32];
2833 tANI_U8 len = 0;
2834
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002835 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002836 then this operation is not permitted (return FAILURE) */
2837 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002838 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002839 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2840 {
2841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002842 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002843 " hence this operation is not permitted!", __func__);
2844 ret = -EPERM;
2845 goto exit;
2846 }
2847
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002848 len = scnprintf(extra, sizeof(extra), "%s %d",
2849 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002850 if (copy_to_user(priv_data.buf, &extra, len + 1))
2851 {
2852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2853 "%s: failed to copy data to user buffer", __func__);
2854 ret = -EFAULT;
2855 goto exit;
2856 }
2857 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002858 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002859 {
2860 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2861 char extra[32];
2862 tANI_U8 len = 0;
2863
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002864 len = scnprintf(extra, sizeof(extra), "%s %d",
2865 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002866 if (copy_to_user(priv_data.buf, &extra, len + 1))
2867 {
2868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2869 "%s: failed to copy data to user buffer", __func__);
2870 ret = -EFAULT;
2871 goto exit;
2872 }
2873 }
2874 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2875 {
2876 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2877 char extra[32];
2878 tANI_U8 len = 0;
2879
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002880 len = scnprintf(extra, sizeof(extra), "%s %d",
2881 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002882 if (copy_to_user(priv_data.buf, &extra, len + 1))
2883 {
2884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2885 "%s: failed to copy data to user buffer", __func__);
2886 ret = -EFAULT;
2887 goto exit;
2888 }
2889 }
2890 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2891 {
2892 tANI_U8 *value = command;
2893 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2894
2895 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2896 value = value + 26;
2897 /* Convert the value from ascii to integer */
2898 ret = kstrtou8(value, 10, &minTime);
2899 if (ret < 0)
2900 {
2901 /* If the input value is greater than max value of datatype, then also
2902 kstrtou8 fails */
2903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2904 "%s: kstrtou8 failed range [%d - %d]", __func__,
2905 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2906 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2907 ret = -EINVAL;
2908 goto exit;
2909 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002910 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2911 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2912 {
2913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2914 "scan min channel time value %d is out of range"
2915 " (Min: %d Max: %d)", minTime,
2916 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2917 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2918 ret = -EINVAL;
2919 goto exit;
2920 }
2921
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302922 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2923 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2924 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2926 "%s: Received Command to change channel min time = %d", __func__, minTime);
2927
2928 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2929 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2930 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002931 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2932 {
2933 tANI_U8 *value = command;
2934 tANI_U8 channel = 0;
2935 tANI_U8 dwellTime = 0;
2936 tANI_U8 bufLen = 0;
2937 tANI_U8 *buf = NULL;
2938 tSirMacAddr targetApBssid;
2939 eHalStatus status = eHAL_STATUS_SUCCESS;
2940 struct ieee80211_channel chan;
2941 tANI_U8 finalLen = 0;
2942 tANI_U8 *finalBuf = NULL;
2943 tANI_U8 temp = 0;
2944 u64 cookie;
2945 hdd_station_ctx_t *pHddStaCtx = NULL;
2946 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2947
2948 /* if not associated, no need to send action frame */
2949 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2950 {
2951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2952 ret = -EINVAL;
2953 goto exit;
2954 }
2955
2956 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2957 &dwellTime, &buf, &bufLen);
2958 if (eHAL_STATUS_SUCCESS != status)
2959 {
2960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2961 "%s: Failed to parse send action frame data", __func__);
2962 ret = -EINVAL;
2963 goto exit;
2964 }
2965
2966 /* if the target bssid is different from currently associated AP,
2967 then no need to send action frame */
2968 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2969 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2970 {
2971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2972 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002973 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002974 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002975 goto exit;
2976 }
2977
2978 /* if the channel number is different from operating channel then
2979 no need to send action frame */
2980 if (channel != pHddStaCtx->conn_info.operationChannel)
2981 {
2982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2983 "%s: channel(%d) is different from operating channel(%d)",
2984 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2985 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002986 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002987 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002988 goto exit;
2989 }
2990 chan.center_freq = sme_ChnToFreq(channel);
2991
2992 finalLen = bufLen + 24;
2993 finalBuf = vos_mem_malloc(finalLen);
2994 if (NULL == finalBuf)
2995 {
2996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2997 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002998 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002999 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003000 goto exit;
3001 }
3002 vos_mem_zero(finalBuf, finalLen);
3003
3004 /* Fill subtype */
3005 temp = SIR_MAC_MGMT_ACTION << 4;
3006 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3007
3008 /* Fill type */
3009 temp = SIR_MAC_MGMT_FRAME;
3010 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3011
3012 /* Fill destination address (bssid of the AP) */
3013 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3014
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003015 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003016 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3017
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003018 /* Fill BSSID (AP mac address) */
3019 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003020
3021 /* Fill received buffer from 24th address */
3022 vos_mem_copy(finalBuf + 24, buf, bufLen);
3023
Jeff Johnson11c33152013-04-16 17:52:40 -07003024 /* done with the parsed buffer */
3025 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003026 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003027
DARAM SUDHA39eede62014-02-12 11:16:40 +05303028 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003029#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3030 &(pAdapter->wdev),
3031#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003032 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003033#endif
3034 &chan, 0,
3035#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3036 NL80211_CHAN_HT20, 1,
3037#endif
3038 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003039 1, &cookie );
3040 vos_mem_free(finalBuf);
3041 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003042 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3043 {
3044 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3045 char extra[32];
3046 tANI_U8 len = 0;
3047
3048 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003049 len = scnprintf(extra, sizeof(extra), "%s %d",
3050 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303051 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3052 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3053 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003054 if (copy_to_user(priv_data.buf, &extra, len + 1))
3055 {
3056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3057 "%s: failed to copy data to user buffer", __func__);
3058 ret = -EFAULT;
3059 goto exit;
3060 }
3061 }
3062 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3063 {
3064 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003065 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003066
3067 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3068 value = value + 19;
3069 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003070 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003071 if (ret < 0)
3072 {
3073 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003074 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003076 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003077 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3078 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3079 ret = -EINVAL;
3080 goto exit;
3081 }
3082
3083 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3084 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3085 {
3086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3087 "lfr mode value %d is out of range"
3088 " (Min: %d Max: %d)", maxTime,
3089 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3090 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3091 ret = -EINVAL;
3092 goto exit;
3093 }
3094
3095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3096 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3097
3098 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3099 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3100 }
3101 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3102 {
3103 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3104 char extra[32];
3105 tANI_U8 len = 0;
3106
3107 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003108 len = scnprintf(extra, sizeof(extra), "%s %d",
3109 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003110 if (copy_to_user(priv_data.buf, &extra, len + 1))
3111 {
3112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3113 "%s: failed to copy data to user buffer", __func__);
3114 ret = -EFAULT;
3115 goto exit;
3116 }
3117 }
3118 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3119 {
3120 tANI_U8 *value = command;
3121 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3122
3123 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3124 value = value + 16;
3125 /* Convert the value from ascii to integer */
3126 ret = kstrtou16(value, 10, &val);
3127 if (ret < 0)
3128 {
3129 /* If the input value is greater than max value of datatype, then also
3130 kstrtou16 fails */
3131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3132 "%s: kstrtou16 failed range [%d - %d]", __func__,
3133 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3134 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3135 ret = -EINVAL;
3136 goto exit;
3137 }
3138
3139 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3140 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3141 {
3142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3143 "scan home time value %d is out of range"
3144 " (Min: %d Max: %d)", val,
3145 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3146 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3147 ret = -EINVAL;
3148 goto exit;
3149 }
3150
3151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3152 "%s: Received Command to change scan home time = %d", __func__, val);
3153
3154 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3155 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3156 }
3157 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3158 {
3159 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3160 char extra[32];
3161 tANI_U8 len = 0;
3162
3163 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003164 len = scnprintf(extra, sizeof(extra), "%s %d",
3165 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003166 if (copy_to_user(priv_data.buf, &extra, len + 1))
3167 {
3168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3169 "%s: failed to copy data to user buffer", __func__);
3170 ret = -EFAULT;
3171 goto exit;
3172 }
3173 }
3174 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3175 {
3176 tANI_U8 *value = command;
3177 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3178
3179 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3180 value = value + 17;
3181 /* Convert the value from ascii to integer */
3182 ret = kstrtou8(value, 10, &val);
3183 if (ret < 0)
3184 {
3185 /* If the input value is greater than max value of datatype, then also
3186 kstrtou8 fails */
3187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3188 "%s: kstrtou8 failed range [%d - %d]", __func__,
3189 CFG_ROAM_INTRA_BAND_MIN,
3190 CFG_ROAM_INTRA_BAND_MAX);
3191 ret = -EINVAL;
3192 goto exit;
3193 }
3194
3195 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3196 (val > CFG_ROAM_INTRA_BAND_MAX))
3197 {
3198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3199 "intra band mode value %d is out of range"
3200 " (Min: %d Max: %d)", val,
3201 CFG_ROAM_INTRA_BAND_MIN,
3202 CFG_ROAM_INTRA_BAND_MAX);
3203 ret = -EINVAL;
3204 goto exit;
3205 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3207 "%s: Received Command to change intra band = %d", __func__, val);
3208
3209 pHddCtx->cfg_ini->nRoamIntraBand = val;
3210 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3211 }
3212 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3213 {
3214 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3215 char extra[32];
3216 tANI_U8 len = 0;
3217
3218 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003219 len = scnprintf(extra, sizeof(extra), "%s %d",
3220 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003221 if (copy_to_user(priv_data.buf, &extra, len + 1))
3222 {
3223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3224 "%s: failed to copy data to user buffer", __func__);
3225 ret = -EFAULT;
3226 goto exit;
3227 }
3228 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003229 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3230 {
3231 tANI_U8 *value = command;
3232 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3233
3234 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3235 value = value + 15;
3236 /* Convert the value from ascii to integer */
3237 ret = kstrtou8(value, 10, &nProbes);
3238 if (ret < 0)
3239 {
3240 /* If the input value is greater than max value of datatype, then also
3241 kstrtou8 fails */
3242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3243 "%s: kstrtou8 failed range [%d - %d]", __func__,
3244 CFG_ROAM_SCAN_N_PROBES_MIN,
3245 CFG_ROAM_SCAN_N_PROBES_MAX);
3246 ret = -EINVAL;
3247 goto exit;
3248 }
3249
3250 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3251 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3252 {
3253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3254 "NProbes value %d is out of range"
3255 " (Min: %d Max: %d)", nProbes,
3256 CFG_ROAM_SCAN_N_PROBES_MIN,
3257 CFG_ROAM_SCAN_N_PROBES_MAX);
3258 ret = -EINVAL;
3259 goto exit;
3260 }
3261
3262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3263 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3264
3265 pHddCtx->cfg_ini->nProbes = nProbes;
3266 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3267 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303268 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003269 {
3270 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3271 char extra[32];
3272 tANI_U8 len = 0;
3273
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003274 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003275 if (copy_to_user(priv_data.buf, &extra, len + 1))
3276 {
3277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3278 "%s: failed to copy data to user buffer", __func__);
3279 ret = -EFAULT;
3280 goto exit;
3281 }
3282 }
3283 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3284 {
3285 tANI_U8 *value = command;
3286 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3287
3288 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3289 /* input value is in units of msec */
3290 value = value + 20;
3291 /* Convert the value from ascii to integer */
3292 ret = kstrtou16(value, 10, &homeAwayTime);
3293 if (ret < 0)
3294 {
3295 /* If the input value is greater than max value of datatype, then also
3296 kstrtou8 fails */
3297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3298 "%s: kstrtou8 failed range [%d - %d]", __func__,
3299 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3300 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3301 ret = -EINVAL;
3302 goto exit;
3303 }
3304
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003305 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3306 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3307 {
3308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3309 "homeAwayTime value %d is out of range"
3310 " (Min: %d Max: %d)", homeAwayTime,
3311 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3312 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3313 ret = -EINVAL;
3314 goto exit;
3315 }
3316
3317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3318 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003319 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3320 {
3321 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3322 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3323 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003324 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303325 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003326 {
3327 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3328 char extra[32];
3329 tANI_U8 len = 0;
3330
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003331 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003332 if (copy_to_user(priv_data.buf, &extra, len + 1))
3333 {
3334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3335 "%s: failed to copy data to user buffer", __func__);
3336 ret = -EFAULT;
3337 goto exit;
3338 }
3339 }
3340 else if (strncmp(command, "REASSOC", 7) == 0)
3341 {
3342 tANI_U8 *value = command;
3343 tANI_U8 channel = 0;
3344 tSirMacAddr targetApBssid;
3345 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003346#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3347 tCsrHandoffRequest handoffInfo;
3348#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003349 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003350 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3351
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003352 /* if not associated, no need to proceed with reassoc */
3353 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3354 {
3355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3356 ret = -EINVAL;
3357 goto exit;
3358 }
3359
3360 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3361 if (eHAL_STATUS_SUCCESS != status)
3362 {
3363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3364 "%s: Failed to parse reassoc command data", __func__);
3365 ret = -EINVAL;
3366 goto exit;
3367 }
3368
3369 /* if the target bssid is same as currently associated AP,
3370 then no need to proceed with reassoc */
3371 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3372 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3373 {
3374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3375 ret = -EINVAL;
3376 goto exit;
3377 }
3378
3379 /* Check channel number is a valid channel number */
3380 if(VOS_STATUS_SUCCESS !=
3381 wlan_hdd_validate_operation_channel(pAdapter, channel))
3382 {
3383 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003384 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003385 return -EINVAL;
3386 }
3387
3388 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003389#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3390 handoffInfo.channel = channel;
3391 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3392 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3393#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003394 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003395 else if (strncmp(command, "SETWESMODE", 10) == 0)
3396 {
3397 tANI_U8 *value = command;
3398 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3399
3400 /* Move pointer to ahead of SETWESMODE<delimiter> */
3401 value = value + 11;
3402 /* Convert the value from ascii to integer */
3403 ret = kstrtou8(value, 10, &wesMode);
3404 if (ret < 0)
3405 {
3406 /* If the input value is greater than max value of datatype, then also
3407 kstrtou8 fails */
3408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3409 "%s: kstrtou8 failed range [%d - %d]", __func__,
3410 CFG_ENABLE_WES_MODE_NAME_MIN,
3411 CFG_ENABLE_WES_MODE_NAME_MAX);
3412 ret = -EINVAL;
3413 goto exit;
3414 }
3415
3416 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3417 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3418 {
3419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3420 "WES Mode value %d is out of range"
3421 " (Min: %d Max: %d)", wesMode,
3422 CFG_ENABLE_WES_MODE_NAME_MIN,
3423 CFG_ENABLE_WES_MODE_NAME_MAX);
3424 ret = -EINVAL;
3425 goto exit;
3426 }
3427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3428 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3429
3430 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3431 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3432 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303433 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003434 {
3435 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3436 char extra[32];
3437 tANI_U8 len = 0;
3438
Arif Hussain826d9412013-11-12 16:44:54 -08003439 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003440 if (copy_to_user(priv_data.buf, &extra, len + 1))
3441 {
3442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3443 "%s: failed to copy data to user buffer", __func__);
3444 ret = -EFAULT;
3445 goto exit;
3446 }
3447 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003448#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003449#ifdef FEATURE_WLAN_LFR
3450 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3451 {
3452 tANI_U8 *value = command;
3453 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3454
3455 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3456 value = value + 12;
3457 /* Convert the value from ascii to integer */
3458 ret = kstrtou8(value, 10, &lfrMode);
3459 if (ret < 0)
3460 {
3461 /* If the input value is greater than max value of datatype, then also
3462 kstrtou8 fails */
3463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3464 "%s: kstrtou8 failed range [%d - %d]", __func__,
3465 CFG_LFR_FEATURE_ENABLED_MIN,
3466 CFG_LFR_FEATURE_ENABLED_MAX);
3467 ret = -EINVAL;
3468 goto exit;
3469 }
3470
3471 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3472 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3473 {
3474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3475 "lfr mode value %d is out of range"
3476 " (Min: %d Max: %d)", lfrMode,
3477 CFG_LFR_FEATURE_ENABLED_MIN,
3478 CFG_LFR_FEATURE_ENABLED_MAX);
3479 ret = -EINVAL;
3480 goto exit;
3481 }
3482
3483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3484 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3485
3486 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3487 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3488 }
3489#endif
3490#ifdef WLAN_FEATURE_VOWIFI_11R
3491 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3492 {
3493 tANI_U8 *value = command;
3494 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3495
3496 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3497 value = value + 18;
3498 /* Convert the value from ascii to integer */
3499 ret = kstrtou8(value, 10, &ft);
3500 if (ret < 0)
3501 {
3502 /* If the input value is greater than max value of datatype, then also
3503 kstrtou8 fails */
3504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3505 "%s: kstrtou8 failed range [%d - %d]", __func__,
3506 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3507 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3508 ret = -EINVAL;
3509 goto exit;
3510 }
3511
3512 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3513 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3514 {
3515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3516 "ft mode value %d is out of range"
3517 " (Min: %d Max: %d)", ft,
3518 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3519 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3520 ret = -EINVAL;
3521 goto exit;
3522 }
3523
3524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3525 "%s: Received Command to change ft mode = %d", __func__, ft);
3526
3527 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3528 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3529 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303530 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3531 {
3532 tANI_U8 *value = command;
3533 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303534
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303535 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3536 value = value + 15;
3537 /* Convert the value from ascii to integer */
3538 ret = kstrtou8(value, 10, &dfsScanMode);
3539 if (ret < 0)
3540 {
3541 /* If the input value is greater than max value of
3542 datatype, then also kstrtou8 fails
3543 */
3544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3545 "%s: kstrtou8 failed range [%d - %d]", __func__,
3546 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3547 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3548 ret = -EINVAL;
3549 goto exit;
3550 }
3551
3552 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3553 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3554 {
3555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3556 "dfsScanMode value %d is out of range"
3557 " (Min: %d Max: %d)", dfsScanMode,
3558 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3559 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3560 ret = -EINVAL;
3561 goto exit;
3562 }
3563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3564 "%s: Received Command to Set DFS Scan Mode = %d",
3565 __func__, dfsScanMode);
3566
3567 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3568 }
3569 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3570 {
3571 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3572 char extra[32];
3573 tANI_U8 len = 0;
3574
3575 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3576 if (copy_to_user(priv_data.buf, &extra, len + 1))
3577 {
3578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3579 "%s: failed to copy data to user buffer", __func__);
3580 ret = -EFAULT;
3581 goto exit;
3582 }
3583 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303584 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3585 {
3586 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303587 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303588 tSirMacAddr targetApBssid;
3589 tANI_U8 trigger = 0;
3590 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303591 tHalHandle hHal;
3592 v_U32_t roamId = 0;
3593 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303594 hdd_station_ctx_t *pHddStaCtx = NULL;
3595 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303596 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303597
3598 /* if not associated, no need to proceed with reassoc */
3599 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3600 {
3601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3602 ret = -EINVAL;
3603 goto exit;
3604 }
3605
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303606 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303607 if (eHAL_STATUS_SUCCESS != status)
3608 {
3609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3610 "%s: Failed to parse reassoc command data", __func__);
3611 ret = -EINVAL;
3612 goto exit;
3613 }
3614
3615 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303616 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303617 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3618 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3619 {
3620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3621 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3622 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303623 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3624 &modProfileFields);
3625 sme_RoamReassoc(hHal, pAdapter->sessionId,
3626 NULL, modProfileFields, &roamId, 1);
3627 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303628 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303629
3630 /* Check channel number is a valid channel number */
3631 if(VOS_STATUS_SUCCESS !=
3632 wlan_hdd_validate_operation_channel(pAdapter, channel))
3633 {
3634 hddLog(VOS_TRACE_LEVEL_ERROR,
3635 "%s: Invalid Channel [%d]", __func__, channel);
3636 return -EINVAL;
3637 }
3638
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303639 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303640
3641 /* Proceed with scan/roam */
3642 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3643 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303644 (tSmeFastRoamTrigger)(trigger),
3645 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303646 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003647#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003648#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003649 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3650 {
3651 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003652 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003653
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003654 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003655 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003656 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003657 hdd_is_okc_mode_enabled(pHddCtx) &&
3658 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3659 {
3660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003661 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003662 " hence this operation is not permitted!", __func__);
3663 ret = -EPERM;
3664 goto exit;
3665 }
3666
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003667 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3668 value = value + 11;
3669 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003670 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003671 if (ret < 0)
3672 {
3673 /* If the input value is greater than max value of datatype, then also
3674 kstrtou8 fails */
3675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3676 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003677 CFG_ESE_FEATURE_ENABLED_MIN,
3678 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003679 ret = -EINVAL;
3680 goto exit;
3681 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003682 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3683 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003684 {
3685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003686 "Ese mode value %d is out of range"
3687 " (Min: %d Max: %d)", eseMode,
3688 CFG_ESE_FEATURE_ENABLED_MIN,
3689 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003690 ret = -EINVAL;
3691 goto exit;
3692 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003694 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003695
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003696 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3697 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003698 }
3699#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003700 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3701 {
3702 tANI_U8 *value = command;
3703 tANI_BOOLEAN roamScanControl = 0;
3704
3705 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3706 value = value + 19;
3707 /* Convert the value from ascii to integer */
3708 ret = kstrtou8(value, 10, &roamScanControl);
3709 if (ret < 0)
3710 {
3711 /* If the input value is greater than max value of datatype, then also
3712 kstrtou8 fails */
3713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3714 "%s: kstrtou8 failed ", __func__);
3715 ret = -EINVAL;
3716 goto exit;
3717 }
3718
3719 if (0 != roamScanControl)
3720 {
3721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3722 "roam scan control invalid value = %d",
3723 roamScanControl);
3724 ret = -EINVAL;
3725 goto exit;
3726 }
3727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3728 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3729
3730 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3731 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003732#ifdef FEATURE_WLAN_OKC
3733 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3734 {
3735 tANI_U8 *value = command;
3736 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3737
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003738 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003739 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003740 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003741 hdd_is_okc_mode_enabled(pHddCtx) &&
3742 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3743 {
3744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003745 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003746 " hence this operation is not permitted!", __func__);
3747 ret = -EPERM;
3748 goto exit;
3749 }
3750
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003751 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3752 value = value + 11;
3753 /* Convert the value from ascii to integer */
3754 ret = kstrtou8(value, 10, &okcMode);
3755 if (ret < 0)
3756 {
3757 /* If the input value is greater than max value of datatype, then also
3758 kstrtou8 fails */
3759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3760 "%s: kstrtou8 failed range [%d - %d]", __func__,
3761 CFG_OKC_FEATURE_ENABLED_MIN,
3762 CFG_OKC_FEATURE_ENABLED_MAX);
3763 ret = -EINVAL;
3764 goto exit;
3765 }
3766
3767 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3768 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3769 {
3770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3771 "Okc mode value %d is out of range"
3772 " (Min: %d Max: %d)", okcMode,
3773 CFG_OKC_FEATURE_ENABLED_MIN,
3774 CFG_OKC_FEATURE_ENABLED_MAX);
3775 ret = -EINVAL;
3776 goto exit;
3777 }
3778
3779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3780 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3781
3782 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3783 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003784#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303785 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003786 {
3787 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3788 char extra[32];
3789 tANI_U8 len = 0;
3790
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003791 len = scnprintf(extra, sizeof(extra), "%s %d",
3792 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003793 if (copy_to_user(priv_data.buf, &extra, len + 1))
3794 {
3795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3796 "%s: failed to copy data to user buffer", __func__);
3797 ret = -EFAULT;
3798 goto exit;
3799 }
3800 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303801#ifdef WLAN_FEATURE_PACKET_FILTERING
3802 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3803 {
3804 tANI_U8 filterType = 0;
3805 tANI_U8 *value = command;
3806
3807 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3808 value = value + 22;
3809
3810 /* Convert the value from ascii to integer */
3811 ret = kstrtou8(value, 10, &filterType);
3812 if (ret < 0)
3813 {
3814 /* If the input value is greater than max value of datatype,
3815 * then also kstrtou8 fails
3816 */
3817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3818 "%s: kstrtou8 failed range ", __func__);
3819 ret = -EINVAL;
3820 goto exit;
3821 }
3822
3823 if (filterType != 0 && filterType != 1)
3824 {
3825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3826 "%s: Accepted Values are 0 and 1 ", __func__);
3827 ret = -EINVAL;
3828 goto exit;
3829 }
3830 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3831 pAdapter->sessionId);
3832 }
3833#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303834 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3835 {
Kiet Lamad161252014-07-22 11:23:32 -07003836 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303837 int ret;
3838
Kiet Lamad161252014-07-22 11:23:32 -07003839 dhcpPhase = command + 11;
3840 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303841 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003843 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303844
3845 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003846
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303847 ret = wlan_hdd_scan_abort(pAdapter);
3848 if (ret < 0)
3849 {
3850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3851 FL("failed to abort existing scan %d"), ret);
3852 }
3853
Kiet Lamad161252014-07-22 11:23:32 -07003854 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3855 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303856 }
Kiet Lamad161252014-07-22 11:23:32 -07003857 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303858 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003860 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303861
3862 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003863
3864 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3865 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303866 }
3867 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003868 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3869 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3871 FL("making default scan to ACTIVE"));
3872 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003873 }
3874 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3875 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3877 FL("making default scan to PASSIVE"));
3878 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003879 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303880 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3881 {
3882 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3883 char extra[32];
3884 tANI_U8 len = 0;
3885
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303886 memset(extra, 0, sizeof(extra));
3887 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3888 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303889 {
3890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3891 "%s: failed to copy data to user buffer", __func__);
3892 ret = -EFAULT;
3893 goto exit;
3894 }
3895 ret = len;
3896 }
3897 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3898 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303899 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303900 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003901 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3902 {
3903 tANI_U8 filterType = 0;
3904 tANI_U8 *value;
3905 value = command + 9;
3906
3907 /* Convert the value from ascii to integer */
3908 ret = kstrtou8(value, 10, &filterType);
3909 if (ret < 0)
3910 {
3911 /* If the input value is greater than max value of datatype,
3912 * then also kstrtou8 fails
3913 */
3914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3915 "%s: kstrtou8 failed range ", __func__);
3916 ret = -EINVAL;
3917 goto exit;
3918 }
3919 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3920 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3921 {
3922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3923 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3924 " 2-Sink ", __func__);
3925 ret = -EINVAL;
3926 goto exit;
3927 }
3928 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3929 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303930 pScanInfo = &pHddCtx->scan_info;
3931 if (filterType && pScanInfo != NULL &&
3932 pHddCtx->scan_info.mScanPending)
3933 {
3934 /*Miracast Session started. Abort Scan */
3935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3936 "%s, Aborting Scan For Miracast",__func__);
3937 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3938 eCSR_SCAN_ABORT_DEFAULT);
3939 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003940 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303941 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003942 }
Leo Chang614d2072013-08-22 14:59:44 -07003943 else if (strncmp(command, "SETMCRATE", 9) == 0)
3944 {
Leo Chang614d2072013-08-22 14:59:44 -07003945 tANI_U8 *value = command;
3946 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003947 tSirRateUpdateInd *rateUpdate;
3948 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003949
3950 /* Only valid for SAP mode */
3951 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3952 {
3953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3954 "%s: SAP mode is not running", __func__);
3955 ret = -EFAULT;
3956 goto exit;
3957 }
3958
3959 /* Move pointer to ahead of SETMCRATE<delimiter> */
3960 /* input value is in units of hundred kbps */
3961 value = value + 10;
3962 /* Convert the value from ascii to integer, decimal base */
3963 ret = kstrtouint(value, 10, &targetRate);
3964
Leo Chang1f98cbd2013-10-17 15:03:52 -07003965 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3966 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003967 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003968 hddLog(VOS_TRACE_LEVEL_ERROR,
3969 "%s: SETMCRATE indication alloc fail", __func__);
3970 ret = -EFAULT;
3971 goto exit;
3972 }
3973 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3974
3975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3976 "MC Target rate %d", targetRate);
3977 /* Ignore unicast */
3978 rateUpdate->ucastDataRate = -1;
3979 rateUpdate->mcastDataRate24GHz = targetRate;
3980 rateUpdate->mcastDataRate5GHz = targetRate;
3981 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3982 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3983 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3984 if (eHAL_STATUS_SUCCESS != status)
3985 {
3986 hddLog(VOS_TRACE_LEVEL_ERROR,
3987 "%s: SET_MC_RATE failed", __func__);
3988 vos_mem_free(rateUpdate);
3989 ret = -EFAULT;
3990 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003991 }
3992 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303993#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003994 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303995 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003996 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303997 }
3998#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003999#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004000 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4001 {
4002 tANI_U8 *value = command;
4003 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4004 tANI_U8 numChannels = 0;
4005 eHalStatus status = eHAL_STATUS_SUCCESS;
4006
4007 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4008 if (eHAL_STATUS_SUCCESS != status)
4009 {
4010 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4011 "%s: Failed to parse channel list information", __func__);
4012 ret = -EINVAL;
4013 goto exit;
4014 }
4015
4016 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4017 {
4018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4019 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4020 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4021 ret = -EINVAL;
4022 goto exit;
4023 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004024 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004025 ChannelList,
4026 numChannels);
4027 if (eHAL_STATUS_SUCCESS != status)
4028 {
4029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4030 "%s: Failed to update channel list information", __func__);
4031 ret = -EINVAL;
4032 goto exit;
4033 }
4034 }
4035 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4036 {
4037 tANI_U8 *value = command;
4038 char extra[128] = {0};
4039 int len = 0;
4040 tANI_U8 tid = 0;
4041 hdd_station_ctx_t *pHddStaCtx = NULL;
4042 tAniTrafStrmMetrics tsmMetrics;
4043 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4044
4045 /* if not associated, return error */
4046 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4047 {
4048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4049 ret = -EINVAL;
4050 goto exit;
4051 }
4052
4053 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4054 value = value + 12;
4055 /* Convert the value from ascii to integer */
4056 ret = kstrtou8(value, 10, &tid);
4057 if (ret < 0)
4058 {
4059 /* If the input value is greater than max value of datatype, then also
4060 kstrtou8 fails */
4061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4062 "%s: kstrtou8 failed range [%d - %d]", __func__,
4063 TID_MIN_VALUE,
4064 TID_MAX_VALUE);
4065 ret = -EINVAL;
4066 goto exit;
4067 }
4068
4069 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4070 {
4071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4072 "tid value %d is out of range"
4073 " (Min: %d Max: %d)", tid,
4074 TID_MIN_VALUE,
4075 TID_MAX_VALUE);
4076 ret = -EINVAL;
4077 goto exit;
4078 }
4079
4080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4081 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4082
4083 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4084 {
4085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4086 "%s: failed to get tsm stats", __func__);
4087 ret = -EFAULT;
4088 goto exit;
4089 }
4090
4091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4092 "UplinkPktQueueDly(%d)\n"
4093 "UplinkPktQueueDlyHist[0](%d)\n"
4094 "UplinkPktQueueDlyHist[1](%d)\n"
4095 "UplinkPktQueueDlyHist[2](%d)\n"
4096 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304097 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004098 "UplinkPktLoss(%d)\n"
4099 "UplinkPktCount(%d)\n"
4100 "RoamingCount(%d)\n"
4101 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4102 tsmMetrics.UplinkPktQueueDlyHist[0],
4103 tsmMetrics.UplinkPktQueueDlyHist[1],
4104 tsmMetrics.UplinkPktQueueDlyHist[2],
4105 tsmMetrics.UplinkPktQueueDlyHist[3],
4106 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4107 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4108
4109 /* Output TSM stats is of the format
4110 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4111 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004112 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004113 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4114 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4115 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4116 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4117 tsmMetrics.RoamingDly);
4118
4119 if (copy_to_user(priv_data.buf, &extra, len + 1))
4120 {
4121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4122 "%s: failed to copy data to user buffer", __func__);
4123 ret = -EFAULT;
4124 goto exit;
4125 }
4126 }
4127 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4128 {
4129 tANI_U8 *value = command;
4130 tANI_U8 *cckmIe = NULL;
4131 tANI_U8 cckmIeLen = 0;
4132 eHalStatus status = eHAL_STATUS_SUCCESS;
4133
4134 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4135 if (eHAL_STATUS_SUCCESS != status)
4136 {
4137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4138 "%s: Failed to parse cckm ie data", __func__);
4139 ret = -EINVAL;
4140 goto exit;
4141 }
4142
4143 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4144 {
4145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4146 "%s: CCKM Ie input length is more than max[%d]", __func__,
4147 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004148 vos_mem_free(cckmIe);
4149 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004150 ret = -EINVAL;
4151 goto exit;
4152 }
4153 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004154 vos_mem_free(cckmIe);
4155 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004156 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004157 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4158 {
4159 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004160 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004161 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004162
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004163 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004164 if (eHAL_STATUS_SUCCESS != status)
4165 {
4166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004167 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004168 ret = -EINVAL;
4169 goto exit;
4170 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004171 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4172 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4173 hdd_indicateEseBcnReportNoResults (pAdapter,
4174 eseBcnReq.bcnReq[0].measurementToken,
4175 0x02, //BIT(1) set for measurement done
4176 0); // no BSS
4177 goto exit;
4178 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004179
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004180 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4181 if (eHAL_STATUS_SUCCESS != status)
4182 {
4183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4184 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4185 ret = -EINVAL;
4186 goto exit;
4187 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004188 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004189#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304190 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4191 {
4192 eHalStatus status;
4193 char buf[32], len;
4194 long waitRet;
4195 bcnMissRateContext_t getBcnMissRateCtx;
4196
4197 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4198
4199 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4200 {
4201 hddLog(VOS_TRACE_LEVEL_WARN,
4202 FL("GETBCNMISSRATE: STA is not in connected state"));
4203 ret = -1;
4204 goto exit;
4205 }
4206
4207 init_completion(&(getBcnMissRateCtx.completion));
4208 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4209
4210 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4211 pAdapter->sessionId,
4212 (void *)getBcnMissRateCB,
4213 (void *)(&getBcnMissRateCtx));
4214 if( eHAL_STATUS_SUCCESS != status)
4215 {
4216 hddLog(VOS_TRACE_LEVEL_INFO,
4217 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4218 ret = -EINVAL;
4219 goto exit;
4220 }
4221
4222 waitRet = wait_for_completion_interruptible_timeout
4223 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4224 if(waitRet <= 0)
4225 {
4226 hddLog(VOS_TRACE_LEVEL_ERROR,
4227 FL("failed to wait on bcnMissRateComp %d"), ret);
4228
4229 //Make magic number to zero so that callback is not called.
4230 spin_lock(&hdd_context_lock);
4231 getBcnMissRateCtx.magic = 0x0;
4232 spin_unlock(&hdd_context_lock);
4233 ret = -EINVAL;
4234 goto exit;
4235 }
4236
4237 hddLog(VOS_TRACE_LEVEL_INFO,
4238 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4239
4240 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4241 if (copy_to_user(priv_data.buf, &buf, len + 1))
4242 {
4243 hddLog(VOS_TRACE_LEVEL_ERROR,
4244 "%s: failed to copy data to user buffer", __func__);
4245 ret = -EFAULT;
4246 goto exit;
4247 }
4248 ret = len;
4249 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304250#ifdef FEATURE_WLAN_TDLS
4251 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4252 tANI_U8 *value = command;
4253 int set_value;
4254 /* Move pointer to ahead of TDLSOFFCH*/
4255 value += 26;
4256 sscanf(value, "%d", &set_value);
4257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4258 "%s: Tdls offchannel offset:%d",
4259 __func__, set_value);
4260 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4261 if (ret < 0)
4262 {
4263 ret = -EINVAL;
4264 goto exit;
4265 }
4266
4267 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4268 tANI_U8 *value = command;
4269 int set_value;
4270 /* Move pointer to ahead of tdlsoffchnmode*/
4271 value += 18;
4272 sscanf(value, "%d", &set_value);
4273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4274 "%s: Tdls offchannel mode:%d",
4275 __func__, set_value);
4276 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4277 if (ret < 0)
4278 {
4279 ret = -EINVAL;
4280 goto exit;
4281 }
4282 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4283 tANI_U8 *value = command;
4284 int set_value;
4285 /* Move pointer to ahead of TDLSOFFCH*/
4286 value += 14;
4287 sscanf(value, "%d", &set_value);
4288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4289 "%s: Tdls offchannel num: %d",
4290 __func__, set_value);
4291 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4292 if (ret < 0)
4293 {
4294 ret = -EINVAL;
4295 goto exit;
4296 }
4297 }
4298#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304299 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4300 {
4301 eHalStatus status;
4302 char *buf = NULL;
4303 char len;
4304 long waitRet;
4305 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304306 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304307 tANI_U8 *ptr = command;
4308 int stats = *(ptr + 11) - '0';
4309
4310 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4311 if (!IS_FEATURE_FW_STATS_ENABLE)
4312 {
4313 hddLog(VOS_TRACE_LEVEL_INFO,
4314 FL("Get Firmware stats feature not supported"));
4315 ret = -EINVAL;
4316 goto exit;
4317 }
4318
4319 if (FW_STATS_MAX <= stats || 0 >= stats)
4320 {
4321 hddLog(VOS_TRACE_LEVEL_INFO,
4322 FL(" stats %d not supported"),stats);
4323 ret = -EINVAL;
4324 goto exit;
4325 }
4326
4327 init_completion(&(fwStatsCtx.completion));
4328 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4329 fwStatsCtx.pAdapter = pAdapter;
4330 fwStatsRsp->type = 0;
4331 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304332 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304333 if (eHAL_STATUS_SUCCESS != status)
4334 {
4335 hddLog(VOS_TRACE_LEVEL_ERROR,
4336 FL(" fail to post WDA cmd status = %d"), status);
4337 ret = -EINVAL;
4338 goto exit;
4339 }
4340 waitRet = wait_for_completion_timeout
4341 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4342 if (waitRet <= 0)
4343 {
4344 hddLog(VOS_TRACE_LEVEL_ERROR,
4345 FL("failed to wait on GwtFwstats"));
4346 //Make magic number to zero so that callback is not executed.
4347 spin_lock(&hdd_context_lock);
4348 fwStatsCtx.magic = 0x0;
4349 spin_unlock(&hdd_context_lock);
4350 ret = -EINVAL;
4351 goto exit;
4352 }
4353 if (fwStatsRsp->type)
4354 {
4355 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4356 if (!buf)
4357 {
4358 hddLog(VOS_TRACE_LEVEL_ERROR,
4359 FL(" failed to allocate memory"));
4360 ret = -ENOMEM;
4361 goto exit;
4362 }
4363 switch( fwStatsRsp->type )
4364 {
4365 case FW_UBSP_STATS:
4366 {
4367 len = snprintf(buf, FW_STATE_RSP_LEN,
4368 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304369 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4370 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304371 }
4372 break;
4373 default:
4374 {
4375 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4376 ret = -EFAULT;
4377 kfree(buf);
4378 goto exit;
4379 }
4380 }
4381 if (copy_to_user(priv_data.buf, buf, len + 1))
4382 {
4383 hddLog(VOS_TRACE_LEVEL_ERROR,
4384 FL(" failed to copy data to user buffer"));
4385 ret = -EFAULT;
4386 kfree(buf);
4387 goto exit;
4388 }
4389 ret = len;
4390 kfree(buf);
4391 }
4392 else
4393 {
4394 hddLog(VOS_TRACE_LEVEL_ERROR,
4395 FL("failed to fetch the stats"));
4396 ret = -EFAULT;
4397 goto exit;
4398 }
4399
4400 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004401 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304402 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4403 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4404 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304405 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4406 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004408 }
4409exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304410 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004411 if (command)
4412 {
4413 kfree(command);
4414 }
4415 return ret;
4416}
4417
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004418#ifdef CONFIG_COMPAT
4419static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4420{
4421 struct {
4422 compat_uptr_t buf;
4423 int used_len;
4424 int total_len;
4425 } compat_priv_data;
4426 hdd_priv_data_t priv_data;
4427 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004428
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004429 /*
4430 * Note that pAdapter and ifr have already been verified by caller,
4431 * and HDD context has also been validated
4432 */
4433 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4434 sizeof(compat_priv_data))) {
4435 ret = -EFAULT;
4436 goto exit;
4437 }
4438 priv_data.buf = compat_ptr(compat_priv_data.buf);
4439 priv_data.used_len = compat_priv_data.used_len;
4440 priv_data.total_len = compat_priv_data.total_len;
4441 ret = hdd_driver_command(pAdapter, &priv_data);
4442 exit:
4443 return ret;
4444}
4445#else /* CONFIG_COMPAT */
4446static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4447{
4448 /* will never be invoked */
4449 return 0;
4450}
4451#endif /* CONFIG_COMPAT */
4452
4453static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4454{
4455 hdd_priv_data_t priv_data;
4456 int ret = 0;
4457
4458 /*
4459 * Note that pAdapter and ifr have already been verified by caller,
4460 * and HDD context has also been validated
4461 */
4462 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4463 ret = -EFAULT;
4464 } else {
4465 ret = hdd_driver_command(pAdapter, &priv_data);
4466 }
4467 return ret;
4468}
4469
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304470int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004471{
4472 hdd_adapter_t *pAdapter;
4473 hdd_context_t *pHddCtx;
4474 int ret;
4475
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304476 ENTER();
4477
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004478 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4479 if (NULL == pAdapter) {
4480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4481 "%s: HDD adapter context is Null", __func__);
4482 ret = -ENODEV;
4483 goto exit;
4484 }
4485 if (dev != pAdapter->dev) {
4486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4487 "%s: HDD adapter/dev inconsistency", __func__);
4488 ret = -ENODEV;
4489 goto exit;
4490 }
4491
4492 if ((!ifr) || (!ifr->ifr_data)) {
4493 ret = -EINVAL;
4494 goto exit;
4495 }
4496
4497 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4498 ret = wlan_hdd_validate_context(pHddCtx);
4499 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004500 ret = -EBUSY;
4501 goto exit;
4502 }
4503
4504 switch (cmd) {
4505 case (SIOCDEVPRIVATE + 1):
4506 if (is_compat_task())
4507 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4508 else
4509 ret = hdd_driver_ioctl(pAdapter, ifr);
4510 break;
4511 default:
4512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4513 __func__, cmd);
4514 ret = -EINVAL;
4515 break;
4516 }
4517 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304518 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004519 return ret;
4520}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004521
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304522int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4523{
4524 int ret;
4525
4526 vos_ssr_protect(__func__);
4527 ret = __hdd_ioctl(dev, ifr, cmd);
4528 vos_ssr_unprotect(__func__);
4529
4530 return ret;
4531}
4532
Katya Nigame7b69a82015-04-28 15:24:06 +05304533int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4534{
4535 return 0;
4536}
4537
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004538#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004539/**---------------------------------------------------------------------------
4540
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004541 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004542
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004543 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004544 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4545 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4546 <space>Scan Mode N<space>Meas Duration N
4547 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4548 then take N.
4549 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4550 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4551 This function does not take care of removing duplicate channels from the list
4552
4553 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004554 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004555
4556 \return - 0 for success non-zero for failure
4557
4558 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004559static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4560 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004561{
4562 tANI_U8 *inPtr = pValue;
4563 int tempInt = 0;
4564 int j = 0, i = 0, v = 0;
4565 char buf[32];
4566
4567 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4568 /*no argument after the command*/
4569 if (NULL == inPtr)
4570 {
4571 return -EINVAL;
4572 }
4573 /*no space after the command*/
4574 else if (SPACE_ASCII_VALUE != *inPtr)
4575 {
4576 return -EINVAL;
4577 }
4578
4579 /*removing empty spaces*/
4580 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4581
4582 /*no argument followed by spaces*/
4583 if ('\0' == *inPtr) return -EINVAL;
4584
4585 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004586 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004587 if (1 != v) return -EINVAL;
4588
4589 v = kstrtos32(buf, 10, &tempInt);
4590 if ( v < 0) return -EINVAL;
4591
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004592 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004593
4594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004595 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004596
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004598 {
4599 for (i = 0; i < 4; i++)
4600 {
4601 /*inPtr pointing to the beginning of first space after number of ie fields*/
4602 inPtr = strpbrk( inPtr, " " );
4603 /*no ie data after the number of ie fields argument*/
4604 if (NULL == inPtr) return -EINVAL;
4605
4606 /*removing empty space*/
4607 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4608
4609 /*no ie data after the number of ie fields argument and spaces*/
4610 if ( '\0' == *inPtr ) return -EINVAL;
4611
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004612 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004613 if (1 != v) return -EINVAL;
4614
4615 v = kstrtos32(buf, 10, &tempInt);
4616 if (v < 0) return -EINVAL;
4617
4618 switch (i)
4619 {
4620 case 0: /* Measurement token */
4621 if (tempInt <= 0)
4622 {
4623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4624 "Invalid Measurement Token(%d)", tempInt);
4625 return -EINVAL;
4626 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004627 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004628 break;
4629
4630 case 1: /* Channel number */
4631 if ((tempInt <= 0) ||
4632 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4633 {
4634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4635 "Invalid Channel Number(%d)", tempInt);
4636 return -EINVAL;
4637 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004638 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004639 break;
4640
4641 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004642 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004643 {
4644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4645 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4646 return -EINVAL;
4647 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004648 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004649 break;
4650
4651 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004652 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4653 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004654 {
4655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4656 "Invalid Measurement Duration(%d)", tempInt);
4657 return -EINVAL;
4658 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004659 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004660 break;
4661 }
4662 }
4663 }
4664
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004665 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004666 {
4667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304668 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004669 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004670 pEseBcnReq->bcnReq[j].measurementToken,
4671 pEseBcnReq->bcnReq[j].channel,
4672 pEseBcnReq->bcnReq[j].scanMode,
4673 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004674 }
4675
4676 return VOS_STATUS_SUCCESS;
4677}
4678
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004679static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4680{
4681 struct statsContext *pStatsContext = NULL;
4682 hdd_adapter_t *pAdapter = NULL;
4683
4684 if (NULL == pContext)
4685 {
4686 hddLog(VOS_TRACE_LEVEL_ERROR,
4687 "%s: Bad param, pContext [%p]",
4688 __func__, pContext);
4689 return;
4690 }
4691
Jeff Johnson72a40512013-12-19 10:14:15 -08004692 /* there is a race condition that exists between this callback
4693 function and the caller since the caller could time out either
4694 before or while this code is executing. we use a spinlock to
4695 serialize these actions */
4696 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004697
4698 pStatsContext = pContext;
4699 pAdapter = pStatsContext->pAdapter;
4700 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4701 {
4702 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004703 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004704 hddLog(VOS_TRACE_LEVEL_WARN,
4705 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4706 __func__, pAdapter, pStatsContext->magic);
4707 return;
4708 }
4709
Jeff Johnson72a40512013-12-19 10:14:15 -08004710 /* context is valid so caller is still waiting */
4711
4712 /* paranoia: invalidate the magic */
4713 pStatsContext->magic = 0;
4714
4715 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004716 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4717 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4718 tsmMetrics.UplinkPktQueueDlyHist,
4719 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4720 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4721 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4722 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4723 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4724 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4725 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4726
Jeff Johnson72a40512013-12-19 10:14:15 -08004727 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004728 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004729
4730 /* serialization is complete */
4731 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004732}
4733
4734
4735
4736static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4737 tAniTrafStrmMetrics* pTsmMetrics)
4738{
4739 hdd_station_ctx_t *pHddStaCtx = NULL;
4740 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004741 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004742 long lrc;
4743 struct statsContext context;
4744 hdd_context_t *pHddCtx = NULL;
4745
4746 if (NULL == pAdapter)
4747 {
4748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4749 return VOS_STATUS_E_FAULT;
4750 }
4751
4752 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4753 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4754
4755 /* we are connected prepare our callback context */
4756 init_completion(&context.completion);
4757 context.pAdapter = pAdapter;
4758 context.magic = STATS_CONTEXT_MAGIC;
4759
4760 /* query tsm stats */
4761 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4762 pHddStaCtx->conn_info.staId[ 0 ],
4763 pHddStaCtx->conn_info.bssId,
4764 &context, pHddCtx->pvosContext, tid);
4765
4766 if (eHAL_STATUS_SUCCESS != hstatus)
4767 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004768 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4769 __func__);
4770 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004771 }
4772 else
4773 {
4774 /* request was sent -- wait for the response */
4775 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4776 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004777 if (lrc <= 0)
4778 {
4779 hddLog(VOS_TRACE_LEVEL_ERROR,
4780 "%s: SME %s while retrieving statistics",
4781 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004782 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004783 }
4784 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004785
Jeff Johnson72a40512013-12-19 10:14:15 -08004786 /* either we never sent a request, we sent a request and received a
4787 response or we sent a request and timed out. if we never sent a
4788 request or if we sent a request and got a response, we want to
4789 clear the magic out of paranoia. if we timed out there is a
4790 race condition such that the callback function could be
4791 executing at the same time we are. of primary concern is if the
4792 callback function had already verified the "magic" but had not
4793 yet set the completion variable when a timeout occurred. we
4794 serialize these activities by invalidating the magic while
4795 holding a shared spinlock which will cause us to block if the
4796 callback is currently executing */
4797 spin_lock(&hdd_context_lock);
4798 context.magic = 0;
4799 spin_unlock(&hdd_context_lock);
4800
4801 if (VOS_STATUS_SUCCESS == vstatus)
4802 {
4803 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4804 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4805 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4806 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4807 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4808 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4809 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4810 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4811 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4812 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4813 }
4814 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004815}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004816#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004817
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004818#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004819void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4820{
4821 eCsrBand band = -1;
4822 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4823 switch (band)
4824 {
4825 case eCSR_BAND_ALL:
4826 *pBand = WLAN_HDD_UI_BAND_AUTO;
4827 break;
4828
4829 case eCSR_BAND_24:
4830 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4831 break;
4832
4833 case eCSR_BAND_5G:
4834 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4835 break;
4836
4837 default:
4838 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4839 *pBand = -1;
4840 break;
4841 }
4842}
4843
4844/**---------------------------------------------------------------------------
4845
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004846 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4847
4848 This function parses the send action frame data passed in the format
4849 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4850
Srinivas Girigowda56076852013-08-20 14:00:50 -07004851 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004852 \param - pTargetApBssid Pointer to target Ap bssid
4853 \param - pChannel Pointer to the Target AP channel
4854 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4855 \param - pBuf Pointer to data
4856 \param - pBufLen Pointer to data length
4857
4858 \return - 0 for success non-zero for failure
4859
4860 --------------------------------------------------------------------------*/
4861VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4862 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4863{
4864 tANI_U8 *inPtr = pValue;
4865 tANI_U8 *dataEnd;
4866 int tempInt;
4867 int j = 0;
4868 int i = 0;
4869 int v = 0;
4870 tANI_U8 tempBuf[32];
4871 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004872 /* 12 hexa decimal digits, 5 ':' and '\0' */
4873 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004874
4875 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4876 /*no argument after the command*/
4877 if (NULL == inPtr)
4878 {
4879 return -EINVAL;
4880 }
4881
4882 /*no space after the command*/
4883 else if (SPACE_ASCII_VALUE != *inPtr)
4884 {
4885 return -EINVAL;
4886 }
4887
4888 /*removing empty spaces*/
4889 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4890
4891 /*no argument followed by spaces*/
4892 if ('\0' == *inPtr)
4893 {
4894 return -EINVAL;
4895 }
4896
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004897 v = sscanf(inPtr, "%17s", macAddress);
4898 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004899 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4901 "Invalid MAC address or All hex inputs are not read (%d)", v);
4902 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004903 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004904
4905 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4906 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4907 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4908 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4909 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4910 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004911
4912 /* point to the next argument */
4913 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4914 /*no argument after the command*/
4915 if (NULL == inPtr) return -EINVAL;
4916
4917 /*removing empty spaces*/
4918 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4919
4920 /*no argument followed by spaces*/
4921 if ('\0' == *inPtr)
4922 {
4923 return -EINVAL;
4924 }
4925
4926 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004927 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004928 if (1 != v) return -EINVAL;
4929
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004930 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304931 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304932 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004933
4934 *pChannel = tempInt;
4935
4936 /* point to the next argument */
4937 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4938 /*no argument after the command*/
4939 if (NULL == inPtr) return -EINVAL;
4940 /*removing empty spaces*/
4941 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4942
4943 /*no argument followed by spaces*/
4944 if ('\0' == *inPtr)
4945 {
4946 return -EINVAL;
4947 }
4948
4949 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004950 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004951 if (1 != v) return -EINVAL;
4952
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004953 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004954 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004955
4956 *pDwellTime = tempInt;
4957
4958 /* point to the next argument */
4959 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4960 /*no argument after the command*/
4961 if (NULL == inPtr) return -EINVAL;
4962 /*removing empty spaces*/
4963 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4964
4965 /*no argument followed by spaces*/
4966 if ('\0' == *inPtr)
4967 {
4968 return -EINVAL;
4969 }
4970
4971 /* find the length of data */
4972 dataEnd = inPtr;
4973 while(('\0' != *dataEnd) )
4974 {
4975 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004976 }
Kiet Lambe150c22013-11-21 16:30:32 +05304977 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004978 if ( *pBufLen <= 0) return -EINVAL;
4979
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004980 /* Allocate the number of bytes based on the number of input characters
4981 whether it is even or odd.
4982 if the number of input characters are even, then we need N/2 byte.
4983 if the number of input characters are odd, then we need do (N+1)/2 to
4984 compensate rounding off.
4985 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4986 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4987 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004988 if (NULL == *pBuf)
4989 {
4990 hddLog(VOS_TRACE_LEVEL_FATAL,
4991 "%s: vos_mem_alloc failed ", __func__);
4992 return -EINVAL;
4993 }
4994
4995 /* the buffer received from the upper layer is character buffer,
4996 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4997 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4998 and f0 in 3rd location */
4999 for (i = 0, j = 0; j < *pBufLen; j += 2)
5000 {
Kiet Lambe150c22013-11-21 16:30:32 +05305001 if( j+1 == *pBufLen)
5002 {
5003 tempByte = hdd_parse_hex(inPtr[j]);
5004 }
5005 else
5006 {
5007 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5008 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005009 (*pBuf)[i++] = tempByte;
5010 }
5011 *pBufLen = i;
5012 return VOS_STATUS_SUCCESS;
5013}
5014
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005015/**---------------------------------------------------------------------------
5016
Srinivas Girigowdade697412013-02-14 16:31:48 -08005017 \brief hdd_parse_channellist() - HDD Parse channel list
5018
5019 This function parses the channel list passed in the format
5020 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005021 if the Number of channels (N) does not match with the actual number of channels passed
5022 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5023 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5024 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5025 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005026
5027 \param - pValue Pointer to input channel list
5028 \param - ChannelList Pointer to local output array to record channel list
5029 \param - pNumChannels Pointer to number of roam scan channels
5030
5031 \return - 0 for success non-zero for failure
5032
5033 --------------------------------------------------------------------------*/
5034VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5035{
5036 tANI_U8 *inPtr = pValue;
5037 int tempInt;
5038 int j = 0;
5039 int v = 0;
5040 char buf[32];
5041
5042 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5043 /*no argument after the command*/
5044 if (NULL == inPtr)
5045 {
5046 return -EINVAL;
5047 }
5048
5049 /*no space after the command*/
5050 else if (SPACE_ASCII_VALUE != *inPtr)
5051 {
5052 return -EINVAL;
5053 }
5054
5055 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005056 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005057
5058 /*no argument followed by spaces*/
5059 if ('\0' == *inPtr)
5060 {
5061 return -EINVAL;
5062 }
5063
5064 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005065 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005066 if (1 != v) return -EINVAL;
5067
Srinivas Girigowdade697412013-02-14 16:31:48 -08005068 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005069 if ((v < 0) ||
5070 (tempInt <= 0) ||
5071 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5072 {
5073 return -EINVAL;
5074 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005075
5076 *pNumChannels = tempInt;
5077
5078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5079 "Number of channels are: %d", *pNumChannels);
5080
5081 for (j = 0; j < (*pNumChannels); j++)
5082 {
5083 /*inPtr pointing to the beginning of first space after number of channels*/
5084 inPtr = strpbrk( inPtr, " " );
5085 /*no channel list after the number of channels argument*/
5086 if (NULL == inPtr)
5087 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005088 if (0 != j)
5089 {
5090 *pNumChannels = j;
5091 return VOS_STATUS_SUCCESS;
5092 }
5093 else
5094 {
5095 return -EINVAL;
5096 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005097 }
5098
5099 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005100 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005101
5102 /*no channel list after the number of channels argument and spaces*/
5103 if ( '\0' == *inPtr )
5104 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005105 if (0 != j)
5106 {
5107 *pNumChannels = j;
5108 return VOS_STATUS_SUCCESS;
5109 }
5110 else
5111 {
5112 return -EINVAL;
5113 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005114 }
5115
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005116 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005117 if (1 != v) return -EINVAL;
5118
Srinivas Girigowdade697412013-02-14 16:31:48 -08005119 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005120 if ((v < 0) ||
5121 (tempInt <= 0) ||
5122 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5123 {
5124 return -EINVAL;
5125 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005126 pChannelList[j] = tempInt;
5127
5128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5129 "Channel %d added to preferred channel list",
5130 pChannelList[j] );
5131 }
5132
Srinivas Girigowdade697412013-02-14 16:31:48 -08005133 return VOS_STATUS_SUCCESS;
5134}
5135
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005136
5137/**---------------------------------------------------------------------------
5138
5139 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5140
5141 This function parses the reasoc command data passed in the format
5142 REASSOC<space><bssid><space><channel>
5143
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005144 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005145 \param - pTargetApBssid Pointer to target Ap bssid
5146 \param - pChannel Pointer to the Target AP channel
5147
5148 \return - 0 for success non-zero for failure
5149
5150 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005151VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5152 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005153{
5154 tANI_U8 *inPtr = pValue;
5155 int tempInt;
5156 int v = 0;
5157 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005158 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005159 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005160
5161 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5162 /*no argument after the command*/
5163 if (NULL == inPtr)
5164 {
5165 return -EINVAL;
5166 }
5167
5168 /*no space after the command*/
5169 else if (SPACE_ASCII_VALUE != *inPtr)
5170 {
5171 return -EINVAL;
5172 }
5173
5174 /*removing empty spaces*/
5175 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5176
5177 /*no argument followed by spaces*/
5178 if ('\0' == *inPtr)
5179 {
5180 return -EINVAL;
5181 }
5182
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005183 v = sscanf(inPtr, "%17s", macAddress);
5184 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005185 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5187 "Invalid MAC address or All hex inputs are not read (%d)", v);
5188 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005189 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005190
5191 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5192 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5193 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5194 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5195 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5196 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005197
5198 /* point to the next argument */
5199 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5200 /*no argument after the command*/
5201 if (NULL == inPtr) return -EINVAL;
5202
5203 /*removing empty spaces*/
5204 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5205
5206 /*no argument followed by spaces*/
5207 if ('\0' == *inPtr)
5208 {
5209 return -EINVAL;
5210 }
5211
5212 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005213 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005214 if (1 != v) return -EINVAL;
5215
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005216 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005217 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305218 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005219 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5220 {
5221 return -EINVAL;
5222 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005223
5224 *pChannel = tempInt;
5225 return VOS_STATUS_SUCCESS;
5226}
5227
5228#endif
5229
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005230#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005231/**---------------------------------------------------------------------------
5232
5233 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5234
5235 This function parses the SETCCKM IE command
5236 SETCCKMIE<space><ie data>
5237
5238 \param - pValue Pointer to input data
5239 \param - pCckmIe Pointer to output cckm Ie
5240 \param - pCckmIeLen Pointer to output cckm ie length
5241
5242 \return - 0 for success non-zero for failure
5243
5244 --------------------------------------------------------------------------*/
5245VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5246 tANI_U8 *pCckmIeLen)
5247{
5248 tANI_U8 *inPtr = pValue;
5249 tANI_U8 *dataEnd;
5250 int j = 0;
5251 int i = 0;
5252 tANI_U8 tempByte = 0;
5253
5254 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5255 /*no argument after the command*/
5256 if (NULL == inPtr)
5257 {
5258 return -EINVAL;
5259 }
5260
5261 /*no space after the command*/
5262 else if (SPACE_ASCII_VALUE != *inPtr)
5263 {
5264 return -EINVAL;
5265 }
5266
5267 /*removing empty spaces*/
5268 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5269
5270 /*no argument followed by spaces*/
5271 if ('\0' == *inPtr)
5272 {
5273 return -EINVAL;
5274 }
5275
5276 /* find the length of data */
5277 dataEnd = inPtr;
5278 while(('\0' != *dataEnd) )
5279 {
5280 dataEnd++;
5281 ++(*pCckmIeLen);
5282 }
5283 if ( *pCckmIeLen <= 0) return -EINVAL;
5284
5285 /* Allocate the number of bytes based on the number of input characters
5286 whether it is even or odd.
5287 if the number of input characters are even, then we need N/2 byte.
5288 if the number of input characters are odd, then we need do (N+1)/2 to
5289 compensate rounding off.
5290 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5291 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5292 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5293 if (NULL == *pCckmIe)
5294 {
5295 hddLog(VOS_TRACE_LEVEL_FATAL,
5296 "%s: vos_mem_alloc failed ", __func__);
5297 return -EINVAL;
5298 }
5299 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5300 /* the buffer received from the upper layer is character buffer,
5301 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5302 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5303 and f0 in 3rd location */
5304 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5305 {
5306 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5307 (*pCckmIe)[i++] = tempByte;
5308 }
5309 *pCckmIeLen = i;
5310
5311 return VOS_STATUS_SUCCESS;
5312}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005313#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005314
Jeff Johnson295189b2012-06-20 16:38:30 -07005315/**---------------------------------------------------------------------------
5316
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005317 \brief hdd_is_valid_mac_address() - Validate MAC address
5318
5319 This function validates whether the given MAC address is valid or not
5320 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5321 where X is the hexa decimal digit character and separated by ':'
5322 This algorithm works even if MAC address is not separated by ':'
5323
5324 This code checks given input string mac contains exactly 12 hexadecimal digits.
5325 and a separator colon : appears in the input string only after
5326 an even number of hex digits.
5327
5328 \param - pMacAddr pointer to the input MAC address
5329 \return - 1 for valid and 0 for invalid
5330
5331 --------------------------------------------------------------------------*/
5332
5333v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5334{
5335 int xdigit = 0;
5336 int separator = 0;
5337 while (*pMacAddr)
5338 {
5339 if (isxdigit(*pMacAddr))
5340 {
5341 xdigit++;
5342 }
5343 else if (':' == *pMacAddr)
5344 {
5345 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5346 break;
5347
5348 ++separator;
5349 }
5350 else
5351 {
5352 separator = -1;
5353 /* Invalid MAC found */
5354 return 0;
5355 }
5356 ++pMacAddr;
5357 }
5358 return (xdigit == 12 && (separator == 5 || separator == 0));
5359}
5360
5361/**---------------------------------------------------------------------------
5362
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305363 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005364
5365 \param - dev Pointer to net_device structure
5366
5367 \return - 0 for success non-zero for failure
5368
5369 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305370int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005371{
5372 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5373 hdd_context_t *pHddCtx;
5374 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5375 VOS_STATUS status;
5376 v_BOOL_t in_standby = TRUE;
5377
5378 if (NULL == pAdapter)
5379 {
5380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305381 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 return -ENODEV;
5383 }
5384
5385 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305386 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5387 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 if (NULL == pHddCtx)
5389 {
5390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005391 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 return -ENODEV;
5393 }
5394
5395 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5396 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5397 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005398 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5399 {
5400 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305401 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005402 in_standby = FALSE;
5403 break;
5404 }
5405 else
5406 {
5407 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5408 pAdapterNode = pNext;
5409 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005410 }
5411
5412 if (TRUE == in_standby)
5413 {
5414 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5415 {
5416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5417 "wlan out of power save", __func__);
5418 return -EINVAL;
5419 }
5420 }
5421
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005422 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5424 {
5425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005426 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005427 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305428 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005429 netif_tx_start_all_queues(dev);
5430 }
5431
5432 return 0;
5433}
5434
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305435/**---------------------------------------------------------------------------
5436
5437 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5438
5439 This is called in response to ifconfig up
5440
5441 \param - dev Pointer to net_device structure
5442
5443 \return - 0 for success non-zero for failure
5444
5445 --------------------------------------------------------------------------*/
5446int hdd_open(struct net_device *dev)
5447{
5448 int ret;
5449
5450 vos_ssr_protect(__func__);
5451 ret = __hdd_open(dev);
5452 vos_ssr_unprotect(__func__);
5453
5454 return ret;
5455}
5456
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305457int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005458{
5459 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5460
5461 if(pAdapter == NULL) {
5462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005463 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005464 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005465 }
5466
Jeff Johnson295189b2012-06-20 16:38:30 -07005467 return 0;
5468}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305469
5470int hdd_mon_open (struct net_device *dev)
5471{
5472 int ret;
5473
5474 vos_ssr_protect(__func__);
5475 ret = __hdd_mon_open(dev);
5476 vos_ssr_unprotect(__func__);
5477
5478 return ret;
5479}
5480
Katya Nigame7b69a82015-04-28 15:24:06 +05305481int hdd_mon_stop(struct net_device *dev)
5482{
5483 return 0;
5484}
5485
Jeff Johnson295189b2012-06-20 16:38:30 -07005486/**---------------------------------------------------------------------------
5487
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305488 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005489
5490 \param - dev Pointer to net_device structure
5491
5492 \return - 0 for success non-zero for failure
5493
5494 --------------------------------------------------------------------------*/
5495
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305496int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005497{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305498 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5500 hdd_context_t *pHddCtx;
5501 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5502 VOS_STATUS status;
5503 v_BOOL_t enter_standby = TRUE;
5504
5505 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 if (NULL == pAdapter)
5507 {
5508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305509 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005510 return -ENODEV;
5511 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305512 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305513 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305514
5515 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5516 ret = wlan_hdd_validate_context(pHddCtx);
5517 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305519 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005520 }
5521
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305522 /* Nothing to be done if the interface is not opened */
5523 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5524 {
5525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5526 "%s: NETDEV Interface is not OPENED", __func__);
5527 return -ENODEV;
5528 }
5529
5530 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005531 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305533
5534 /* Disable TX on the interface, after this hard_start_xmit() will not
5535 * be called on that interface
5536 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305537 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005538 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305539
5540 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 netif_carrier_off(pAdapter->dev);
5542
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305543 /* The interface is marked as down for outside world (aka kernel)
5544 * But the driver is pretty much alive inside. The driver needs to
5545 * tear down the existing connection on the netdev (session)
5546 * cleanup the data pipes and wait until the control plane is stabilized
5547 * for this interface. The call also needs to wait until the above
5548 * mentioned actions are completed before returning to the caller.
5549 * Notice that the hdd_stop_adapter is requested not to close the session
5550 * That is intentional to be able to scan if it is a STA/P2P interface
5551 */
5552 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305553#ifdef FEATURE_WLAN_TDLS
5554 mutex_lock(&pHddCtx->tdls_lock);
5555#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305556 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305557 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305558#ifdef FEATURE_WLAN_TDLS
5559 mutex_unlock(&pHddCtx->tdls_lock);
5560#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 /* SoftAP ifaces should never go in power save mode
5562 making sure same here. */
5563 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5564 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 )
5567 {
5568 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5570 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005571 EXIT();
5572 return 0;
5573 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305574 /* Find if any iface is up. If any iface is up then can't put device to
5575 * sleep/power save mode
5576 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005577 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5578 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5579 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005580 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5581 {
5582 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305583 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005584 enter_standby = FALSE;
5585 break;
5586 }
5587 else
5588 {
5589 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5590 pAdapterNode = pNext;
5591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005592 }
5593
5594 if (TRUE == enter_standby)
5595 {
5596 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5597 "entering standby", __func__);
5598 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5599 {
5600 /*log and return success*/
5601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5602 "wlan in power save", __func__);
5603 }
5604 }
5605
5606 EXIT();
5607 return 0;
5608}
5609
5610/**---------------------------------------------------------------------------
5611
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305612 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005613
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305614 This is called in response to ifconfig down
5615
5616 \param - dev Pointer to net_device structure
5617
5618 \return - 0 for success non-zero for failure
5619-----------------------------------------------------------------------------*/
5620int hdd_stop (struct net_device *dev)
5621{
5622 int ret;
5623
5624 vos_ssr_protect(__func__);
5625 ret = __hdd_stop(dev);
5626 vos_ssr_unprotect(__func__);
5627
5628 return ret;
5629}
5630
5631/**---------------------------------------------------------------------------
5632
5633 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005634
5635 \param - dev Pointer to net_device structure
5636
5637 \return - void
5638
5639 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305640static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005641{
5642 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305643 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 ENTER();
5645
5646 do
5647 {
5648 if (NULL == pAdapter)
5649 {
5650 hddLog(VOS_TRACE_LEVEL_FATAL,
5651 "%s: NULL pAdapter", __func__);
5652 break;
5653 }
5654
5655 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5656 {
5657 hddLog(VOS_TRACE_LEVEL_FATAL,
5658 "%s: Invalid magic", __func__);
5659 break;
5660 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305661 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5662 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005663 {
5664 hddLog(VOS_TRACE_LEVEL_FATAL,
5665 "%s: NULL pHddCtx", __func__);
5666 break;
5667 }
5668
5669 if (dev != pAdapter->dev)
5670 {
5671 hddLog(VOS_TRACE_LEVEL_FATAL,
5672 "%s: Invalid device reference", __func__);
5673 /* we haven't validated all cases so let this go for now */
5674 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305675#ifdef FEATURE_WLAN_TDLS
5676 mutex_lock(&pHddCtx->tdls_lock);
5677#endif
c_hpothu002231a2015-02-05 14:58:51 +05305678 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305679#ifdef FEATURE_WLAN_TDLS
5680 mutex_unlock(&pHddCtx->tdls_lock);
5681#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005682
5683 /* after uninit our adapter structure will no longer be valid */
5684 pAdapter->dev = NULL;
5685 pAdapter->magic = 0;
5686 } while (0);
5687
5688 EXIT();
5689}
5690
5691/**---------------------------------------------------------------------------
5692
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305693 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5694
5695 This is called during the netdev unregister to uninitialize all data
5696associated with the device
5697
5698 \param - dev Pointer to net_device structure
5699
5700 \return - void
5701
5702 --------------------------------------------------------------------------*/
5703static void hdd_uninit (struct net_device *dev)
5704{
5705 vos_ssr_protect(__func__);
5706 __hdd_uninit(dev);
5707 vos_ssr_unprotect(__func__);
5708}
5709
5710/**---------------------------------------------------------------------------
5711
Jeff Johnson295189b2012-06-20 16:38:30 -07005712 \brief hdd_release_firmware() -
5713
5714 This function calls the release firmware API to free the firmware buffer.
5715
5716 \param - pFileName Pointer to the File Name.
5717 pCtx - Pointer to the adapter .
5718
5719
5720 \return - 0 for success, non zero for failure
5721
5722 --------------------------------------------------------------------------*/
5723
5724VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5725{
5726 VOS_STATUS status = VOS_STATUS_SUCCESS;
5727 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5728 ENTER();
5729
5730
5731 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5732
5733 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5734
5735 if(pHddCtx->fw) {
5736 release_firmware(pHddCtx->fw);
5737 pHddCtx->fw = NULL;
5738 }
5739 else
5740 status = VOS_STATUS_E_FAILURE;
5741 }
5742 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5743 if(pHddCtx->nv) {
5744 release_firmware(pHddCtx->nv);
5745 pHddCtx->nv = NULL;
5746 }
5747 else
5748 status = VOS_STATUS_E_FAILURE;
5749
5750 }
5751
5752 EXIT();
5753 return status;
5754}
5755
5756/**---------------------------------------------------------------------------
5757
5758 \brief hdd_request_firmware() -
5759
5760 This function reads the firmware file using the request firmware
5761 API and returns the the firmware data and the firmware file size.
5762
5763 \param - pfileName - Pointer to the file name.
5764 - pCtx - Pointer to the adapter .
5765 - ppfw_data - Pointer to the pointer of the firmware data.
5766 - pSize - Pointer to the file size.
5767
5768 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5769
5770 --------------------------------------------------------------------------*/
5771
5772
5773VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5774{
5775 int status;
5776 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5777 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5778 ENTER();
5779
5780 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5781
5782 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5783
5784 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5785 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5786 __func__, pfileName);
5787 retval = VOS_STATUS_E_FAILURE;
5788 }
5789
5790 else {
5791 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5792 *pSize = pHddCtx->fw->size;
5793 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5794 __func__, *pSize);
5795 }
5796 }
5797 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5798
5799 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5800
5801 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5802 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5803 __func__, pfileName);
5804 retval = VOS_STATUS_E_FAILURE;
5805 }
5806
5807 else {
5808 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5809 *pSize = pHddCtx->nv->size;
5810 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5811 __func__, *pSize);
5812 }
5813 }
5814
5815 EXIT();
5816 return retval;
5817}
5818/**---------------------------------------------------------------------------
5819 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5820
5821 This is the function invoked by SME to inform the result of a full power
5822 request issued by HDD
5823
5824 \param - callbackcontext - Pointer to cookie
5825 status - result of request
5826
5827 \return - None
5828
5829--------------------------------------------------------------------------*/
5830void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5831{
5832 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5833
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005834 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 if(&pHddCtx->full_pwr_comp_var)
5836 {
5837 complete(&pHddCtx->full_pwr_comp_var);
5838 }
5839}
5840
5841/**---------------------------------------------------------------------------
5842
5843 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5844
5845 This is the function invoked by SME to inform the result of BMPS
5846 request issued by HDD
5847
5848 \param - callbackcontext - Pointer to cookie
5849 status - result of request
5850
5851 \return - None
5852
5853--------------------------------------------------------------------------*/
5854void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5855{
5856
5857 struct completion *completion_var = (struct completion*) callbackContext;
5858
Arif Hussain6d2a3322013-11-17 19:50:10 -08005859 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005860 if(completion_var != NULL)
5861 {
5862 complete(completion_var);
5863 }
5864}
5865
5866/**---------------------------------------------------------------------------
5867
5868 \brief hdd_get_cfg_file_size() -
5869
5870 This function reads the configuration file using the request firmware
5871 API and returns the configuration file size.
5872
5873 \param - pCtx - Pointer to the adapter .
5874 - pFileName - Pointer to the file name.
5875 - pBufSize - Pointer to the buffer size.
5876
5877 \return - 0 for success, non zero for failure
5878
5879 --------------------------------------------------------------------------*/
5880
5881VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5882{
5883 int status;
5884 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5885
5886 ENTER();
5887
5888 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5889
5890 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5891 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5892 status = VOS_STATUS_E_FAILURE;
5893 }
5894 else {
5895 *pBufSize = pHddCtx->fw->size;
5896 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5897 release_firmware(pHddCtx->fw);
5898 pHddCtx->fw = NULL;
5899 }
5900
5901 EXIT();
5902 return VOS_STATUS_SUCCESS;
5903}
5904
5905/**---------------------------------------------------------------------------
5906
5907 \brief hdd_read_cfg_file() -
5908
5909 This function reads the configuration file using the request firmware
5910 API and returns the cfg data and the buffer size of the configuration file.
5911
5912 \param - pCtx - Pointer to the adapter .
5913 - pFileName - Pointer to the file name.
5914 - pBuffer - Pointer to the data buffer.
5915 - pBufSize - Pointer to the buffer size.
5916
5917 \return - 0 for success, non zero for failure
5918
5919 --------------------------------------------------------------------------*/
5920
5921VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5922 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5923{
5924 int status;
5925 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5926
5927 ENTER();
5928
5929 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5930
5931 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5932 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5933 return VOS_STATUS_E_FAILURE;
5934 }
5935 else {
5936 if(*pBufSize != pHddCtx->fw->size) {
5937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5938 "file size", __func__);
5939 release_firmware(pHddCtx->fw);
5940 pHddCtx->fw = NULL;
5941 return VOS_STATUS_E_FAILURE;
5942 }
5943 else {
5944 if(pBuffer) {
5945 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5946 }
5947 release_firmware(pHddCtx->fw);
5948 pHddCtx->fw = NULL;
5949 }
5950 }
5951
5952 EXIT();
5953
5954 return VOS_STATUS_SUCCESS;
5955}
5956
5957/**---------------------------------------------------------------------------
5958
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305959 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005960
5961 This function sets the user specified mac address using
5962 the command ifconfig wlanX hw ether <mac adress>.
5963
5964 \param - dev - Pointer to the net device.
5965 - addr - Pointer to the sockaddr.
5966 \return - 0 for success, non zero for failure
5967
5968 --------------------------------------------------------------------------*/
5969
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305970static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005971{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305972 hdd_adapter_t *pAdapter;
5973 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005974 struct sockaddr *psta_mac_addr = addr;
5975 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305976 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005977
5978 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305979 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5980 if (NULL == pAdapter)
5981 {
5982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5983 "%s: Adapter is NULL",__func__);
5984 return -EINVAL;
5985 }
5986 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5987 ret = wlan_hdd_validate_context(pHddCtx);
5988 if (0 != ret)
5989 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305990 return ret;
5991 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005992
5993 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5995
5996 EXIT();
5997 return halStatus;
5998}
5999
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306000/**---------------------------------------------------------------------------
6001
6002 \brief hdd_set_mac_address() -
6003
6004 Wrapper function to protect __hdd_set_mac_address() function from ssr
6005
6006 \param - dev - Pointer to the net device.
6007 - addr - Pointer to the sockaddr.
6008 \return - 0 for success, non zero for failure
6009
6010 --------------------------------------------------------------------------*/
6011static int hdd_set_mac_address(struct net_device *dev, void *addr)
6012{
6013 int ret;
6014
6015 vos_ssr_protect(__func__);
6016 ret = __hdd_set_mac_address(dev, addr);
6017 vos_ssr_unprotect(__func__);
6018
6019 return ret;
6020}
6021
Jeff Johnson295189b2012-06-20 16:38:30 -07006022tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6023{
6024 int i;
6025 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6026 {
Abhishek Singheb183782014-02-06 13:37:21 +05306027 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 break;
6029 }
6030
6031 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6032 return NULL;
6033
6034 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6035 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6036}
6037
6038void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6039{
6040 int i;
6041 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6042 {
6043 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6044 {
6045 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6046 break;
6047 }
6048 }
6049 return;
6050}
6051
6052#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6053 static struct net_device_ops wlan_drv_ops = {
6054 .ndo_open = hdd_open,
6055 .ndo_stop = hdd_stop,
6056 .ndo_uninit = hdd_uninit,
6057 .ndo_start_xmit = hdd_hard_start_xmit,
6058 .ndo_tx_timeout = hdd_tx_timeout,
6059 .ndo_get_stats = hdd_stats,
6060 .ndo_do_ioctl = hdd_ioctl,
6061 .ndo_set_mac_address = hdd_set_mac_address,
6062 .ndo_select_queue = hdd_select_queue,
6063#ifdef WLAN_FEATURE_PACKET_FILTERING
6064#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6065 .ndo_set_rx_mode = hdd_set_multicast_list,
6066#else
6067 .ndo_set_multicast_list = hdd_set_multicast_list,
6068#endif //LINUX_VERSION_CODE
6069#endif
6070 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 static struct net_device_ops wlan_mon_drv_ops = {
6072 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306073 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 .ndo_uninit = hdd_uninit,
6075 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6076 .ndo_tx_timeout = hdd_tx_timeout,
6077 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306078 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 .ndo_set_mac_address = hdd_set_mac_address,
6080 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306081
Jeff Johnson295189b2012-06-20 16:38:30 -07006082#endif
6083
6084void hdd_set_station_ops( struct net_device *pWlanDev )
6085{
6086#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006087 pWlanDev->netdev_ops = &wlan_drv_ops;
6088#else
6089 pWlanDev->open = hdd_open;
6090 pWlanDev->stop = hdd_stop;
6091 pWlanDev->uninit = hdd_uninit;
6092 pWlanDev->hard_start_xmit = NULL;
6093 pWlanDev->tx_timeout = hdd_tx_timeout;
6094 pWlanDev->get_stats = hdd_stats;
6095 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006096 pWlanDev->set_mac_address = hdd_set_mac_address;
6097#endif
6098}
6099
Katya Nigam1fd24402015-02-16 14:52:19 +05306100void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6101{
6102 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6103 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6104 #else
6105 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6106 #endif
6107}
6108
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006109static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006110{
6111 struct net_device *pWlanDev = NULL;
6112 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006113 /*
6114 * cfg80211 initialization and registration....
6115 */
6116 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6117
Jeff Johnson295189b2012-06-20 16:38:30 -07006118 if(pWlanDev != NULL)
6119 {
6120
6121 //Save the pointer to the net_device in the HDD adapter
6122 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6123
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6125
6126 pAdapter->dev = pWlanDev;
6127 pAdapter->pHddCtx = pHddCtx;
6128 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306129 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006130
6131 init_completion(&pAdapter->session_open_comp_var);
6132 init_completion(&pAdapter->session_close_comp_var);
6133 init_completion(&pAdapter->disconnect_comp_var);
6134 init_completion(&pAdapter->linkup_event_var);
6135 init_completion(&pAdapter->cancel_rem_on_chan_var);
6136 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306137 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6139 init_completion(&pAdapter->offchannel_tx_event);
6140#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006141 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006142#ifdef FEATURE_WLAN_TDLS
6143 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006144 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006145 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306146 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006147#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006148 init_completion(&pHddCtx->mc_sus_event_var);
6149 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306150 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006151 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006152 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006153
Rajeev79dbe4c2013-10-05 11:03:42 +05306154#ifdef FEATURE_WLAN_BATCH_SCAN
6155 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6156 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6157 pAdapter->pBatchScanRsp = NULL;
6158 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006159 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006160 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306161 mutex_init(&pAdapter->hdd_batch_scan_lock);
6162#endif
6163
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 pAdapter->isLinkUpSvcNeeded = FALSE;
6165 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6166 //Init the net_device structure
6167 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6168
6169 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6170 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6171 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6172 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6173
6174 hdd_set_station_ops( pAdapter->dev );
6175
6176 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6178 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6179 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006180 /* set pWlanDev's parent to underlying device */
6181 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006182
6183 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006184 }
6185
6186 return pAdapter;
6187}
6188
6189VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6190{
6191 struct net_device *pWlanDev = pAdapter->dev;
6192 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6193 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6194 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6195
6196 if( rtnl_lock_held )
6197 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006198 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6200 {
6201 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6202 return VOS_STATUS_E_FAILURE;
6203 }
6204 }
6205 if (register_netdevice(pWlanDev))
6206 {
6207 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6208 return VOS_STATUS_E_FAILURE;
6209 }
6210 }
6211 else
6212 {
6213 if(register_netdev(pWlanDev))
6214 {
6215 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6216 return VOS_STATUS_E_FAILURE;
6217 }
6218 }
6219 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6220
6221 return VOS_STATUS_SUCCESS;
6222}
6223
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006224static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006225{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006226 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006227
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006228 if (NULL == pAdapter)
6229 {
6230 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6231 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006233
6234 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6235 {
6236 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6237 return eHAL_STATUS_NOT_INITIALIZED;
6238 }
6239
6240 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6241
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006242#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006243 /* need to make sure all of our scheduled work has completed.
6244 * This callback is called from MC thread context, so it is safe to
6245 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006246 *
6247 * Even though this is called from MC thread context, if there is a faulty
6248 * work item in the system, that can hang this call forever. So flushing
6249 * this global work queue is not safe; and now we make sure that
6250 * individual work queues are stopped correctly. But the cancel work queue
6251 * is a GPL only API, so the proprietary version of the driver would still
6252 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006253 */
6254 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006255#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006256
6257 /* We can be blocked while waiting for scheduled work to be
6258 * flushed, and the adapter structure can potentially be freed, in
6259 * which case the magic will have been reset. So make sure the
6260 * magic is still good, and hence the adapter structure is still
6261 * valid, before signaling completion */
6262 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6263 {
6264 complete(&pAdapter->session_close_comp_var);
6265 }
6266
Jeff Johnson295189b2012-06-20 16:38:30 -07006267 return eHAL_STATUS_SUCCESS;
6268}
6269
6270VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6271{
6272 struct net_device *pWlanDev = pAdapter->dev;
6273 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6274 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6275 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6276 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306277 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006278
6279 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006280 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006281 //Open a SME session for future operation
6282 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006283 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6285 {
6286 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006287 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 halStatus, halStatus );
6289 status = VOS_STATUS_E_FAILURE;
6290 goto error_sme_open;
6291 }
6292
6293 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306294 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 &pAdapter->session_open_comp_var,
6296 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306297 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 {
6299 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306300 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006301 status = VOS_STATUS_E_FAILURE;
6302 goto error_sme_open;
6303 }
6304
6305 // Register wireless extensions
6306 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6307 {
6308 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006309 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 halStatus, halStatus );
6311 status = VOS_STATUS_E_FAILURE;
6312 goto error_register_wext;
6313 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306314
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306316 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6317 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6318 #else
6319 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6320 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006321
6322 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306323 hddLog(VOS_TRACE_LEVEL_INFO,
6324 "%s: Set HDD connState to eConnectionState_NotConnected",
6325 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006326 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6327
6328 //Set the default operation channel
6329 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6330
6331 /* Make the default Auth Type as OPEN*/
6332 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6333
6334 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6335 {
6336 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006337 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 status, status );
6339 goto error_init_txrx;
6340 }
6341
6342 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6343
6344 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6345 {
6346 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006347 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 status, status );
6349 goto error_wmm_init;
6350 }
6351
6352 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6353
6354 return VOS_STATUS_SUCCESS;
6355
6356error_wmm_init:
6357 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6358 hdd_deinit_tx_rx(pAdapter);
6359error_init_txrx:
6360 hdd_UnregisterWext(pWlanDev);
6361error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006362 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 {
6364 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006365 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006367 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006368 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306369 unsigned long rc;
6370
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306372 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006374 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306375 if (rc <= 0)
6376 hddLog(VOS_TRACE_LEVEL_ERROR,
6377 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006378 }
6379}
6380error_sme_open:
6381 return status;
6382}
6383
Jeff Johnson295189b2012-06-20 16:38:30 -07006384void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6385{
6386 hdd_cfg80211_state_t *cfgState;
6387
6388 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6389
6390 if( NULL != cfgState->buf )
6391 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306392 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6394 rc = wait_for_completion_interruptible_timeout(
6395 &pAdapter->tx_action_cnf_event,
6396 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306397 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006398 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306400 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6401 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006402 }
6403 }
6404 return;
6405}
Jeff Johnson295189b2012-06-20 16:38:30 -07006406
c_hpothu002231a2015-02-05 14:58:51 +05306407void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006408{
6409 ENTER();
6410 switch ( pAdapter->device_mode )
6411 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306412 case WLAN_HDD_IBSS:
6413 {
6414 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6415 {
6416 hdd_ibss_deinit_tx_rx( pAdapter );
6417 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6418 }
6419 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 case WLAN_HDD_INFRA_STATION:
6421 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006422 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 {
6424 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6425 {
6426 hdd_deinit_tx_rx( pAdapter );
6427 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6428 }
6429
6430 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6431 {
6432 hdd_wmm_adapter_close( pAdapter );
6433 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6434 }
6435
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006437 break;
6438 }
6439
6440 case WLAN_HDD_SOFTAP:
6441 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306443
6444 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6445 {
6446 hdd_wmm_adapter_close( pAdapter );
6447 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6448 }
6449
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006451
c_hpothu002231a2015-02-05 14:58:51 +05306452 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006454 break;
6455 }
6456
6457 case WLAN_HDD_MONITOR:
6458 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6460 {
6461 hdd_deinit_tx_rx( pAdapter );
6462 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 break;
6465 }
6466
6467
6468 default:
6469 break;
6470 }
6471
6472 EXIT();
6473}
6474
6475void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6476{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006477 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306478
6479 ENTER();
6480 if (NULL == pAdapter)
6481 {
6482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6483 "%s: HDD adapter is Null", __func__);
6484 return;
6485 }
6486
6487 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006488
Rajeev79dbe4c2013-10-05 11:03:42 +05306489#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306490 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6491 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006492 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306493 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6494 )
6495 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006496 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306497 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006498 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6499 {
6500 hdd_deinit_batch_scan(pAdapter);
6501 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306502 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006503 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306504#endif
6505
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6507 if( rtnl_held )
6508 {
6509 unregister_netdevice(pWlanDev);
6510 }
6511 else
6512 {
6513 unregister_netdev(pWlanDev);
6514 }
6515 // note that the pAdapter is no longer valid at this point
6516 // since the memory has been reclaimed
6517 }
6518
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306519 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006520}
6521
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006522void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6523{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306524 VOS_STATUS status;
6525 hdd_adapter_t *pAdapter = NULL;
6526 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006527
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306528 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006529
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306530 /*loop through all adapters.*/
6531 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006532 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306533 pAdapter = pAdapterNode->pAdapter;
6534 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6535 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006536
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306537 { // we skip this registration for modes other than STA and P2P client modes.
6538 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6539 pAdapterNode = pNext;
6540 continue;
6541 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006542
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306543 //Apply Dynamic DTIM For P2P
6544 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6545 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6546 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6547 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6548 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6549 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6550 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6551 (eConnectionState_Associated ==
6552 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6553 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6554 {
6555 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006556
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306557 powerRequest.uIgnoreDTIM = 1;
6558 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6559
6560 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6561 {
6562 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6563 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6564 }
6565 else
6566 {
6567 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6568 }
6569
6570 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6571 * specified during Enter/Exit BMPS when LCD off*/
6572 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6573 NULL, eANI_BOOLEAN_FALSE);
6574 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6575 NULL, eANI_BOOLEAN_FALSE);
6576
6577 /* switch to the DTIM specified in cfg.ini */
6578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6579 "Switch to DTIM %d", powerRequest.uListenInterval);
6580 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6581 break;
6582
6583 }
6584
6585 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6586 pAdapterNode = pNext;
6587 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006588}
6589
6590void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6591{
6592 /*Switch back to DTIM 1*/
6593 tSirSetPowerParamsReq powerRequest = { 0 };
6594
6595 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6596 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006597 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006598
6599 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6600 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6601 NULL, eANI_BOOLEAN_FALSE);
6602 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6603 NULL, eANI_BOOLEAN_FALSE);
6604
6605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6606 "Switch to DTIM%d",powerRequest.uListenInterval);
6607 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6608
6609}
6610
Jeff Johnson295189b2012-06-20 16:38:30 -07006611VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6612{
6613 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306614 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6615 {
6616 hddLog( LOGE, FL("Wlan Unload in progress"));
6617 return VOS_STATUS_E_PERM;
6618 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006619 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6620 {
6621 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6622 }
6623
6624 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6625 {
6626 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6627 }
6628
6629 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6630 {
6631 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6632 }
6633
6634 return status;
6635}
6636
6637VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6638{
6639 hdd_adapter_t *pAdapter = NULL;
6640 eHalStatus halStatus;
6641 VOS_STATUS status = VOS_STATUS_E_INVAL;
6642 v_BOOL_t disableBmps = FALSE;
6643 v_BOOL_t disableImps = FALSE;
6644
6645 switch(session_type)
6646 {
6647 case WLAN_HDD_INFRA_STATION:
6648 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006649 case WLAN_HDD_P2P_CLIENT:
6650 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 //Exit BMPS -> Is Sta/P2P Client is already connected
6652 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6653 if((NULL != pAdapter)&&
6654 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6655 {
6656 disableBmps = TRUE;
6657 }
6658
6659 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6660 if((NULL != pAdapter)&&
6661 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6662 {
6663 disableBmps = TRUE;
6664 }
6665
6666 //Exit both Bmps and Imps incase of Go/SAP Mode
6667 if((WLAN_HDD_SOFTAP == session_type) ||
6668 (WLAN_HDD_P2P_GO == session_type))
6669 {
6670 disableBmps = TRUE;
6671 disableImps = TRUE;
6672 }
6673
6674 if(TRUE == disableImps)
6675 {
6676 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6677 {
6678 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6679 }
6680 }
6681
6682 if(TRUE == disableBmps)
6683 {
6684 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6685 {
6686 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6687
6688 if(eHAL_STATUS_SUCCESS != halStatus)
6689 {
6690 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006691 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006692 VOS_ASSERT(0);
6693 return status;
6694 }
6695 }
6696
6697 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6698 {
6699 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6700
6701 if(eHAL_STATUS_SUCCESS != halStatus)
6702 {
6703 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006704 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006705 VOS_ASSERT(0);
6706 return status;
6707 }
6708 }
6709 }
6710
6711 if((TRUE == disableBmps) ||
6712 (TRUE == disableImps))
6713 {
6714 /* Now, get the chip into Full Power now */
6715 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6716 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6717 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6718
6719 if(halStatus != eHAL_STATUS_SUCCESS)
6720 {
6721 if(halStatus == eHAL_STATUS_PMC_PENDING)
6722 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306723 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006724 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306725 ret = wait_for_completion_interruptible_timeout(
6726 &pHddCtx->full_pwr_comp_var,
6727 msecs_to_jiffies(1000));
6728 if (ret <= 0)
6729 {
6730 hddLog(VOS_TRACE_LEVEL_ERROR,
6731 "%s: wait on full_pwr_comp_var failed %ld",
6732 __func__, ret);
6733 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006734 }
6735 else
6736 {
6737 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006738 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006739 VOS_ASSERT(0);
6740 return status;
6741 }
6742 }
6743
6744 status = VOS_STATUS_SUCCESS;
6745 }
6746
6747 break;
6748 }
6749 return status;
6750}
Katya Nigame7b69a82015-04-28 15:24:06 +05306751void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6752 {
6753 hdd_mon_ctx_t *pMonCtx = NULL;
6754 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6755
6756 pMonCtx->state = 0;
6757 pMonCtx->ChannelNo = 1;
6758 pMonCtx->ChannelBW = 20;
6759 pMonCtx->crcCheckEnabled = 0;
6760 pMonCtx->typeSubtypeBitmap = 0xFFFFFFFFFFFF;
6761 pMonCtx->is80211to803ConReq = 0;
6762 pMonCtx->numOfMacFilters = 0;
6763 }
6764
Jeff Johnson295189b2012-06-20 16:38:30 -07006765
6766hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006767 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 tANI_U8 rtnl_held )
6769{
6770 hdd_adapter_t *pAdapter = NULL;
6771 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6772 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6773 VOS_STATUS exitbmpsStatus;
6774
Arif Hussain6d2a3322013-11-17 19:50:10 -08006775 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006776
Nirav Shah436658f2014-02-28 17:05:45 +05306777 if(macAddr == NULL)
6778 {
6779 /* Not received valid macAddr */
6780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6781 "%s:Unable to add virtual intf: Not able to get"
6782 "valid mac address",__func__);
6783 return NULL;
6784 }
6785
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 //Disable BMPS incase of Concurrency
6787 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6788
6789 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6790 {
6791 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306792 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006793 VOS_ASSERT(0);
6794 return NULL;
6795 }
6796
6797 switch(session_type)
6798 {
6799 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006800 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006801 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006802 {
6803 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6804
6805 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306806 {
6807 hddLog(VOS_TRACE_LEVEL_FATAL,
6808 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006809 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306810 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006811
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306812#ifdef FEATURE_WLAN_TDLS
6813 /* A Mutex Lock is introduced while changing/initializing the mode to
6814 * protect the concurrent access for the Adapters by TDLS module.
6815 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306816 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306817#endif
6818
Jeff Johnsone7245742012-09-05 17:12:55 -07006819 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6820 NL80211_IFTYPE_P2P_CLIENT:
6821 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006822
Jeff Johnson295189b2012-06-20 16:38:30 -07006823 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306824#ifdef FEATURE_WLAN_TDLS
6825 mutex_unlock(&pHddCtx->tdls_lock);
6826#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306827
6828 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006829 if( VOS_STATUS_SUCCESS != status )
6830 goto err_free_netdev;
6831
6832 status = hdd_register_interface( pAdapter, rtnl_held );
6833 if( VOS_STATUS_SUCCESS != status )
6834 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306835#ifdef FEATURE_WLAN_TDLS
6836 mutex_lock(&pHddCtx->tdls_lock);
6837#endif
c_hpothu002231a2015-02-05 14:58:51 +05306838 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306839#ifdef FEATURE_WLAN_TDLS
6840 mutex_unlock(&pHddCtx->tdls_lock);
6841#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 goto err_free_netdev;
6843 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306844
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306845 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306846 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306847
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306848#ifdef WLAN_NS_OFFLOAD
6849 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306850 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306851#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006852 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306853 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 netif_tx_disable(pAdapter->dev);
6855 //netif_tx_disable(pWlanDev);
6856 netif_carrier_off(pAdapter->dev);
6857
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306858 if (WLAN_HDD_P2P_CLIENT == session_type ||
6859 WLAN_HDD_P2P_DEVICE == session_type)
6860 {
6861 /* Initialize the work queue to defer the
6862 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306863 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306864 hdd_p2p_roc_work_queue);
6865 }
6866
Jeff Johnson295189b2012-06-20 16:38:30 -07006867 break;
6868 }
6869
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 case WLAN_HDD_SOFTAP:
6872 {
6873 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6874 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306875 {
6876 hddLog(VOS_TRACE_LEVEL_FATAL,
6877 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306879 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006880
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6882 NL80211_IFTYPE_AP:
6883 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006884 pAdapter->device_mode = session_type;
6885
6886 status = hdd_init_ap_mode(pAdapter);
6887 if( VOS_STATUS_SUCCESS != status )
6888 goto err_free_netdev;
6889
6890 status = hdd_register_hostapd( pAdapter, rtnl_held );
6891 if( VOS_STATUS_SUCCESS != status )
6892 {
c_hpothu002231a2015-02-05 14:58:51 +05306893 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 goto err_free_netdev;
6895 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306896 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006897 netif_tx_disable(pAdapter->dev);
6898 netif_carrier_off(pAdapter->dev);
6899
6900 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306901
6902 if (WLAN_HDD_P2P_GO == session_type)
6903 {
6904 /* Initialize the work queue to
6905 * defer the back to back RoC request */
6906 INIT_DELAYED_WORK(&pAdapter->roc_work,
6907 hdd_p2p_roc_work_queue);
6908 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006909 break;
6910 }
6911 case WLAN_HDD_MONITOR:
6912 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006913 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6914 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306915 {
6916 hddLog(VOS_TRACE_LEVEL_FATAL,
6917 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006918 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306919 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006920
Katya Nigame7b69a82015-04-28 15:24:06 +05306921 // Register wireless extensions
6922 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6923 {
6924 hddLog(VOS_TRACE_LEVEL_FATAL,
6925 "hdd_register_wext() failed with status code %08d [x%08x]",
6926 status, status );
6927 status = VOS_STATUS_E_FAILURE;
6928 }
6929
Jeff Johnson295189b2012-06-20 16:38:30 -07006930 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6931 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006932#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6933 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6934#else
6935 pAdapter->dev->open = hdd_mon_open;
6936 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05306937 pAdapter->dev->stop = hdd_mon_stop;
6938 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006939#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05306940 status = hdd_register_interface( pAdapter, rtnl_held );
6941 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 hdd_init_tx_rx( pAdapter );
6943 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05306944 //Stop the Interface TX queue.
6945 netif_tx_disable(pAdapter->dev);
6946 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006947 }
6948 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 case WLAN_HDD_FTM:
6950 {
6951 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6952
6953 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306954 {
6955 hddLog(VOS_TRACE_LEVEL_FATAL,
6956 FL("failed to allocate adapter for session %d"), session_type);
6957 return NULL;
6958 }
6959
Jeff Johnson295189b2012-06-20 16:38:30 -07006960 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6961 * message while loading driver in FTM mode. */
6962 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6963 pAdapter->device_mode = session_type;
6964 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306965
6966 hdd_init_tx_rx( pAdapter );
6967
6968 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306969 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306970 netif_tx_disable(pAdapter->dev);
6971 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006972 }
6973 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006974 default:
6975 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306976 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6977 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006978 VOS_ASSERT(0);
6979 return NULL;
6980 }
6981 }
6982
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 if( VOS_STATUS_SUCCESS == status )
6984 {
6985 //Add it to the hdd's session list.
6986 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6987 if( NULL == pHddAdapterNode )
6988 {
6989 status = VOS_STATUS_E_NOMEM;
6990 }
6991 else
6992 {
6993 pHddAdapterNode->pAdapter = pAdapter;
6994 status = hdd_add_adapter_back ( pHddCtx,
6995 pHddAdapterNode );
6996 }
6997 }
6998
6999 if( VOS_STATUS_SUCCESS != status )
7000 {
7001 if( NULL != pAdapter )
7002 {
7003 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7004 pAdapter = NULL;
7005 }
7006 if( NULL != pHddAdapterNode )
7007 {
7008 vos_mem_free( pHddAdapterNode );
7009 }
7010
7011 goto resume_bmps;
7012 }
7013
7014 if(VOS_STATUS_SUCCESS == status)
7015 {
7016 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7017
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007018 //Initialize the WoWL service
7019 if(!hdd_init_wowl(pAdapter))
7020 {
7021 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7022 goto err_free_netdev;
7023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 return pAdapter;
7026
7027err_free_netdev:
7028 free_netdev(pAdapter->dev);
7029 wlan_hdd_release_intf_addr( pHddCtx,
7030 pAdapter->macAddressCurrent.bytes );
7031
7032resume_bmps:
7033 //If bmps disabled enable it
7034 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7035 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307036 if (pHddCtx->hdd_wlan_suspended)
7037 {
7038 hdd_set_pwrparams(pHddCtx);
7039 }
7040 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007041 }
7042 return NULL;
7043}
7044
7045VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7046 tANI_U8 rtnl_held )
7047{
7048 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7049 VOS_STATUS status;
7050
7051 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7052 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307053 {
7054 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7055 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307057 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007058
7059 while ( pCurrent->pAdapter != pAdapter )
7060 {
7061 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7062 if( VOS_STATUS_SUCCESS != status )
7063 break;
7064
7065 pCurrent = pNext;
7066 }
7067 pAdapterNode = pCurrent;
7068 if( VOS_STATUS_SUCCESS == status )
7069 {
7070 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7071 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307072
7073#ifdef FEATURE_WLAN_TDLS
7074
7075 /* A Mutex Lock is introduced while changing/initializing the mode to
7076 * protect the concurrent access for the Adapters by TDLS module.
7077 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307078 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307079#endif
7080
Jeff Johnson295189b2012-06-20 16:38:30 -07007081 hdd_remove_adapter( pHddCtx, pAdapterNode );
7082 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007083 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007084
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307085#ifdef FEATURE_WLAN_TDLS
7086 mutex_unlock(&pHddCtx->tdls_lock);
7087#endif
7088
Jeff Johnson295189b2012-06-20 16:38:30 -07007089
7090 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307091 if ((!vos_concurrent_open_sessions_running()) &&
7092 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7093 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007094 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307095 if (pHddCtx->hdd_wlan_suspended)
7096 {
7097 hdd_set_pwrparams(pHddCtx);
7098 }
7099 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007100 }
7101
7102 return VOS_STATUS_SUCCESS;
7103 }
7104
7105 return VOS_STATUS_E_FAILURE;
7106}
7107
7108VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7109{
7110 hdd_adapter_list_node_t *pHddAdapterNode;
7111 VOS_STATUS status;
7112
7113 ENTER();
7114
7115 do
7116 {
7117 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7118 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7119 {
7120 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7121 vos_mem_free( pHddAdapterNode );
7122 }
7123 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7124
7125 EXIT();
7126
7127 return VOS_STATUS_SUCCESS;
7128}
7129
7130void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7131{
7132 v_U8_t addIE[1] = {0};
7133
7134 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7135 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7136 eANI_BOOLEAN_FALSE) )
7137 {
7138 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007139 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 }
7141
7142 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7143 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7144 eANI_BOOLEAN_FALSE) )
7145 {
7146 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007147 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007148 }
7149
7150 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7151 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7152 eANI_BOOLEAN_FALSE) )
7153 {
7154 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007155 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007156 }
7157}
7158
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307159VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7160 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007161{
7162 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7163 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307164 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007165 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307166 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307167 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007168
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307169 if (pHddCtx->isLogpInProgress) {
7170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7171 "%s:LOGP in Progress. Ignore!!!",__func__);
7172 return VOS_STATUS_E_FAILURE;
7173 }
7174
Jeff Johnson295189b2012-06-20 16:38:30 -07007175 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307176
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307177 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007178 switch(pAdapter->device_mode)
7179 {
7180 case WLAN_HDD_INFRA_STATION:
7181 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007182 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307183 {
7184 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7185 if( hdd_connIsConnected(pstation) ||
7186 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007187 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307188#ifdef FEATURE_WLAN_TDLS
7189 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307190 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307191 mutex_unlock(&pHddCtx->tdls_lock);
7192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007193 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7194 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7195 pAdapter->sessionId,
7196 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7197 else
7198 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7199 pAdapter->sessionId,
7200 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7201 //success implies disconnect command got queued up successfully
7202 if(halStatus == eHAL_STATUS_SUCCESS)
7203 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307204 ret = wait_for_completion_interruptible_timeout(
7205 &pAdapter->disconnect_comp_var,
7206 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7207 if (ret <= 0)
7208 {
7209 hddLog(VOS_TRACE_LEVEL_ERROR,
7210 "%s: wait on disconnect_comp_var failed %ld",
7211 __func__, ret);
7212 }
7213 }
7214 else
7215 {
7216 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7217 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 }
7219 memset(&wrqu, '\0', sizeof(wrqu));
7220 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7221 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7222 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7223 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307224 else if(pstation->conn_info.connState ==
7225 eConnectionState_Disconnecting)
7226 {
7227 ret = wait_for_completion_interruptible_timeout(
7228 &pAdapter->disconnect_comp_var,
7229 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7230 if (ret <= 0)
7231 {
7232 hddLog(VOS_TRACE_LEVEL_ERROR,
7233 FL("wait on disconnect_comp_var failed %ld"), ret);
7234 }
7235 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307236 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307238 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307239 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007240 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307241 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7242 {
7243 while (pAdapter->is_roc_inprogress)
7244 {
7245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7246 "%s: ROC in progress for session %d!!!",
7247 __func__, pAdapter->sessionId);
7248 // waiting for ROC to expire
7249 msleep(500);
7250 /* In GO present case , if retry exceeds 3,
7251 it means something went wrong. */
7252 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7253 {
7254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7255 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307256 if (eHAL_STATUS_SUCCESS !=
7257 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7258 pAdapter->sessionId ))
7259 {
7260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7261 FL("Failed to Cancel Remain on Channel"));
7262 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307263 wait_for_completion_interruptible_timeout(
7264 &pAdapter->cancel_rem_on_chan_var,
7265 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7266 break;
7267 }
7268 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307269 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307270 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307271#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307272 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307273#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307274
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307275 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307276
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307277 /* It is possible that the caller of this function does not
7278 * wish to close the session
7279 */
7280 if (VOS_TRUE == bCloseSession &&
7281 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 {
7283 INIT_COMPLETION(pAdapter->session_close_comp_var);
7284 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307285 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7286 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007287 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307288 unsigned long ret;
7289
Jeff Johnson295189b2012-06-20 16:38:30 -07007290 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307291 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307292 &pAdapter->session_close_comp_var,
7293 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307294 if ( 0 >= ret)
7295 {
7296 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307297 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307298 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 }
7300 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307301 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007302 break;
7303
7304 case WLAN_HDD_SOFTAP:
7305 case WLAN_HDD_P2P_GO:
7306 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307307 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7308 while (pAdapter->is_roc_inprogress) {
7309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7310 "%s: ROC in progress for session %d!!!",
7311 __func__, pAdapter->sessionId);
7312 msleep(500);
7313 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7315 "%s: ROC completion is not received.!!!", __func__);
7316 WLANSAP_CancelRemainOnChannel(
7317 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7318 wait_for_completion_interruptible_timeout(
7319 &pAdapter->cancel_rem_on_chan_var,
7320 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7321 break;
7322 }
7323 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307324
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307325 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307326 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 mutex_lock(&pHddCtx->sap_lock);
7328 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7329 {
7330 VOS_STATUS status;
7331 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7332
7333 //Stop Bss.
7334 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7335 if (VOS_IS_STATUS_SUCCESS(status))
7336 {
7337 hdd_hostapd_state_t *pHostapdState =
7338 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7339
7340 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7341
7342 if (!VOS_IS_STATUS_SUCCESS(status))
7343 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307344 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7345 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007346 }
7347 }
7348 else
7349 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007350 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007351 }
7352 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307353 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007354
7355 if (eHAL_STATUS_FAILURE ==
7356 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7357 0, NULL, eANI_BOOLEAN_FALSE))
7358 {
7359 hddLog(LOGE,
7360 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007361 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 }
7363
7364 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7365 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7366 eANI_BOOLEAN_FALSE) )
7367 {
7368 hddLog(LOGE,
7369 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7370 }
7371
7372 // Reset WNI_CFG_PROBE_RSP Flags
7373 wlan_hdd_reset_prob_rspies(pAdapter);
7374 kfree(pAdapter->sessionCtx.ap.beacon);
7375 pAdapter->sessionCtx.ap.beacon = NULL;
7376 }
7377 mutex_unlock(&pHddCtx->sap_lock);
7378 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007379
Jeff Johnson295189b2012-06-20 16:38:30 -07007380 case WLAN_HDD_MONITOR:
7381 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007382
Jeff Johnson295189b2012-06-20 16:38:30 -07007383 default:
7384 break;
7385 }
7386
7387 EXIT();
7388 return VOS_STATUS_SUCCESS;
7389}
7390
7391VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7392{
7393 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7394 VOS_STATUS status;
7395 hdd_adapter_t *pAdapter;
7396
7397 ENTER();
7398
7399 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7400
7401 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7402 {
7403 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007404
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307405 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007406
7407 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7408 pAdapterNode = pNext;
7409 }
7410
7411 EXIT();
7412
7413 return VOS_STATUS_SUCCESS;
7414}
7415
Rajeev Kumarf999e582014-01-09 17:33:29 -08007416
7417#ifdef FEATURE_WLAN_BATCH_SCAN
7418/**---------------------------------------------------------------------------
7419
7420 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7421 structures
7422
7423 \param - pAdapter Pointer to HDD adapter
7424
7425 \return - None
7426
7427 --------------------------------------------------------------------------*/
7428void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7429{
7430 tHddBatchScanRsp *pNode;
7431 tHddBatchScanRsp *pPrev;
7432
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307433 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007434 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307435 hddLog(VOS_TRACE_LEVEL_ERROR,
7436 "%s: Adapter context is Null", __func__);
7437 return;
7438 }
7439
7440 pNode = pAdapter->pBatchScanRsp;
7441 while (pNode)
7442 {
7443 pPrev = pNode;
7444 pNode = pNode->pNext;
7445 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007446 }
7447
7448 pAdapter->pBatchScanRsp = NULL;
7449 pAdapter->numScanList = 0;
7450 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7451 pAdapter->prev_batch_id = 0;
7452
7453 return;
7454}
7455#endif
7456
7457
Jeff Johnson295189b2012-06-20 16:38:30 -07007458VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7459{
7460 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7461 VOS_STATUS status;
7462 hdd_adapter_t *pAdapter;
7463
7464 ENTER();
7465
7466 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7467
7468 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7469 {
7470 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307471 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007472 netif_tx_disable(pAdapter->dev);
7473 netif_carrier_off(pAdapter->dev);
7474
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007475 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7476
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307478
Katya Nigam1fd24402015-02-16 14:52:19 +05307479 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7480 hdd_ibss_deinit_tx_rx(pAdapter);
7481
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307482 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7483
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307484 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7485 {
7486 hdd_wmm_adapter_close( pAdapter );
7487 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7488 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007489
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307490 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7491 {
7492 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7493 }
7494
Rajeev Kumarf999e582014-01-09 17:33:29 -08007495#ifdef FEATURE_WLAN_BATCH_SCAN
7496 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7497 {
7498 hdd_deinit_batch_scan(pAdapter);
7499 }
7500#endif
7501
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307502#ifdef FEATURE_WLAN_TDLS
7503 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307504 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307505 mutex_unlock(&pHddCtx->tdls_lock);
7506#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7508 pAdapterNode = pNext;
7509 }
7510
7511 EXIT();
7512
7513 return VOS_STATUS_SUCCESS;
7514}
7515
7516VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7517{
7518 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7519 VOS_STATUS status;
7520 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307521 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007522
7523 ENTER();
7524
7525 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7526
7527 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7528 {
7529 pAdapter = pAdapterNode->pAdapter;
7530
Kumar Anand82c009f2014-05-29 00:29:42 -07007531 hdd_wmm_init( pAdapter );
7532
Jeff Johnson295189b2012-06-20 16:38:30 -07007533 switch(pAdapter->device_mode)
7534 {
7535 case WLAN_HDD_INFRA_STATION:
7536 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007537 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307538
7539 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7540
Jeff Johnson295189b2012-06-20 16:38:30 -07007541 hdd_init_station_mode(pAdapter);
7542 /* Open the gates for HDD to receive Wext commands */
7543 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007544 pHddCtx->scan_info.mScanPending = FALSE;
7545 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007546
7547 //Trigger the initial scan
7548 hdd_wlan_initial_scan(pAdapter);
7549
7550 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307551 if (eConnectionState_Associated == connState ||
7552 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007553 {
7554 union iwreq_data wrqu;
7555 memset(&wrqu, '\0', sizeof(wrqu));
7556 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7557 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7558 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007559 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007560
Jeff Johnson295189b2012-06-20 16:38:30 -07007561 /* indicate disconnected event to nl80211 */
7562 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7563 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007564 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307565 else if (eConnectionState_Connecting == connState)
7566 {
7567 /*
7568 * Indicate connect failure to supplicant if we were in the
7569 * process of connecting
7570 */
7571 cfg80211_connect_result(pAdapter->dev, NULL,
7572 NULL, 0, NULL, 0,
7573 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7574 GFP_KERNEL);
7575 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 break;
7577
7578 case WLAN_HDD_SOFTAP:
7579 /* softAP can handle SSR */
7580 break;
7581
7582 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007583 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007585 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007586 break;
7587
7588 case WLAN_HDD_MONITOR:
7589 /* monitor interface start */
7590 break;
7591 default:
7592 break;
7593 }
7594
7595 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7596 pAdapterNode = pNext;
7597 }
7598
7599 EXIT();
7600
7601 return VOS_STATUS_SUCCESS;
7602}
7603
7604VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7605{
7606 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7607 hdd_adapter_t *pAdapter;
7608 VOS_STATUS status;
7609 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307610 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007611
7612 ENTER();
7613
7614 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7615
7616 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7617 {
7618 pAdapter = pAdapterNode->pAdapter;
7619
7620 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7621 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7622 {
7623 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7624 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7625
Abhishek Singhf4669da2014-05-26 15:07:49 +05307626 hddLog(VOS_TRACE_LEVEL_INFO,
7627 "%s: Set HDD connState to eConnectionState_NotConnected",
7628 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7630 init_completion(&pAdapter->disconnect_comp_var);
7631 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7632 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7633
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307634 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 &pAdapter->disconnect_comp_var,
7636 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307637 if (0 >= ret)
7638 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7639 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007640
7641 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7642 pHddCtx->isAmpAllowed = VOS_FALSE;
7643 sme_RoamConnect(pHddCtx->hHal,
7644 pAdapter->sessionId, &(pWextState->roamProfile),
7645 &roamId);
7646 }
7647
7648 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7649 pAdapterNode = pNext;
7650 }
7651
7652 EXIT();
7653
7654 return VOS_STATUS_SUCCESS;
7655}
7656
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007657void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7658{
7659 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7660 VOS_STATUS status;
7661 hdd_adapter_t *pAdapter;
7662 hdd_station_ctx_t *pHddStaCtx;
7663 hdd_ap_ctx_t *pHddApCtx;
7664 hdd_hostapd_state_t * pHostapdState;
7665 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7666 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7667 const char *p2pMode = "DEV";
7668 const char *ccMode = "Standalone";
7669 int n;
7670
7671 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7672 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7673 {
7674 pAdapter = pAdapterNode->pAdapter;
7675 switch (pAdapter->device_mode) {
7676 case WLAN_HDD_INFRA_STATION:
7677 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7678 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7679 staChannel = pHddStaCtx->conn_info.operationChannel;
7680 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7681 }
7682 break;
7683 case WLAN_HDD_P2P_CLIENT:
7684 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7685 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7686 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7687 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7688 p2pMode = "CLI";
7689 }
7690 break;
7691 case WLAN_HDD_P2P_GO:
7692 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7693 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7694 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7695 p2pChannel = pHddApCtx->operatingChannel;
7696 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7697 }
7698 p2pMode = "GO";
7699 break;
7700 case WLAN_HDD_SOFTAP:
7701 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7702 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7703 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7704 apChannel = pHddApCtx->operatingChannel;
7705 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7706 }
7707 break;
7708 default:
7709 break;
7710 }
7711 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7712 pAdapterNode = pNext;
7713 }
7714 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7715 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7716 }
7717 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7718 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7719 if (p2pChannel > 0) {
7720 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7721 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7722 }
7723 if (apChannel > 0) {
7724 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7725 apChannel, MAC_ADDR_ARRAY(apBssid));
7726 }
7727
7728 if (p2pChannel > 0 && apChannel > 0) {
7729 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7730 }
7731}
7732
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007733bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007734{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007735 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007736}
7737
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007738/* Once SSR is disabled then it cannot be set. */
7739void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007740{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007741 if (HDD_SSR_DISABLED == isSsrRequired)
7742 return;
7743
Jeff Johnson295189b2012-06-20 16:38:30 -07007744 isSsrRequired = value;
7745}
7746
7747VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7748 hdd_adapter_list_node_t** ppAdapterNode)
7749{
7750 VOS_STATUS status;
7751 spin_lock(&pHddCtx->hddAdapters.lock);
7752 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7753 (hdd_list_node_t**) ppAdapterNode );
7754 spin_unlock(&pHddCtx->hddAdapters.lock);
7755 return status;
7756}
7757
7758VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7759 hdd_adapter_list_node_t* pAdapterNode,
7760 hdd_adapter_list_node_t** pNextAdapterNode)
7761{
7762 VOS_STATUS status;
7763 spin_lock(&pHddCtx->hddAdapters.lock);
7764 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7765 (hdd_list_node_t*) pAdapterNode,
7766 (hdd_list_node_t**)pNextAdapterNode );
7767
7768 spin_unlock(&pHddCtx->hddAdapters.lock);
7769 return status;
7770}
7771
7772VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7773 hdd_adapter_list_node_t* pAdapterNode)
7774{
7775 VOS_STATUS status;
7776 spin_lock(&pHddCtx->hddAdapters.lock);
7777 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7778 &pAdapterNode->node );
7779 spin_unlock(&pHddCtx->hddAdapters.lock);
7780 return status;
7781}
7782
7783VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7784 hdd_adapter_list_node_t** ppAdapterNode)
7785{
7786 VOS_STATUS status;
7787 spin_lock(&pHddCtx->hddAdapters.lock);
7788 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7789 (hdd_list_node_t**) ppAdapterNode );
7790 spin_unlock(&pHddCtx->hddAdapters.lock);
7791 return status;
7792}
7793
7794VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7795 hdd_adapter_list_node_t* pAdapterNode)
7796{
7797 VOS_STATUS status;
7798 spin_lock(&pHddCtx->hddAdapters.lock);
7799 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7800 (hdd_list_node_t*) pAdapterNode );
7801 spin_unlock(&pHddCtx->hddAdapters.lock);
7802 return status;
7803}
7804
7805VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7806 hdd_adapter_list_node_t* pAdapterNode)
7807{
7808 VOS_STATUS status;
7809 spin_lock(&pHddCtx->hddAdapters.lock);
7810 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7811 (hdd_list_node_t*) pAdapterNode );
7812 spin_unlock(&pHddCtx->hddAdapters.lock);
7813 return status;
7814}
7815
7816hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7817 tSirMacAddr macAddr )
7818{
7819 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7820 hdd_adapter_t *pAdapter;
7821 VOS_STATUS status;
7822
7823 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7824
7825 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7826 {
7827 pAdapter = pAdapterNode->pAdapter;
7828
7829 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7830 macAddr, sizeof(tSirMacAddr) ) )
7831 {
7832 return pAdapter;
7833 }
7834 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7835 pAdapterNode = pNext;
7836 }
7837
7838 return NULL;
7839
7840}
7841
7842hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7843{
7844 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7845 hdd_adapter_t *pAdapter;
7846 VOS_STATUS status;
7847
7848 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7849
7850 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7851 {
7852 pAdapter = pAdapterNode->pAdapter;
7853
7854 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7855 IFNAMSIZ ) )
7856 {
7857 return pAdapter;
7858 }
7859 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7860 pAdapterNode = pNext;
7861 }
7862
7863 return NULL;
7864
7865}
7866
7867hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7868{
7869 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7870 hdd_adapter_t *pAdapter;
7871 VOS_STATUS status;
7872
7873 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7874
7875 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7876 {
7877 pAdapter = pAdapterNode->pAdapter;
7878
7879 if( pAdapter && (mode == pAdapter->device_mode) )
7880 {
7881 return pAdapter;
7882 }
7883 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7884 pAdapterNode = pNext;
7885 }
7886
7887 return NULL;
7888
7889}
7890
7891//Remove this function later
7892hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7893{
7894 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7895 hdd_adapter_t *pAdapter;
7896 VOS_STATUS status;
7897
7898 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7899
7900 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7901 {
7902 pAdapter = pAdapterNode->pAdapter;
7903
7904 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7905 {
7906 return pAdapter;
7907 }
7908
7909 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7910 pAdapterNode = pNext;
7911 }
7912
7913 return NULL;
7914
7915}
7916
Jeff Johnson295189b2012-06-20 16:38:30 -07007917/**---------------------------------------------------------------------------
7918
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307919 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007920
7921 This API returns the operating channel of the requested device mode
7922
7923 \param - pHddCtx - Pointer to the HDD context.
7924 - mode - Device mode for which operating channel is required
7925 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7926 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7927 \return - channel number. "0" id the requested device is not found OR it is not connected.
7928 --------------------------------------------------------------------------*/
7929v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7930{
7931 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7932 VOS_STATUS status;
7933 hdd_adapter_t *pAdapter;
7934 v_U8_t operatingChannel = 0;
7935
7936 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7937
7938 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7939 {
7940 pAdapter = pAdapterNode->pAdapter;
7941
7942 if( mode == pAdapter->device_mode )
7943 {
7944 switch(pAdapter->device_mode)
7945 {
7946 case WLAN_HDD_INFRA_STATION:
7947 case WLAN_HDD_P2P_CLIENT:
7948 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7949 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7950 break;
7951 case WLAN_HDD_SOFTAP:
7952 case WLAN_HDD_P2P_GO:
7953 /*softap connection info */
7954 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7955 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7956 break;
7957 default:
7958 break;
7959 }
7960
7961 break; //Found the device of interest. break the loop
7962 }
7963
7964 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7965 pAdapterNode = pNext;
7966 }
7967 return operatingChannel;
7968}
7969
7970#ifdef WLAN_FEATURE_PACKET_FILTERING
7971/**---------------------------------------------------------------------------
7972
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307973 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007974
7975 This used to set the multicast address list.
7976
7977 \param - dev - Pointer to the WLAN device.
7978 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307979 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07007980
7981 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307982static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007983{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307984 hdd_adapter_t *pAdapter;
7985 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007986 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307987 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007988 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307989
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307990 ENTER();
7991
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307992 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307993 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 {
7995 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307996 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007997 return;
7998 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8000 ret = wlan_hdd_validate_context(pHddCtx);
8001 if (0 != ret)
8002 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308003 return;
8004 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008005 if (dev->flags & IFF_ALLMULTI)
8006 {
8007 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008008 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308009 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008010 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308011 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008012 {
8013 mc_count = netdev_mc_count(dev);
8014 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008015 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008016 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8017 {
8018 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008019 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308020 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008021 return;
8022 }
8023
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308024 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008025
8026 netdev_for_each_mc_addr(ha, dev) {
8027 if (i == mc_count)
8028 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308029 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8030 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008031 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308032 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308033 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008034 i++;
8035 }
8036 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308037
8038 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008039 return;
8040}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308041
8042static void hdd_set_multicast_list(struct net_device *dev)
8043{
8044 vos_ssr_protect(__func__);
8045 __hdd_set_multicast_list(dev);
8046 vos_ssr_unprotect(__func__);
8047}
Jeff Johnson295189b2012-06-20 16:38:30 -07008048#endif
8049
8050/**---------------------------------------------------------------------------
8051
8052 \brief hdd_select_queue() -
8053
8054 This function is registered with the Linux OS for network
8055 core to decide which queue to use first.
8056
8057 \param - dev - Pointer to the WLAN device.
8058 - skb - Pointer to OS packet (sk_buff).
8059 \return - ac, Queue Index/access category corresponding to UP in IP header
8060
8061 --------------------------------------------------------------------------*/
8062v_U16_t hdd_select_queue(struct net_device *dev,
8063 struct sk_buff *skb)
8064{
8065 return hdd_wmm_select_queue(dev, skb);
8066}
8067
8068
8069/**---------------------------------------------------------------------------
8070
8071 \brief hdd_wlan_initial_scan() -
8072
8073 This function triggers the initial scan
8074
8075 \param - pAdapter - Pointer to the HDD adapter.
8076
8077 --------------------------------------------------------------------------*/
8078void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8079{
8080 tCsrScanRequest scanReq;
8081 tCsrChannelInfo channelInfo;
8082 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008083 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008084 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8085
8086 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8087 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8088 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8089
8090 if(sme_Is11dSupported(pHddCtx->hHal))
8091 {
8092 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8093 if ( HAL_STATUS_SUCCESS( halStatus ) )
8094 {
8095 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8096 if( !scanReq.ChannelInfo.ChannelList )
8097 {
8098 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8099 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008100 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008101 return;
8102 }
8103 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8104 channelInfo.numOfChannels);
8105 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8106 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008107 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008108 }
8109
8110 scanReq.scanType = eSIR_PASSIVE_SCAN;
8111 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8112 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8113 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8114 }
8115 else
8116 {
8117 scanReq.scanType = eSIR_ACTIVE_SCAN;
8118 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8119 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8120 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8121 }
8122
8123 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8124 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8125 {
8126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8127 __func__, halStatus );
8128 }
8129
8130 if(sme_Is11dSupported(pHddCtx->hHal))
8131 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8132}
8133
Jeff Johnson295189b2012-06-20 16:38:30 -07008134/**---------------------------------------------------------------------------
8135
8136 \brief hdd_full_power_callback() - HDD full power callback function
8137
8138 This is the function invoked by SME to inform the result of a full power
8139 request issued by HDD
8140
8141 \param - callbackcontext - Pointer to cookie
8142 \param - status - result of request
8143
8144 \return - None
8145
8146 --------------------------------------------------------------------------*/
8147static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8148{
Jeff Johnson72a40512013-12-19 10:14:15 -08008149 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008150
8151 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308152 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008153
8154 if (NULL == callbackContext)
8155 {
8156 hddLog(VOS_TRACE_LEVEL_ERROR,
8157 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008158 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008159 return;
8160 }
8161
Jeff Johnson72a40512013-12-19 10:14:15 -08008162 /* there is a race condition that exists between this callback
8163 function and the caller since the caller could time out either
8164 before or while this code is executing. we use a spinlock to
8165 serialize these actions */
8166 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008167
8168 if (POWER_CONTEXT_MAGIC != pContext->magic)
8169 {
8170 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008171 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 hddLog(VOS_TRACE_LEVEL_WARN,
8173 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008174 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 return;
8176 }
8177
Jeff Johnson72a40512013-12-19 10:14:15 -08008178 /* context is valid so caller is still waiting */
8179
8180 /* paranoia: invalidate the magic */
8181 pContext->magic = 0;
8182
8183 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008184 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008185
8186 /* serialization is complete */
8187 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008188}
8189
Katya Nigamf0511f62015-05-05 16:40:57 +05308190void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8191{
8192 pMonCtx->typeSubtypeBitmap = 0;
8193 if( type%10 ) /* Management Packets */
8194 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8195 type/=10;
8196 if( type%10 ) /* Control Packets */
8197 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8198 type/=10;
8199 if( type%10 ) /* Data Packets */
8200 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8201}
8202
8203VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8204{
8205 vos_msg_t monMsg;
8206
8207 monMsg.type = WDA_MON_START_REQ;
8208 monMsg.reserved = 0;
8209 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8210 monMsg.bodyval = 0;
8211
8212 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8213 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8214 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8215 return VOS_STATUS_E_FAILURE;
8216 }
8217
8218 return VOS_STATUS_SUCCESS;
8219}
8220
8221void wlan_hdd_mon_poststopmsg(void)
8222{
8223 vos_msg_t monMsg;
8224
8225 monMsg.type = WDA_MON_STOP_REQ;
8226 monMsg.reserved = 0;
8227 monMsg.bodyptr = NULL;
8228 monMsg.bodyval = 0;
8229
8230 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8231 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8232 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8233 }
8234}
8235
Katya Nigame7b69a82015-04-28 15:24:06 +05308236void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8237{
8238 VOS_STATUS vosStatus;
8239 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8240 struct wiphy *wiphy = pHddCtx->wiphy;
8241
8242 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8243 if(pAdapter == NULL || pVosContext == NULL)
8244 {
8245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8246 return ;
8247 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308248
8249 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308250 hdd_UnregisterWext(pAdapter->dev);
8251
8252 vos_mon_stop( pVosContext );
8253
8254 vosStatus = vos_sched_close( pVosContext );
8255 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8256 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8257 "%s: Failed to close VOSS Scheduler",__func__);
8258 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8259 }
8260
8261 vosStatus = vos_nv_close();
8262 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8263 {
8264 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8265 "%s: Failed to close NV", __func__);
8266 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8267 }
8268
8269 vos_close(pVosContext);
8270
8271 #ifdef WLAN_KD_READY_NOTIFIER
8272 nl_srv_exit(pHddCtx->ptt_pid);
8273 #else
8274 nl_srv_exit();
8275 #endif
8276
8277 if (pHddCtx->cfg_ini)
8278 {
8279 kfree(pHddCtx->cfg_ini);
8280 pHddCtx->cfg_ini= NULL;
8281 }
8282 hdd_close_all_adapters( pHddCtx );
8283
8284 wiphy_free(wiphy) ;
8285
8286}
Jeff Johnson295189b2012-06-20 16:38:30 -07008287/**---------------------------------------------------------------------------
8288
8289 \brief hdd_wlan_exit() - HDD WLAN exit function
8290
8291 This is the driver exit point (invoked during rmmod)
8292
8293 \param - pHddCtx - Pointer to the HDD Context
8294
8295 \return - None
8296
8297 --------------------------------------------------------------------------*/
8298void hdd_wlan_exit(hdd_context_t *pHddCtx)
8299{
8300 eHalStatus halStatus;
8301 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8302 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308303 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008304 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008305 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308307 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008308
8309 ENTER();
8310
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308311
Katya Nigame7b69a82015-04-28 15:24:06 +05308312 if (VOS_MONITOR_MODE == hdd_get_conparam())
8313 {
8314 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8315 wlan_hdd_mon_close(pHddCtx);
8316 return;
8317 }
8318 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008319 {
8320 // Unloading, restart logic is no more required.
8321 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008322
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308323#ifdef FEATURE_WLAN_TDLS
8324 /* At the time of driver unloading; if tdls connection is present;
8325 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8326 * wlan_hdd_tdls_find_peer always checks for valid context;
8327 * as load/unload in progress there can be a race condition.
8328 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8329 * when tdls state is enabled.
8330 * As soon as driver set load/unload flag; tdls flag also needs
8331 * to be disabled so that hdd_rx_packet_cbk won't call
8332 * wlan_hdd_tdls_find_peer.
8333 */
8334 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8335#endif
8336
c_hpothu5ab05e92014-06-13 17:34:05 +05308337 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8338 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308340 pAdapter = pAdapterNode->pAdapter;
8341 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008342 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308343 /* Disable TX on the interface, after this hard_start_xmit() will
8344 * not be called on that interface
8345 */
8346 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8347 netif_tx_disable(pAdapter->dev);
8348
8349 /* Mark the interface status as "down" for outside world */
8350 netif_carrier_off(pAdapter->dev);
8351
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308352 /* DeInit the adapter. This ensures that all data packets
8353 * are freed.
8354 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308355#ifdef FEATURE_WLAN_TDLS
8356 mutex_lock(&pHddCtx->tdls_lock);
8357#endif
c_hpothu002231a2015-02-05 14:58:51 +05308358 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308359#ifdef FEATURE_WLAN_TDLS
8360 mutex_unlock(&pHddCtx->tdls_lock);
8361#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308362
c_hpothu5ab05e92014-06-13 17:34:05 +05308363 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8364 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8365 {
8366 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8367 hdd_UnregisterWext(pAdapter->dev);
8368 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308369
Jeff Johnson295189b2012-06-20 16:38:30 -07008370 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308371 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8372 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308374 // Cancel any outstanding scan requests. We are about to close all
8375 // of our adapters, but an adapter structure is what SME passes back
8376 // to our callback function. Hence if there are any outstanding scan
8377 // requests then there is a race condition between when the adapter
8378 // is closed and when the callback is invoked.We try to resolve that
8379 // race condition here by canceling any outstanding scans before we
8380 // close the adapters.
8381 // Note that the scans may be cancelled in an asynchronous manner,
8382 // so ideally there needs to be some kind of synchronization. Rather
8383 // than introduce a new synchronization here, we will utilize the
8384 // fact that we are about to Request Full Power, and since that is
8385 // synchronized, the expectation is that by the time Request Full
8386 // Power has completed all scans will be cancelled.
8387 if (pHddCtx->scan_info.mScanPending)
8388 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308389 if(NULL != pAdapter)
8390 {
8391 hddLog(VOS_TRACE_LEVEL_INFO,
8392 FL("abort scan mode: %d sessionId: %d"),
8393 pAdapter->device_mode,
8394 pAdapter->sessionId);
8395 }
8396 hdd_abort_mac_scan(pHddCtx,
8397 pHddCtx->scan_info.sessionId,
8398 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308399 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008400 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308401 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008402 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308403 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308404 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8405 {
8406 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8408 "%s: in middle of FTM START", __func__);
8409 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8410 msecs_to_jiffies(20000));
8411 if(!lrc)
8412 {
8413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8414 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8415 }
8416 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008417 wlan_hdd_ftm_close(pHddCtx);
8418 goto free_hdd_ctx;
8419 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308420
Jeff Johnson295189b2012-06-20 16:38:30 -07008421 /* DeRegister with platform driver as client for Suspend/Resume */
8422 vosStatus = hddDeregisterPmOps(pHddCtx);
8423 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8424 {
8425 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8426 VOS_ASSERT(0);
8427 }
8428
8429 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8430 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8431 {
8432 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8433 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008434
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008435 //Stop the traffic monitor timer
8436 if ( VOS_TIMER_STATE_RUNNING ==
8437 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8438 {
8439 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8440 }
8441
8442 // Destroy the traffic monitor timer
8443 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8444 &pHddCtx->tx_rx_trafficTmr)))
8445 {
8446 hddLog(VOS_TRACE_LEVEL_ERROR,
8447 "%s: Cannot deallocate Traffic monitor timer", __func__);
8448 }
8449
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 //Disable IMPS/BMPS as we do not want the device to enter any power
8451 //save mode during shutdown
8452 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8453 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8454 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8455
8456 //Ensure that device is in full power as we will touch H/W during vos_Stop
8457 init_completion(&powerContext.completion);
8458 powerContext.magic = POWER_CONTEXT_MAGIC;
8459
8460 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8461 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8462
8463 if (eHAL_STATUS_SUCCESS != halStatus)
8464 {
8465 if (eHAL_STATUS_PMC_PENDING == halStatus)
8466 {
8467 /* request was sent -- wait for the response */
8468 lrc = wait_for_completion_interruptible_timeout(
8469 &powerContext.completion,
8470 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 if (lrc <= 0)
8472 {
8473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008474 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 }
8476 }
8477 else
8478 {
8479 hddLog(VOS_TRACE_LEVEL_ERROR,
8480 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008481 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008482 /* continue -- need to clean up as much as possible */
8483 }
8484 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308485 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8486 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8487 {
8488 /* This will issue a dump command which will clean up
8489 BTQM queues and unblock MC thread */
8490 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8491 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008492
Jeff Johnson72a40512013-12-19 10:14:15 -08008493 /* either we never sent a request, we sent a request and received a
8494 response or we sent a request and timed out. if we never sent a
8495 request or if we sent a request and got a response, we want to
8496 clear the magic out of paranoia. if we timed out there is a
8497 race condition such that the callback function could be
8498 executing at the same time we are. of primary concern is if the
8499 callback function had already verified the "magic" but had not
8500 yet set the completion variable when a timeout occurred. we
8501 serialize these activities by invalidating the magic while
8502 holding a shared spinlock which will cause us to block if the
8503 callback is currently executing */
8504 spin_lock(&hdd_context_lock);
8505 powerContext.magic = 0;
8506 spin_unlock(&hdd_context_lock);
8507
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308508 /* If Device is shutdown, no point for SME to wait for responses
8509 from device. Pre Close SME */
8510 if(wcnss_device_is_shutdown())
8511 {
8512 sme_PreClose(pHddCtx->hHal);
8513 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008514 hdd_debugfs_exit(pHddCtx);
8515
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308516#ifdef WLAN_NS_OFFLOAD
8517 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8518 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8519#endif
8520 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8521 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8522
Jeff Johnson295189b2012-06-20 16:38:30 -07008523 // Unregister the Net Device Notifier
8524 unregister_netdevice_notifier(&hdd_netdev_notifier);
8525
Jeff Johnson295189b2012-06-20 16:38:30 -07008526 hdd_stop_all_adapters( pHddCtx );
8527
Jeff Johnson295189b2012-06-20 16:38:30 -07008528#ifdef WLAN_BTAMP_FEATURE
8529 vosStatus = WLANBAP_Stop(pVosContext);
8530 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8531 {
8532 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8533 "%s: Failed to stop BAP",__func__);
8534 }
8535#endif //WLAN_BTAMP_FEATURE
8536
8537 //Stop all the modules
8538 vosStatus = vos_stop( pVosContext );
8539 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8540 {
8541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8542 "%s: Failed to stop VOSS",__func__);
8543 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8544 }
8545
Jeff Johnson295189b2012-06-20 16:38:30 -07008546 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008548
8549 //Close the scheduler before calling vos_close to make sure no thread is
8550 // scheduled after the each module close is called i.e after all the data
8551 // structures are freed.
8552 vosStatus = vos_sched_close( pVosContext );
8553 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8554 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8555 "%s: Failed to close VOSS Scheduler",__func__);
8556 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8557 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008558#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8559 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308560 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008561#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008562 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308563 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008564
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308565#ifdef CONFIG_ENABLE_LINUX_REG
8566 vosStatus = vos_nv_close();
8567 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8568 {
8569 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8570 "%s: Failed to close NV", __func__);
8571 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8572 }
8573#endif
8574
Jeff Johnson295189b2012-06-20 16:38:30 -07008575 //Close VOSS
8576 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8577 vos_close(pVosContext);
8578
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 //Close Watchdog
8580 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8581 vos_watchdog_close(pVosContext);
8582
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308583 //Clean up HDD Nlink Service
8584 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308585
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308586#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308587 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308588 {
8589 wlan_logging_sock_deactivate_svc();
8590 }
8591#endif
8592
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308593#ifdef WLAN_KD_READY_NOTIFIER
8594 nl_srv_exit(pHddCtx->ptt_pid);
8595#else
8596 nl_srv_exit();
8597#endif /* WLAN_KD_READY_NOTIFIER */
8598
8599
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 hdd_close_all_adapters( pHddCtx );
8601
Jeff Johnson295189b2012-06-20 16:38:30 -07008602 /* free the power on lock from platform driver */
8603 if (free_riva_power_on_lock("wlan"))
8604 {
8605 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8606 __func__);
8607 }
8608
Jeff Johnson88ba7742013-02-27 14:36:02 -08008609free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308610
8611 //Free up dynamically allocated members inside HDD Adapter
8612 if (pHddCtx->cfg_ini)
8613 {
8614 kfree(pHddCtx->cfg_ini);
8615 pHddCtx->cfg_ini= NULL;
8616 }
8617
Leo Changf04ddad2013-09-18 13:46:38 -07008618 /* FTM mode, WIPHY did not registered
8619 If un-register here, system crash will happen */
8620 if (VOS_FTM_MODE != hdd_get_conparam())
8621 {
8622 wiphy_unregister(wiphy) ;
8623 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008624 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 if (hdd_is_ssr_required())
8626 {
8627 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008628 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008629 msleep(5000);
8630 }
8631 hdd_set_ssr_required (VOS_FALSE);
8632}
8633
8634
8635/**---------------------------------------------------------------------------
8636
8637 \brief hdd_update_config_from_nv() - Function to update the contents of
8638 the running configuration with parameters taken from NV storage
8639
8640 \param - pHddCtx - Pointer to the HDD global context
8641
8642 \return - VOS_STATUS_SUCCESS if successful
8643
8644 --------------------------------------------------------------------------*/
8645static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8646{
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 v_BOOL_t itemIsValid = VOS_FALSE;
8648 VOS_STATUS status;
8649 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8650 v_U8_t macLoop;
8651
8652 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8653 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8654 if(status != VOS_STATUS_SUCCESS)
8655 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008656 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008657 return VOS_STATUS_E_FAILURE;
8658 }
8659
8660 if (itemIsValid == VOS_TRUE)
8661 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008662 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8664 VOS_MAX_CONCURRENCY_PERSONA);
8665 if(status != VOS_STATUS_SUCCESS)
8666 {
8667 /* Get MAC from NV fail, not update CFG info
8668 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008669 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008670 return VOS_STATUS_E_FAILURE;
8671 }
8672
8673 /* If first MAC is not valid, treat all others are not valid
8674 * Then all MACs will be got from ini file */
8675 if(vos_is_macaddr_zero(&macFromNV[0]))
8676 {
8677 /* MAC address in NV file is not configured yet */
8678 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8679 return VOS_STATUS_E_INVAL;
8680 }
8681
8682 /* Get MAC address from NV, update CFG info */
8683 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8684 {
8685 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8686 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308687 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 /* This MAC is not valid, skip it
8689 * This MAC will be got from ini file */
8690 }
8691 else
8692 {
8693 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8694 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8695 VOS_MAC_ADDR_SIZE);
8696 }
8697 }
8698 }
8699 else
8700 {
8701 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8702 return VOS_STATUS_E_FAILURE;
8703 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008704
Jeff Johnson295189b2012-06-20 16:38:30 -07008705
8706 return VOS_STATUS_SUCCESS;
8707}
8708
8709/**---------------------------------------------------------------------------
8710
8711 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8712
8713 \param - pAdapter - Pointer to the HDD
8714
8715 \return - None
8716
8717 --------------------------------------------------------------------------*/
8718VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8719{
8720 eHalStatus halStatus;
8721 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308722 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008723
Jeff Johnson295189b2012-06-20 16:38:30 -07008724
8725 // Send ready indication to the HDD. This will kick off the MAC
8726 // into a 'running' state and should kick off an initial scan.
8727 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8728 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8729 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308730 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008731 "code %08d [x%08x]",__func__, halStatus, halStatus );
8732 return VOS_STATUS_E_FAILURE;
8733 }
8734
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308735 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008736 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8737 // And RIVA will crash
8738 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8739 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308740 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8741 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8742
8743
Jeff Johnson295189b2012-06-20 16:38:30 -07008744 return VOS_STATUS_SUCCESS;
8745}
8746
Jeff Johnson295189b2012-06-20 16:38:30 -07008747/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308748void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008749{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308750
8751 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8752
Jeff Johnson295189b2012-06-20 16:38:30 -07008753}
8754
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308755void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008756{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308757
8758 vos_wake_lock_release(&wlan_wake_lock, reason);
8759
Jeff Johnson295189b2012-06-20 16:38:30 -07008760}
8761
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308762void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008763{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308764
8765 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8766 reason);
8767
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008768}
8769
Jeff Johnson295189b2012-06-20 16:38:30 -07008770/**---------------------------------------------------------------------------
8771
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008772 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8773 information between Host and Riva
8774
8775 This function gets reported version of FW
8776 It also finds the version of Riva headers used to compile the host
8777 It compares the above two and prints a warning if they are different
8778 It gets the SW and HW version string
8779 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8780 indicating the features they support through a bitmap
8781
8782 \param - pHddCtx - Pointer to HDD context
8783
8784 \return - void
8785
8786 --------------------------------------------------------------------------*/
8787
8788void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8789{
8790
8791 tSirVersionType versionCompiled;
8792 tSirVersionType versionReported;
8793 tSirVersionString versionString;
8794 tANI_U8 fwFeatCapsMsgSupported = 0;
8795 VOS_STATUS vstatus;
8796
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008797 memset(&versionCompiled, 0, sizeof(versionCompiled));
8798 memset(&versionReported, 0, sizeof(versionReported));
8799
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008800 /* retrieve and display WCNSS version information */
8801 do {
8802
8803 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8804 &versionCompiled);
8805 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8806 {
8807 hddLog(VOS_TRACE_LEVEL_FATAL,
8808 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008809 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008810 break;
8811 }
8812
8813 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8814 &versionReported);
8815 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8816 {
8817 hddLog(VOS_TRACE_LEVEL_FATAL,
8818 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008819 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008820 break;
8821 }
8822
8823 if ((versionCompiled.major != versionReported.major) ||
8824 (versionCompiled.minor != versionReported.minor) ||
8825 (versionCompiled.version != versionReported.version) ||
8826 (versionCompiled.revision != versionReported.revision))
8827 {
8828 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8829 "Host expected %u.%u.%u.%u\n",
8830 WLAN_MODULE_NAME,
8831 (int)versionReported.major,
8832 (int)versionReported.minor,
8833 (int)versionReported.version,
8834 (int)versionReported.revision,
8835 (int)versionCompiled.major,
8836 (int)versionCompiled.minor,
8837 (int)versionCompiled.version,
8838 (int)versionCompiled.revision);
8839 }
8840 else
8841 {
8842 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8843 WLAN_MODULE_NAME,
8844 (int)versionReported.major,
8845 (int)versionReported.minor,
8846 (int)versionReported.version,
8847 (int)versionReported.revision);
8848 }
8849
8850 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8851 versionString,
8852 sizeof(versionString));
8853 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8854 {
8855 hddLog(VOS_TRACE_LEVEL_FATAL,
8856 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008857 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008858 break;
8859 }
8860
8861 pr_info("%s: WCNSS software version %s\n",
8862 WLAN_MODULE_NAME, versionString);
8863
8864 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8865 versionString,
8866 sizeof(versionString));
8867 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8868 {
8869 hddLog(VOS_TRACE_LEVEL_FATAL,
8870 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008871 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008872 break;
8873 }
8874
8875 pr_info("%s: WCNSS hardware version %s\n",
8876 WLAN_MODULE_NAME, versionString);
8877
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008878 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8879 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008880 send the message only if it the riva is 1.1
8881 minor numbers for different riva branches:
8882 0 -> (1.0)Mainline Build
8883 1 -> (1.1)Mainline Build
8884 2->(1.04) Stability Build
8885 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008886 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008887 ((versionReported.minor>=1) && (versionReported.version>=1)))
8888 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8889 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008890
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008891 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008892 {
8893#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8894 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8895 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8896#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008897 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8898 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8899 {
8900 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8901 }
8902
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008903 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008904 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008905
8906 } while (0);
8907
8908}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308909void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8910{
8911 struct sk_buff *skb;
8912 struct nlmsghdr *nlh;
8913 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05308914 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05308915
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05308916 if (in_interrupt() || irqs_disabled() || in_atomic())
8917 flags = GFP_ATOMIC;
8918
8919 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05308920
8921 if(skb == NULL) {
8922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8923 "%s: alloc_skb failed", __func__);
8924 return;
8925 }
8926
8927 nlh = (struct nlmsghdr *)skb->data;
8928 nlh->nlmsg_pid = 0; /* from kernel */
8929 nlh->nlmsg_flags = 0;
8930 nlh->nlmsg_seq = 0;
8931 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8932
8933 ani_hdr = NLMSG_DATA(nlh);
8934 ani_hdr->type = type;
8935
8936 switch(type) {
8937 case WLAN_SVC_SAP_RESTART_IND:
8938 ani_hdr->length = 0;
8939 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8940 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8941 break;
8942 default:
8943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8944 "Attempt to send unknown nlink message %d", type);
8945 kfree_skb(skb);
8946 return;
8947 }
8948
8949 nl_srv_bcast(skb);
8950
8951 return;
8952}
8953
8954
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008955
8956/**---------------------------------------------------------------------------
8957
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308958 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8959
8960 \param - pHddCtx - Pointer to the hdd context
8961
8962 \return - true if hardware supports 5GHz
8963
8964 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308965boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308966{
8967 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8968 * then hardware support 5Ghz.
8969 */
8970 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8971 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308972 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308973 return true;
8974 }
8975 else
8976 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308978 __func__);
8979 return false;
8980 }
8981}
8982
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308983/**---------------------------------------------------------------------------
8984
8985 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8986 generate function
8987
8988 This is generate the random mac address for WLAN interface
8989
8990 \param - pHddCtx - Pointer to HDD context
8991 idx - Start interface index to get auto
8992 generated mac addr.
8993 mac_addr - Mac address
8994
8995 \return - 0 for success, < 0 for failure
8996
8997 --------------------------------------------------------------------------*/
8998
8999static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9000 int idx, v_MACADDR_t mac_addr)
9001{
9002 int i;
9003 unsigned int serialno;
9004 serialno = wcnss_get_serial_number();
9005
9006 if (0 != serialno)
9007 {
9008 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9009 bytes of the serial number that can be used to generate
9010 the other 3 bytes of the MAC address. Mask off all but
9011 the lower 3 bytes (this will also make sure we don't
9012 overflow in the next step) */
9013 serialno &= 0x00FFFFFF;
9014
9015 /* we need a unique address for each session */
9016 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9017
9018 /* autogen other Mac addresses */
9019 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9020 {
9021 /* start with the entire default address */
9022 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9023 /* then replace the lower 3 bytes */
9024 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9025 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9026 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9027
9028 serialno++;
9029 hddLog(VOS_TRACE_LEVEL_ERROR,
9030 "%s: Derived Mac Addr: "
9031 MAC_ADDRESS_STR, __func__,
9032 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9033 }
9034
9035 }
9036 else
9037 {
9038 hddLog(LOGE, FL("Failed to Get Serial NO"));
9039 return -1;
9040 }
9041 return 0;
9042}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309043
Katya Nigame7b69a82015-04-28 15:24:06 +05309044int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9045{
9046 VOS_STATUS status;
9047 v_CONTEXT_t pVosContext= NULL;
9048 hdd_adapter_t *pAdapter= NULL;
9049
9050 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9051
9052 if (NULL == pVosContext)
9053 {
9054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9055 "%s: Trying to open VOSS without a PreOpen", __func__);
9056 VOS_ASSERT(0);
9057 return VOS_STATUS_E_FAILURE;
9058 }
9059
9060 status = vos_nv_open();
9061 if (!VOS_IS_STATUS_SUCCESS(status))
9062 {
9063 /* NV module cannot be initialized */
9064 hddLog( VOS_TRACE_LEVEL_FATAL,
9065 "%s: vos_nv_open failed", __func__);
9066 return VOS_STATUS_E_FAILURE;
9067 }
9068
9069 status = vos_init_wiphy_from_nv_bin();
9070 if (!VOS_IS_STATUS_SUCCESS(status))
9071 {
9072 /* NV module cannot be initialized */
9073 hddLog( VOS_TRACE_LEVEL_FATAL,
9074 "%s: vos_init_wiphy failed", __func__);
9075 goto err_vos_nv_close;
9076 }
9077
9078 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9079 if ( !VOS_IS_STATUS_SUCCESS( status ))
9080 {
9081 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9082 goto err_vos_nv_close;
9083 }
9084
9085 status = vos_mon_start( pVosContext );
9086 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9087 {
9088 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9089 goto err_vosclose;
9090 }
9091
9092 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9093 WDA_featureCapsExchange(pVosContext);
9094 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9095
9096 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9097 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9098 if( pAdapter == NULL )
9099 {
9100 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9101 goto err_close_adapter;
9102 }
9103
9104 //Initialize the nlink service
9105 if(nl_srv_init() != 0)
9106 {
9107 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9108 goto err_close_adapter;
9109 }
9110 return VOS_STATUS_SUCCESS;
9111
9112err_close_adapter:
9113 hdd_close_all_adapters( pHddCtx );
9114 vos_mon_stop( pVosContext );
9115err_vosclose:
9116 status = vos_sched_close( pVosContext );
9117 if (!VOS_IS_STATUS_SUCCESS(status)) {
9118 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9119 "%s: Failed to close VOSS Scheduler", __func__);
9120 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9121 }
9122 vos_close(pVosContext );
9123
9124err_vos_nv_close:
9125 vos_nv_close();
9126
9127return status;
9128}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309129/**---------------------------------------------------------------------------
9130
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309131 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9132 completed to flush out the scan results
9133
9134 11d scan is done during driver load and is a passive scan on all
9135 channels supported by the device, 11d scans may find some APs on
9136 frequencies which are forbidden to be used in the regulatory domain
9137 the device is operating in. If these APs are notified to the supplicant
9138 it may try to connect to these APs, thus flush out all the scan results
9139 which are present in SME after 11d scan is done.
9140
9141 \return - eHalStatus
9142
9143 --------------------------------------------------------------------------*/
9144static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9145 tANI_U32 scanId, eCsrScanStatus status)
9146{
9147 ENTER();
9148
9149 sme_ScanFlushResult(halHandle, 0);
9150
9151 EXIT();
9152
9153 return eHAL_STATUS_SUCCESS;
9154}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309155/**---------------------------------------------------------------------------
9156
9157 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9158 logging is completed successfully.
9159
9160 \return - None
9161
9162 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309163void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309164{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309165 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309166
9167 if (NULL == pHddCtx)
9168 {
9169 hddLog(VOS_TRACE_LEVEL_ERROR,
9170 "%s: HDD context is NULL",__func__);
9171 return;
9172 }
9173
9174 if (VOS_STATUS_SUCCESS == status)
9175 {
9176 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9177 pHddCtx->mgmt_frame_logging = TRUE;
9178 }
9179 else
9180 {
9181 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9182 pHddCtx->mgmt_frame_logging = FALSE;
9183 }
9184
9185 return;
9186}
9187/**---------------------------------------------------------------------------
9188
9189 \brief hdd_init_frame_logging - function to initialize frame logging.
9190 Currently only Mgmt Frames are logged in both TX
9191 and Rx direction and are sent to userspace
9192 application using logger thread when queried.
9193
9194 \return - None
9195
9196 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309197void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309198{
9199 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309200 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309201
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309202 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9203 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309204 {
9205 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9206 return;
9207 }
9208
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309209 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9210 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309211 {
9212 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9213 return;
9214 }
9215
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309216 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309217
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309218 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9219 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9220 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9221 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309222
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309223 if (pHddCtx->cfg_ini->enableFWLogging ||
9224 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309225 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309226 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309227 }
9228
9229 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9230 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309231 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309232 }
9233
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309234 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9235 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9236 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9237 wlanFWLoggingInitParam->continuousFrameLogging =
9238 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309239
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309240 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309241
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309242 wlanFWLoggingInitParam->minLogBufferSize =
9243 pHddCtx->cfg_ini->minLoggingBufferSize;
9244 wlanFWLoggingInitParam->maxLogBufferSize =
9245 pHddCtx->cfg_ini->maxLoggingBufferSize;
9246 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9247 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309248
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309249 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309250
9251 if (eHAL_STATUS_SUCCESS != halStatus)
9252 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309253 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309254 }
9255
9256 return;
9257}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309258
9259/**---------------------------------------------------------------------------
9260
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 \brief hdd_wlan_startup() - HDD init function
9262
9263 This is the driver startup code executed once a WLAN device has been detected
9264
9265 \param - dev - Pointer to the underlying device
9266
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009267 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009268
9269 --------------------------------------------------------------------------*/
9270
9271int hdd_wlan_startup(struct device *dev )
9272{
9273 VOS_STATUS status;
9274 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009275 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 hdd_context_t *pHddCtx = NULL;
9277 v_CONTEXT_t pVosContext= NULL;
9278#ifdef WLAN_BTAMP_FEATURE
9279 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9280 WLANBAP_ConfigType btAmpConfig;
9281 hdd_config_t *pConfig;
9282#endif
9283 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009284 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309285 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009286
9287 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009288 /*
9289 * cfg80211: wiphy allocation
9290 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309291 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009292
9293 if(wiphy == NULL)
9294 {
9295 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009296 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009297 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 pHddCtx = wiphy_priv(wiphy);
9299
Jeff Johnson295189b2012-06-20 16:38:30 -07009300 //Initialize the adapter context to zeros.
9301 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9302
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309304 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309305 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009306
9307 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9308
9309 /*Get vos context here bcoz vos_open requires it*/
9310 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9311
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009312 if(pVosContext == NULL)
9313 {
9314 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9315 goto err_free_hdd_context;
9316 }
9317
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 //Save the Global VOSS context in adapter context for future.
9319 pHddCtx->pvosContext = pVosContext;
9320
9321 //Save the adapter context in global context for future.
9322 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9323
Jeff Johnson295189b2012-06-20 16:38:30 -07009324 pHddCtx->parent_dev = dev;
9325
9326 init_completion(&pHddCtx->full_pwr_comp_var);
9327 init_completion(&pHddCtx->standby_comp_var);
9328 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009329 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009330 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309331 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309332 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009333
9334#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009335 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009336#else
9337 init_completion(&pHddCtx->driver_crda_req);
9338#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009339
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309340 spin_lock_init(&pHddCtx->schedScan_lock);
9341
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9343
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309344#ifdef FEATURE_WLAN_TDLS
9345 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9346 * invoked by other instances also) to protect the concurrent
9347 * access for the Adapters by TDLS module.
9348 */
9349 mutex_init(&pHddCtx->tdls_lock);
9350#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309351 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309352 mutex_init(&pHddCtx->wmmLock);
9353
Agarwal Ashish1f422872014-07-22 00:11:55 +05309354 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309355
Agarwal Ashish1f422872014-07-22 00:11:55 +05309356 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 // Load all config first as TL config is needed during vos_open
9358 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9359 if(pHddCtx->cfg_ini == NULL)
9360 {
9361 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9362 goto err_free_hdd_context;
9363 }
9364
9365 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9366
9367 // Read and parse the qcom_cfg.ini file
9368 status = hdd_parse_config_ini( pHddCtx );
9369 if ( VOS_STATUS_SUCCESS != status )
9370 {
9371 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9372 __func__, WLAN_INI_FILE);
9373 goto err_config;
9374 }
Arif Hussaind5218912013-12-05 01:10:55 -08009375#ifdef MEMORY_DEBUG
9376 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9377 vos_mem_init();
9378
9379 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9380 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9381#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009382
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309383 /* INI has been read, initialise the configuredMcastBcastFilter with
9384 * INI value as this will serve as the default value
9385 */
9386 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9387 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9388 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309389
9390 if (false == hdd_is_5g_supported(pHddCtx))
9391 {
9392 //5Ghz is not supported.
9393 if (1 != pHddCtx->cfg_ini->nBandCapability)
9394 {
9395 hddLog(VOS_TRACE_LEVEL_INFO,
9396 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9397 pHddCtx->cfg_ini->nBandCapability = 1;
9398 }
9399 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309400
9401 /* If SNR Monitoring is enabled, FW has to parse all beacons
9402 * for calcaluting and storing the average SNR, so set Nth beacon
9403 * filter to 1 to enable FW to parse all the beaocons
9404 */
9405 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9406 {
9407 /* The log level is deliberately set to WARN as overriding
9408 * nthBeaconFilter to 1 will increase power cosumption and this
9409 * might just prove helpful to detect the power issue.
9410 */
9411 hddLog(VOS_TRACE_LEVEL_WARN,
9412 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9413 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9414 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309416 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009418 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009420 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9421 {
9422 hddLog(VOS_TRACE_LEVEL_FATAL,
9423 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9424 goto err_config;
9425 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009426 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009427
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009428 // Update VOS trace levels based upon the cfg.ini
9429 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9430 pHddCtx->cfg_ini->vosTraceEnableBAP);
9431 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9432 pHddCtx->cfg_ini->vosTraceEnableTL);
9433 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9434 pHddCtx->cfg_ini->vosTraceEnableWDI);
9435 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9436 pHddCtx->cfg_ini->vosTraceEnableHDD);
9437 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9438 pHddCtx->cfg_ini->vosTraceEnableSME);
9439 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9440 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309441 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9442 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009443 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9444 pHddCtx->cfg_ini->vosTraceEnableWDA);
9445 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9446 pHddCtx->cfg_ini->vosTraceEnableSYS);
9447 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9448 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009449 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9450 pHddCtx->cfg_ini->vosTraceEnableSAP);
9451 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9452 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009453
Jeff Johnson295189b2012-06-20 16:38:30 -07009454 // Update WDI trace levels based upon the cfg.ini
9455 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9456 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9457 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9458 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9459 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9460 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9461 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9462 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009463
Jeff Johnson88ba7742013-02-27 14:36:02 -08009464 if (VOS_FTM_MODE == hdd_get_conparam())
9465 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9467 {
9468 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9469 goto err_free_hdd_context;
9470 }
9471 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309472 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309473 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009475 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009476
Katya Nigame7b69a82015-04-28 15:24:06 +05309477 if( VOS_MONITOR_MODE == hdd_get_conparam())
9478 {
9479 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9480 {
9481 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9482 goto err_free_hdd_context;
9483 }
9484 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9485 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9486 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9487 return VOS_STATUS_SUCCESS;
9488 }
9489
Jeff Johnson88ba7742013-02-27 14:36:02 -08009490 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9492 {
9493 status = vos_watchdog_open(pVosContext,
9494 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9495
9496 if(!VOS_IS_STATUS_SUCCESS( status ))
9497 {
9498 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309499 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009500 }
9501 }
9502
9503 pHddCtx->isLogpInProgress = FALSE;
9504 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9505
Amar Singhala49cbc52013-10-08 18:37:44 -07009506#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009507 /* initialize the NV module. This is required so that
9508 we can initialize the channel information in wiphy
9509 from the NV.bin data. The channel information in
9510 wiphy needs to be initialized before wiphy registration */
9511
9512 status = vos_nv_open();
9513 if (!VOS_IS_STATUS_SUCCESS(status))
9514 {
9515 /* NV module cannot be initialized */
9516 hddLog( VOS_TRACE_LEVEL_FATAL,
9517 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309518 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009519 }
9520
9521 status = vos_init_wiphy_from_nv_bin();
9522 if (!VOS_IS_STATUS_SUCCESS(status))
9523 {
9524 /* NV module cannot be initialized */
9525 hddLog( VOS_TRACE_LEVEL_FATAL,
9526 "%s: vos_init_wiphy failed", __func__);
9527 goto err_vos_nv_close;
9528 }
9529
Amar Singhala49cbc52013-10-08 18:37:44 -07009530#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309531 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309532 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 if ( !VOS_IS_STATUS_SUCCESS( status ))
9534 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009535 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309536 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 }
9538
Jeff Johnson295189b2012-06-20 16:38:30 -07009539 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9540
9541 if ( NULL == pHddCtx->hHal )
9542 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009543 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 goto err_vosclose;
9545 }
9546
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009547 status = vos_preStart( pHddCtx->pvosContext );
9548 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9549 {
9550 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309551 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009552 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009553
Arif Hussaineaf68602013-12-30 23:10:44 -08009554 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9555 {
9556 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9557 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9558 __func__, enable_dfs_chan_scan);
9559 }
9560 if (0 == enable_11d || 1 == enable_11d)
9561 {
9562 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9563 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9564 __func__, enable_11d);
9565 }
9566
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009567 /* Note that the vos_preStart() sequence triggers the cfg download.
9568 The cfg download must occur before we update the SME config
9569 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 status = hdd_set_sme_config( pHddCtx );
9571
9572 if ( VOS_STATUS_SUCCESS != status )
9573 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009574 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309575 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009576 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009577
Jeff Johnson295189b2012-06-20 16:38:30 -07009578 /* In the integrated architecture we update the configuration from
9579 the INI file and from NV before vOSS has been started so that
9580 the final contents are available to send down to the cCPU */
9581
9582 // Apply the cfg.ini to cfg.dat
9583 if (FALSE == hdd_update_config_dat(pHddCtx))
9584 {
9585 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309586 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 }
9588
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309589 // Get mac addr from platform driver
9590 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9591
9592 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309594 /* Store the mac addr for first interface */
9595 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9596
9597 hddLog(VOS_TRACE_LEVEL_ERROR,
9598 "%s: WLAN Mac Addr: "
9599 MAC_ADDRESS_STR, __func__,
9600 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9601
9602 /* Here, passing Arg2 as 1 because we do not want to change the
9603 last 3 bytes (means non OUI bytes) of first interface mac
9604 addr.
9605 */
9606 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9607 {
9608 hddLog(VOS_TRACE_LEVEL_ERROR,
9609 "%s: Failed to generate wlan interface mac addr "
9610 "using MAC from ini file ", __func__);
9611 }
9612 }
9613 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9614 {
9615 // Apply the NV to cfg.dat
9616 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009617#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9618 /* There was not a valid set of MAC Addresses in NV. See if the
9619 default addresses were modified by the cfg.ini settings. If so,
9620 we'll use them, but if not, we'll autogenerate a set of MAC
9621 addresses based upon the device serial number */
9622
9623 static const v_MACADDR_t default_address =
9624 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009625
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309626 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9627 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 {
9629 /* cfg.ini has the default address, invoke autogen logic */
9630
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309631 /* Here, passing Arg2 as 0 because we want to change the
9632 last 3 bytes (means non OUI bytes) of all the interfaces
9633 mac addr.
9634 */
9635 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9636 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309638 hddLog(VOS_TRACE_LEVEL_ERROR,
9639 "%s: Failed to generate wlan interface mac addr "
9640 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9641 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 }
9644 else
9645#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9646 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009647 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 "%s: Invalid MAC address in NV, using MAC from ini file "
9649 MAC_ADDRESS_STR, __func__,
9650 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9651 }
9652 }
9653 {
9654 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309655
9656 /* Set the MAC Address Currently this is used by HAL to
9657 * add self sta. Remove this once self sta is added as
9658 * part of session open.
9659 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9661 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9662 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309663
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 if (!HAL_STATUS_SUCCESS( halStatus ))
9665 {
9666 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9667 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309668 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009669 }
9670 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009671
9672 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9673 Note: Firmware image will be read and downloaded inside vos_start API */
9674 status = vos_start( pHddCtx->pvosContext );
9675 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9676 {
9677 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309678 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009679 }
9680
Leo Chang6cec3e22014-01-21 15:33:49 -08009681#ifdef FEATURE_WLAN_CH_AVOID
9682 /* Plug in avoid channel notification callback
9683 * This should happen before ADD_SELF_STA
9684 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309685
9686 /* check the Channel Avoidance is enabled */
9687 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9688 {
9689 sme_AddChAvoidCallback(pHddCtx->hHal,
9690 hdd_hostapd_ch_avoid_cb);
9691 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009692#endif /* FEATURE_WLAN_CH_AVOID */
9693
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009694 /* Exchange capability info between Host and FW and also get versioning info from FW */
9695 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009696
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309697#ifdef CONFIG_ENABLE_LINUX_REG
9698 status = wlan_hdd_init_channels(pHddCtx);
9699 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9700 {
9701 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9702 __func__);
9703 goto err_vosstop;
9704 }
9705#endif
9706
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 status = hdd_post_voss_start_config( pHddCtx );
9708 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9709 {
9710 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9711 __func__);
9712 goto err_vosstop;
9713 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009714
9715#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309716 wlan_hdd_cfg80211_update_reg_info( wiphy );
9717
9718 /* registration of wiphy dev with cfg80211 */
9719 if (0 > wlan_hdd_cfg80211_register(wiphy))
9720 {
9721 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9722 goto err_vosstop;
9723 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009724#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009725
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309726#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309727 /* registration of wiphy dev with cfg80211 */
9728 if (0 > wlan_hdd_cfg80211_register(wiphy))
9729 {
9730 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9731 goto err_vosstop;
9732 }
9733
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309734 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309735 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9736 {
9737 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9738 __func__);
9739 goto err_unregister_wiphy;
9740 }
9741#endif
9742
c_hpothu4a298be2014-12-22 21:12:51 +05309743 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9744
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9746 {
9747 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9748 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9749 }
9750 else
9751 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9753 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9754 if (pAdapter != NULL)
9755 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309756 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009757 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309758 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9759 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9760 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009761
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309762 /* Generate the P2P Device Address. This consists of the device's
9763 * primary MAC address with the locally administered bit set.
9764 */
9765 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009766 }
9767 else
9768 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309769 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9770 if (p2p_dev_addr != NULL)
9771 {
9772 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9773 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9774 }
9775 else
9776 {
9777 hddLog(VOS_TRACE_LEVEL_FATAL,
9778 "%s: Failed to allocate mac_address for p2p_device",
9779 __func__);
9780 goto err_close_adapter;
9781 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009783
9784 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9785 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9786 if ( NULL == pP2pAdapter )
9787 {
9788 hddLog(VOS_TRACE_LEVEL_FATAL,
9789 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009790 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009791 goto err_close_adapter;
9792 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009793 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009795
9796 if( pAdapter == NULL )
9797 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009798 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9799 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009800 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009801
Arif Hussain66559122013-11-21 10:11:40 -08009802 if (country_code)
9803 {
9804 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009805 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009806 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9807#ifndef CONFIG_ENABLE_LINUX_REG
9808 hdd_checkandupdate_phymode(pAdapter, country_code);
9809#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009810 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9811 (void *)(tSmeChangeCountryCallback)
9812 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009813 country_code,
9814 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309815 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009816 if (eHAL_STATUS_SUCCESS == ret)
9817 {
Arif Hussaincb607082013-12-20 11:57:42 -08009818 ret = wait_for_completion_interruptible_timeout(
9819 &pAdapter->change_country_code,
9820 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9821
9822 if (0 >= ret)
9823 {
9824 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9825 "%s: SME while setting country code timed out", __func__);
9826 }
Arif Hussain66559122013-11-21 10:11:40 -08009827 }
9828 else
9829 {
Arif Hussaincb607082013-12-20 11:57:42 -08009830 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9831 "%s: SME Change Country code from module param fail ret=%d",
9832 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009833 }
9834 }
9835
Jeff Johnson295189b2012-06-20 16:38:30 -07009836#ifdef WLAN_BTAMP_FEATURE
9837 vStatus = WLANBAP_Open(pVosContext);
9838 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9839 {
9840 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9841 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009842 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009843 }
9844
9845 vStatus = BSL_Init(pVosContext);
9846 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9847 {
9848 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9849 "%s: Failed to Init BSL",__func__);
9850 goto err_bap_close;
9851 }
9852 vStatus = WLANBAP_Start(pVosContext);
9853 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9854 {
9855 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9856 "%s: Failed to start TL",__func__);
9857 goto err_bap_close;
9858 }
9859
9860 pConfig = pHddCtx->cfg_ini;
9861 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9862 status = WLANBAP_SetConfig(&btAmpConfig);
9863
9864#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009865
Mihir Shete9c238772014-10-15 14:35:16 +05309866 /*
9867 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9868 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9869 * which is greater than 0xf. So the below check is safe to make
9870 * sure that there is no entry for UapsdMask in the ini
9871 */
9872 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9873 {
9874 if(IS_DYNAMIC_WMM_PS_ENABLED)
9875 {
9876 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9877 __func__);
9878 pHddCtx->cfg_ini->UapsdMask =
9879 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9880 }
9881 else
9882 {
9883 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9884 __func__);
9885 pHddCtx->cfg_ini->UapsdMask =
9886 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9887 }
9888 }
9889
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009890#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9891 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9892 {
9893 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9894 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9895 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9896 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9897 }
9898#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009899
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309900 wlan_hdd_tdls_init(pHddCtx);
9901
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309902 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9903
Jeff Johnson295189b2012-06-20 16:38:30 -07009904 /* Register with platform driver as client for Suspend/Resume */
9905 status = hddRegisterPmOps(pHddCtx);
9906 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9907 {
9908 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9909#ifdef WLAN_BTAMP_FEATURE
9910 goto err_bap_stop;
9911#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009912 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009913#endif //WLAN_BTAMP_FEATURE
9914 }
9915
Yue Ma0d4891e2013-08-06 17:01:45 -07009916 /* Open debugfs interface */
9917 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9918 {
9919 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9920 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009921 }
9922
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 /* Register TM level change handler function to the platform */
9924 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9925 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9926 {
9927 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9928 goto err_unregister_pmops;
9929 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009930
9931 /* register for riva power on lock to platform driver */
9932 if (req_riva_power_on_lock("wlan"))
9933 {
9934 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9935 __func__);
9936 goto err_unregister_pmops;
9937 }
9938
Jeff Johnson295189b2012-06-20 16:38:30 -07009939 // register net device notifier for device change notification
9940 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9941
9942 if(ret < 0)
9943 {
9944 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9945 goto err_free_power_on_lock;
9946 }
9947
9948 //Initialize the nlink service
9949 if(nl_srv_init() != 0)
9950 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309951 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009952 goto err_reg_netdev;
9953 }
9954
Leo Chang4ce1cc52013-10-21 18:27:15 -07009955#ifdef WLAN_KD_READY_NOTIFIER
9956 pHddCtx->kd_nl_init = 1;
9957#endif /* WLAN_KD_READY_NOTIFIER */
9958
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 //Initialize the BTC service
9960 if(btc_activate_service(pHddCtx) != 0)
9961 {
9962 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9963 goto err_nl_srv;
9964 }
9965
9966#ifdef PTT_SOCK_SVC_ENABLE
9967 //Initialize the PTT service
9968 if(ptt_sock_activate_svc(pHddCtx) != 0)
9969 {
9970 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9971 goto err_nl_srv;
9972 }
9973#endif
9974
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309975#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9976 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9977 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309978 if(wlan_logging_sock_activate_svc(
9979 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9980 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9981 {
9982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9983 " failed", __func__);
9984 goto err_nl_srv;
9985 }
9986 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9987 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309988 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9989 pHddCtx->cfg_ini->gEnableDebugLog =
9990 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309991 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309992
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309993 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
9994 (pHddCtx->cfg_ini->enableFWLogging ||
9995 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309996 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309997 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309998 }
9999 else
10000 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010001 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010002 }
10003
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010004#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010005
10006
Sushant Kaushik215778f2015-05-21 14:05:36 +053010007 if (vos_is_multicast_logging())
10008 wlan_logging_set_log_level();
10009
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010013 /* Action frame registered in one adapter which will
10014 * applicable to all interfaces
10015 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010016 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010018
10019 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010020 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010021
Jeff Johnsone7245742012-09-05 17:12:55 -070010022#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10023 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010024 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010025 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010026
Jeff Johnsone7245742012-09-05 17:12:55 -070010027#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010028 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010029 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010030 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010031
Jeff Johnsone7245742012-09-05 17:12:55 -070010032
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010033 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10034 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010035
Katya Nigam5c306ea2014-06-19 15:39:54 +053010036 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010038 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010039
10040#ifdef FEATURE_WLAN_SCAN_PNO
10041 /*SME must send channel update configuration to RIVA*/
10042 sme_UpdateChannelConfig(pHddCtx->hHal);
10043#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010044 /* Send the update default channel list to the FW*/
10045 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010046
10047 /* Fwr capabilities received, Set the Dot11 mode */
10048 sme_SetDefDot11Mode(pHddCtx->hHal);
10049
Abhishek Singha306a442013-11-07 18:39:01 +053010050#ifndef CONFIG_ENABLE_LINUX_REG
10051 /*updating wiphy so that regulatory user hints can be processed*/
10052 if (wiphy)
10053 {
10054 regulatory_hint(wiphy, "00");
10055 }
10056#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010057 // Initialize the restart logic
10058 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010059
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010060 //Register the traffic monitor timer now
10061 if ( pHddCtx->cfg_ini->dynSplitscan)
10062 {
10063 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10064 VOS_TIMER_TYPE_SW,
10065 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10066 (void *)pHddCtx);
10067 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010068 wlan_hdd_cfg80211_nan_init(pHddCtx);
10069
Dino Mycle6fb96c12014-06-10 11:52:40 +053010070#ifdef WLAN_FEATURE_EXTSCAN
10071 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10072 wlan_hdd_cfg80211_extscan_callback,
10073 pHddCtx);
10074#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010075
10076#ifdef WLAN_NS_OFFLOAD
10077 // Register IPv6 notifier to notify if any change in IP
10078 // So that we can reconfigure the offload parameters
10079 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10080 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10081 if (ret)
10082 {
10083 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10084 }
10085 else
10086 {
10087 hddLog(LOGE, FL("Registered IPv6 notifier"));
10088 }
10089#endif
10090
10091 // Register IPv4 notifier to notify if any change in IP
10092 // So that we can reconfigure the offload parameters
10093 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10094 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10095 if (ret)
10096 {
10097 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10098 }
10099 else
10100 {
10101 hddLog(LOGE, FL("Registered IPv4 notifier"));
10102 }
10103
Jeff Johnson295189b2012-06-20 16:38:30 -070010104 goto success;
10105
10106err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010107#ifdef WLAN_KD_READY_NOTIFIER
10108 nl_srv_exit(pHddCtx->ptt_pid);
10109#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010110 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010111#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010112err_reg_netdev:
10113 unregister_netdevice_notifier(&hdd_netdev_notifier);
10114
10115err_free_power_on_lock:
10116 free_riva_power_on_lock("wlan");
10117
10118err_unregister_pmops:
10119 hddDevTmUnregisterNotifyCallback(pHddCtx);
10120 hddDeregisterPmOps(pHddCtx);
10121
Yue Ma0d4891e2013-08-06 17:01:45 -070010122 hdd_debugfs_exit(pHddCtx);
10123
Jeff Johnson295189b2012-06-20 16:38:30 -070010124#ifdef WLAN_BTAMP_FEATURE
10125err_bap_stop:
10126 WLANBAP_Stop(pVosContext);
10127#endif
10128
10129#ifdef WLAN_BTAMP_FEATURE
10130err_bap_close:
10131 WLANBAP_Close(pVosContext);
10132#endif
10133
Jeff Johnson295189b2012-06-20 16:38:30 -070010134err_close_adapter:
10135 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010136#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010137err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010138#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010139 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010140err_vosstop:
10141 vos_stop(pVosContext);
10142
Amar Singhala49cbc52013-10-08 18:37:44 -070010143err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010144 status = vos_sched_close( pVosContext );
10145 if (!VOS_IS_STATUS_SUCCESS(status)) {
10146 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10147 "%s: Failed to close VOSS Scheduler", __func__);
10148 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10149 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010150 vos_close(pVosContext );
10151
Amar Singhal0a402232013-10-11 20:57:16 -070010152err_vos_nv_close:
10153
c_hpothue6a36282014-03-19 12:27:38 +053010154#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010155 vos_nv_close();
10156
c_hpothu70f8d812014-03-22 22:59:23 +053010157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010158
10159err_wdclose:
10160 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10161 vos_watchdog_close(pVosContext);
10162
Jeff Johnson295189b2012-06-20 16:38:30 -070010163err_config:
10164 kfree(pHddCtx->cfg_ini);
10165 pHddCtx->cfg_ini= NULL;
10166
10167err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010168 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Jeff Johnson295189b2012-06-20 16:38:30 -070010169 wiphy_free(wiphy) ;
10170 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 VOS_BUG(1);
10172
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010173 if (hdd_is_ssr_required())
10174 {
10175 /* WDI timeout had happened during load, so SSR is needed here */
10176 subsystem_restart("wcnss");
10177 msleep(5000);
10178 }
10179 hdd_set_ssr_required (VOS_FALSE);
10180
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010181 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010182
10183success:
10184 EXIT();
10185 return 0;
10186}
10187
10188/**---------------------------------------------------------------------------
10189
Jeff Johnson32d95a32012-09-10 13:15:23 -070010190 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010191
Jeff Johnson32d95a32012-09-10 13:15:23 -070010192 This is the driver entry point - called in different timeline depending
10193 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010194
10195 \param - None
10196
10197 \return - 0 for success, non zero for failure
10198
10199 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010200static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010201{
10202 VOS_STATUS status;
10203 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 struct device *dev = NULL;
10205 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010206#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10207 int max_retries = 0;
10208#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010209#ifdef HAVE_CBC_DONE
10210 int max_cbc_retries = 0;
10211#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010212
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010213#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10214 wlan_logging_sock_init_svc();
10215#endif
10216
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 ENTER();
10218
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010219 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010220
10221 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10222 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10223
Jeff Johnson295189b2012-06-20 16:38:30 -070010224#ifdef ANI_BUS_TYPE_PCI
10225
10226 dev = wcnss_wlan_get_device();
10227
10228#endif // ANI_BUS_TYPE_PCI
10229
10230#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010231
10232#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10233 /* wait until WCNSS driver downloads NV */
10234 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10235 msleep(1000);
10236 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010237
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010238 if (max_retries >= 5) {
10239 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010240 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010241#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10242 wlan_logging_sock_deinit_svc();
10243#endif
10244
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010245 return -ENODEV;
10246 }
10247#endif
10248
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010249#ifdef HAVE_CBC_DONE
10250 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10251 msleep(1000);
10252 }
10253 if (max_cbc_retries >= 10) {
10254 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10255 }
10256#endif
10257
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 dev = wcnss_wlan_get_device();
10259#endif // ANI_BUS_TYPE_PLATFORM
10260
10261
10262 do {
10263 if (NULL == dev) {
10264 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10265 ret_status = -1;
10266 break;
10267 }
10268
Jeff Johnson295189b2012-06-20 16:38:30 -070010269#ifdef TIMER_MANAGER
10270 vos_timer_manager_init();
10271#endif
10272
10273 /* Preopen VOSS so that it is ready to start at least SAL */
10274 status = vos_preOpen(&pVosContext);
10275
10276 if (!VOS_IS_STATUS_SUCCESS(status))
10277 {
10278 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10279 ret_status = -1;
10280 break;
10281 }
10282
Sushant Kaushik02beb352015-06-04 15:15:01 +053010283 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010284#ifndef MODULE
10285 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10286 */
10287 hdd_set_conparam((v_UINT_t)con_mode);
10288#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010289
10290 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010291 if (hdd_wlan_startup(dev))
10292 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010293 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010294 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010295 vos_preClose( &pVosContext );
10296 ret_status = -1;
10297 break;
10298 }
10299
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 } while (0);
10301
10302 if (0 != ret_status)
10303 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010304#ifdef TIMER_MANAGER
10305 vos_timer_exit();
10306#endif
10307#ifdef MEMORY_DEBUG
10308 vos_mem_exit();
10309#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010310 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010311#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10312 wlan_logging_sock_deinit_svc();
10313#endif
10314
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10316 }
10317 else
10318 {
10319 //Send WLAN UP indication to Nlink Service
10320 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10321
10322 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 }
10324
10325 EXIT();
10326
10327 return ret_status;
10328}
10329
Jeff Johnson32d95a32012-09-10 13:15:23 -070010330/**---------------------------------------------------------------------------
10331
10332 \brief hdd_module_init() - Init Function
10333
10334 This is the driver entry point (invoked when module is loaded using insmod)
10335
10336 \param - None
10337
10338 \return - 0 for success, non zero for failure
10339
10340 --------------------------------------------------------------------------*/
10341#ifdef MODULE
10342static int __init hdd_module_init ( void)
10343{
10344 return hdd_driver_init();
10345}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010346#else /* #ifdef MODULE */
10347static int __init hdd_module_init ( void)
10348{
10349 /* Driver initialization is delayed to fwpath_changed_handler */
10350 return 0;
10351}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010352#endif /* #ifdef MODULE */
10353
Jeff Johnson295189b2012-06-20 16:38:30 -070010354
10355/**---------------------------------------------------------------------------
10356
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010357 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010358
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010359 This is the driver exit point (invoked when module is unloaded using rmmod
10360 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010361
10362 \param - None
10363
10364 \return - None
10365
10366 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010367static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010368{
10369 hdd_context_t *pHddCtx = NULL;
10370 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010371 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010372 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010373
10374 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10375
10376 //Get the global vos context
10377 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10378
10379 if(!pVosContext)
10380 {
10381 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10382 goto done;
10383 }
10384
10385 //Get the HDD context.
10386 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10387
10388 if(!pHddCtx)
10389 {
10390 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10391 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010392 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10393 {
10394 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10395 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10396 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10397 hdd_wlan_exit(pHddCtx);
10398 vos_preClose( &pVosContext );
10399 goto done;
10400 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010401 else
10402 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010403 /* We wait for active entry threads to exit from driver
10404 * by waiting until rtnl_lock is available.
10405 */
10406 rtnl_lock();
10407 rtnl_unlock();
10408
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010409 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10410 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10411 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10412 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010414 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010415 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10416 msecs_to_jiffies(30000));
10417 if(!rc)
10418 {
10419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10420 "%s:SSR timedout, fatal error", __func__);
10421 VOS_BUG(0);
10422 }
10423 }
10424
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010425 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10426 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010427
c_hpothu8adb97b2014-12-08 19:38:20 +053010428 /* Driver Need to send country code 00 in below condition
10429 * 1) If gCountryCodePriority is set to 1; and last country
10430 * code set is through 11d. This needs to be done in case
10431 * when NV country code is 00.
10432 * This Needs to be done as when kernel store last country
10433 * code and if stored country code is not through 11d,
10434 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10435 * in next load/unload as soon as we get any country through
10436 * 11d. In sme_HandleChangeCountryCodeByUser
10437 * pMsg->countryCode will be last countryCode and
10438 * pMac->scan.countryCode11d will be country through 11d so
10439 * due to mismatch driver will disable 11d.
10440 *
10441 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010442
c_hpothu8adb97b2014-12-08 19:38:20 +053010443 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010444 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010445 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010446 {
10447 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010448 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010449 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10450 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010451
c_hpothu8adb97b2014-12-08 19:38:20 +053010452 //Do all the cleanup before deregistering the driver
10453 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 }
10455
Jeff Johnson295189b2012-06-20 16:38:30 -070010456 vos_preClose( &pVosContext );
10457
10458#ifdef TIMER_MANAGER
10459 vos_timer_exit();
10460#endif
10461#ifdef MEMORY_DEBUG
10462 vos_mem_exit();
10463#endif
10464
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010465#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10466 wlan_logging_sock_deinit_svc();
10467#endif
10468
Jeff Johnson295189b2012-06-20 16:38:30 -070010469done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010470 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010471
Jeff Johnson295189b2012-06-20 16:38:30 -070010472 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10473}
10474
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010475/**---------------------------------------------------------------------------
10476
10477 \brief hdd_module_exit() - Exit function
10478
10479 This is the driver exit point (invoked when module is unloaded using rmmod)
10480
10481 \param - None
10482
10483 \return - None
10484
10485 --------------------------------------------------------------------------*/
10486static void __exit hdd_module_exit(void)
10487{
10488 hdd_driver_exit();
10489}
10490
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010491#ifdef MODULE
10492static int fwpath_changed_handler(const char *kmessage,
10493 struct kernel_param *kp)
10494{
Jeff Johnson76052702013-04-16 13:55:05 -070010495 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010496}
10497
10498static int con_mode_handler(const char *kmessage,
10499 struct kernel_param *kp)
10500{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010501 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010502}
10503#else /* #ifdef MODULE */
10504/**---------------------------------------------------------------------------
10505
Jeff Johnson76052702013-04-16 13:55:05 -070010506 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010507
Jeff Johnson76052702013-04-16 13:55:05 -070010508 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010509 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010510 - invoked when module parameter fwpath is modified from userspace to signal
10511 initializing the WLAN driver or when con_mode is modified from userspace
10512 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010513
10514 \return - 0 for success, non zero for failure
10515
10516 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010517static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010518{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010519 int ret_status;
10520
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010521 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010522 ret_status = hdd_driver_init();
10523 wlan_hdd_inited = ret_status ? 0 : 1;
10524 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010525 }
10526
10527 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010528
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010529 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010530
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010531 ret_status = hdd_driver_init();
10532 wlan_hdd_inited = ret_status ? 0 : 1;
10533 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010534}
10535
Jeff Johnson295189b2012-06-20 16:38:30 -070010536/**---------------------------------------------------------------------------
10537
Jeff Johnson76052702013-04-16 13:55:05 -070010538 \brief fwpath_changed_handler() - Handler Function
10539
10540 Handle changes to the fwpath parameter
10541
10542 \return - 0 for success, non zero for failure
10543
10544 --------------------------------------------------------------------------*/
10545static int fwpath_changed_handler(const char *kmessage,
10546 struct kernel_param *kp)
10547{
10548 int ret;
10549
10550 ret = param_set_copystring(kmessage, kp);
10551 if (0 == ret)
10552 ret = kickstart_driver();
10553 return ret;
10554}
10555
10556/**---------------------------------------------------------------------------
10557
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010558 \brief con_mode_handler() -
10559
10560 Handler function for module param con_mode when it is changed by userspace
10561 Dynamically linked - do nothing
10562 Statically linked - exit and init driver, as in rmmod and insmod
10563
Jeff Johnson76052702013-04-16 13:55:05 -070010564 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010565
Jeff Johnson76052702013-04-16 13:55:05 -070010566 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010567
10568 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010569static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010570{
Jeff Johnson76052702013-04-16 13:55:05 -070010571 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010572
Jeff Johnson76052702013-04-16 13:55:05 -070010573 ret = param_set_int(kmessage, kp);
10574 if (0 == ret)
10575 ret = kickstart_driver();
10576 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010577}
10578#endif /* #ifdef MODULE */
10579
10580/**---------------------------------------------------------------------------
10581
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 \brief hdd_get_conparam() -
10583
10584 This is the driver exit point (invoked when module is unloaded using rmmod)
10585
10586 \param - None
10587
10588 \return - tVOS_CON_MODE
10589
10590 --------------------------------------------------------------------------*/
10591tVOS_CON_MODE hdd_get_conparam ( void )
10592{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010593#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010594 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010595#else
10596 return (tVOS_CON_MODE)curr_con_mode;
10597#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010598}
10599void hdd_set_conparam ( v_UINT_t newParam )
10600{
10601 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010602#ifndef MODULE
10603 curr_con_mode = con_mode;
10604#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010605}
10606/**---------------------------------------------------------------------------
10607
10608 \brief hdd_softap_sta_deauth() - function
10609
10610 This to take counter measure to handle deauth req from HDD
10611
10612 \param - pAdapter - Pointer to the HDD
10613
10614 \param - enable - boolean value
10615
10616 \return - None
10617
10618 --------------------------------------------------------------------------*/
10619
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010620VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10621 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010622{
Jeff Johnson295189b2012-06-20 16:38:30 -070010623 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010624 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010625
10626 ENTER();
10627
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010628 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10629 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010630
10631 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010632 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010633 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010634
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010635 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010636
10637 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010638 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010639}
10640
10641/**---------------------------------------------------------------------------
10642
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010643 \brief hdd_del_all_sta() - function
10644
10645 This function removes all the stations associated on stopping AP/P2P GO.
10646
10647 \param - pAdapter - Pointer to the HDD
10648
10649 \return - None
10650
10651 --------------------------------------------------------------------------*/
10652
10653int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10654{
10655 v_U16_t i;
10656 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010657 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10658 ptSapContext pSapCtx = NULL;
10659 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10660 if(pSapCtx == NULL){
10661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10662 FL("psapCtx is NULL"));
10663 return 1;
10664 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010665 ENTER();
10666
10667 hddLog(VOS_TRACE_LEVEL_INFO,
10668 "%s: Delete all STAs associated.",__func__);
10669 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10670 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10671 )
10672 {
10673 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10674 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010675 if ((pSapCtx->aStaInfo[i].isUsed) &&
10676 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010677 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010678 struct tagCsrDelStaParams delStaParams;
10679
10680 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010681 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010682 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10683 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010684 &delStaParams);
10685 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010686 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010687 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010688 }
10689 }
10690 }
10691
10692 EXIT();
10693 return 0;
10694}
10695
10696/**---------------------------------------------------------------------------
10697
Jeff Johnson295189b2012-06-20 16:38:30 -070010698 \brief hdd_softap_sta_disassoc() - function
10699
10700 This to take counter measure to handle deauth req from HDD
10701
10702 \param - pAdapter - Pointer to the HDD
10703
10704 \param - enable - boolean value
10705
10706 \return - None
10707
10708 --------------------------------------------------------------------------*/
10709
10710void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10711{
10712 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10713
10714 ENTER();
10715
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010716 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010717
10718 //Ignore request to disassoc bcmc station
10719 if( pDestMacAddress[0] & 0x1 )
10720 return;
10721
10722 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10723}
10724
10725void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10726{
10727 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10728
10729 ENTER();
10730
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010731 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010732
10733 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10734}
10735
Jeff Johnson295189b2012-06-20 16:38:30 -070010736/**---------------------------------------------------------------------------
10737 *
10738 * \brief hdd_get__concurrency_mode() -
10739 *
10740 *
10741 * \param - None
10742 *
10743 * \return - CONCURRENCY MODE
10744 *
10745 * --------------------------------------------------------------------------*/
10746tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10747{
10748 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10749 hdd_context_t *pHddCtx;
10750
10751 if (NULL != pVosContext)
10752 {
10753 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10754 if (NULL != pHddCtx)
10755 {
10756 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10757 }
10758 }
10759
10760 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010761 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010762 return VOS_STA;
10763}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010764v_BOOL_t
10765wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10766{
10767 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010768
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010769 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10770 if (pAdapter == NULL)
10771 {
10772 hddLog(VOS_TRACE_LEVEL_INFO,
10773 FL("GO doesn't exist"));
10774 return TRUE;
10775 }
10776 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10777 {
10778 hddLog(VOS_TRACE_LEVEL_INFO,
10779 FL("GO started"));
10780 return TRUE;
10781 }
10782 else
10783 /* wait till GO changes its interface to p2p device */
10784 hddLog(VOS_TRACE_LEVEL_INFO,
10785 FL("Del_bss called, avoid apps suspend"));
10786 return FALSE;
10787
10788}
Jeff Johnson295189b2012-06-20 16:38:30 -070010789/* Decide whether to allow/not the apps power collapse.
10790 * Allow apps power collapse if we are in connected state.
10791 * if not, allow only if we are in IMPS */
10792v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10793{
10794 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010795 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010796 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010797 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10798 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10799 hdd_adapter_t *pAdapter = NULL;
10800 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010801 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010802
Jeff Johnson295189b2012-06-20 16:38:30 -070010803 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10804 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010805
Yathish9f22e662012-12-10 14:21:35 -080010806 concurrent_state = hdd_get_concurrency_mode();
10807
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010808 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10809 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10810 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010811#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010812
Yathish9f22e662012-12-10 14:21:35 -080010813 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010814 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010815 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10816 return TRUE;
10817#endif
10818
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 /*loop through all adapters. TBD fix for Concurrency */
10820 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10821 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10822 {
10823 pAdapter = pAdapterNode->pAdapter;
10824 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10825 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10826 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010827 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010828 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010829 && pmcState != STOPPED && pmcState != STANDBY &&
10830 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010831 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10832 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010833 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010834 if(pmcState == FULL_POWER &&
10835 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10836 {
10837 /*
10838 * When SCO indication comes from Coex module , host will
10839 * enter in to full power mode, but this should not prevent
10840 * apps processor power collapse.
10841 */
10842 hddLog(LOG1,
10843 FL("Allow apps power collapse"
10844 "even when sco indication is set"));
10845 return TRUE;
10846 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010847 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010848 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10849 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010850 return FALSE;
10851 }
10852 }
10853 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10854 pAdapterNode = pNext;
10855 }
10856 return TRUE;
10857}
10858
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010859/* Decides whether to send suspend notification to Riva
10860 * if any adapter is in BMPS; then it is required */
10861v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10862{
10863 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10864 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10865
10866 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10867 {
10868 return TRUE;
10869 }
10870 return FALSE;
10871}
10872
Jeff Johnson295189b2012-06-20 16:38:30 -070010873void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10874{
10875 switch(mode)
10876 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010877 case VOS_STA_MODE:
10878 case VOS_P2P_CLIENT_MODE:
10879 case VOS_P2P_GO_MODE:
10880 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010881 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010882 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010883 break;
10884 default:
10885 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010886 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010887 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10888 "Number of open sessions for mode %d = %d"),
10889 pHddCtx->concurrency_mode, mode,
10890 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010891}
10892
10893
10894void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10895{
10896 switch(mode)
10897 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010898 case VOS_STA_MODE:
10899 case VOS_P2P_CLIENT_MODE:
10900 case VOS_P2P_GO_MODE:
10901 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010902 pHddCtx->no_of_open_sessions[mode]--;
10903 if (!(pHddCtx->no_of_open_sessions[mode]))
10904 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 break;
10906 default:
10907 break;
10908 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010909 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10910 "Number of open sessions for mode %d = %d"),
10911 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10912
10913}
10914/**---------------------------------------------------------------------------
10915 *
10916 * \brief wlan_hdd_incr_active_session()
10917 *
10918 * This function increments the number of active sessions
10919 * maintained per device mode
10920 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10921 * Incase of SAP/P2P GO upon bss start it is incremented
10922 *
10923 * \param pHddCtx - HDD Context
10924 * \param mode - device mode
10925 *
10926 * \return - None
10927 *
10928 * --------------------------------------------------------------------------*/
10929void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10930{
10931 switch (mode) {
10932 case VOS_STA_MODE:
10933 case VOS_P2P_CLIENT_MODE:
10934 case VOS_P2P_GO_MODE:
10935 case VOS_STA_SAP_MODE:
10936 pHddCtx->no_of_active_sessions[mode]++;
10937 break;
10938 default:
10939 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10940 break;
10941 }
10942 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10943 mode,
10944 pHddCtx->no_of_active_sessions[mode]);
10945}
10946
10947/**---------------------------------------------------------------------------
10948 *
10949 * \brief wlan_hdd_decr_active_session()
10950 *
10951 * This function decrements the number of active sessions
10952 * maintained per device mode
10953 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10954 * Incase of SAP/P2P GO upon bss stop it is decremented
10955 *
10956 * \param pHddCtx - HDD Context
10957 * \param mode - device mode
10958 *
10959 * \return - None
10960 *
10961 * --------------------------------------------------------------------------*/
10962void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10963{
10964 switch (mode) {
10965 case VOS_STA_MODE:
10966 case VOS_P2P_CLIENT_MODE:
10967 case VOS_P2P_GO_MODE:
10968 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010969 if (pHddCtx->no_of_active_sessions[mode] > 0)
10970 pHddCtx->no_of_active_sessions[mode]--;
10971 else
10972 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10973 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010974 break;
10975 default:
10976 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10977 break;
10978 }
10979 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10980 mode,
10981 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010982}
10983
Jeff Johnsone7245742012-09-05 17:12:55 -070010984/**---------------------------------------------------------------------------
10985 *
10986 * \brief wlan_hdd_restart_init
10987 *
10988 * This function initalizes restart timer/flag. An internal function.
10989 *
10990 * \param - pHddCtx
10991 *
10992 * \return - None
10993 *
10994 * --------------------------------------------------------------------------*/
10995
10996static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10997{
10998 /* Initialize */
10999 pHddCtx->hdd_restart_retries = 0;
11000 atomic_set(&pHddCtx->isRestartInProgress, 0);
11001 vos_timer_init(&pHddCtx->hdd_restart_timer,
11002 VOS_TIMER_TYPE_SW,
11003 wlan_hdd_restart_timer_cb,
11004 pHddCtx);
11005}
11006/**---------------------------------------------------------------------------
11007 *
11008 * \brief wlan_hdd_restart_deinit
11009 *
11010 * This function cleans up the resources used. An internal function.
11011 *
11012 * \param - pHddCtx
11013 *
11014 * \return - None
11015 *
11016 * --------------------------------------------------------------------------*/
11017
11018static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11019{
11020
11021 VOS_STATUS vos_status;
11022 /* Block any further calls */
11023 atomic_set(&pHddCtx->isRestartInProgress, 1);
11024 /* Cleanup */
11025 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11026 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011027 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011028 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11029 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011030 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011031
11032}
11033
11034/**---------------------------------------------------------------------------
11035 *
11036 * \brief wlan_hdd_framework_restart
11037 *
11038 * This function uses a cfg80211 API to start a framework initiated WLAN
11039 * driver module unload/load.
11040 *
11041 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11042 *
11043 *
11044 * \param - pHddCtx
11045 *
11046 * \return - VOS_STATUS_SUCCESS: Success
11047 * VOS_STATUS_E_EMPTY: Adapter is Empty
11048 * VOS_STATUS_E_NOMEM: No memory
11049
11050 * --------------------------------------------------------------------------*/
11051
11052static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11053{
11054 VOS_STATUS status = VOS_STATUS_SUCCESS;
11055 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011056 int len = (sizeof (struct ieee80211_mgmt));
11057 struct ieee80211_mgmt *mgmt = NULL;
11058
11059 /* Prepare the DEAUTH managment frame with reason code */
11060 mgmt = kzalloc(len, GFP_KERNEL);
11061 if(mgmt == NULL)
11062 {
11063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11064 "%s: memory allocation failed (%d bytes)", __func__, len);
11065 return VOS_STATUS_E_NOMEM;
11066 }
11067 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011068
11069 /* Iterate over all adapters/devices */
11070 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011071 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11072 {
11073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11074 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11075 goto end;
11076 }
11077
Jeff Johnsone7245742012-09-05 17:12:55 -070011078 do
11079 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011080 if(pAdapterNode->pAdapter &&
11081 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011082 {
11083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11084 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11085 pAdapterNode->pAdapter->dev->name,
11086 pAdapterNode->pAdapter->device_mode,
11087 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011088 /*
11089 * CFG80211 event to restart the driver
11090 *
11091 * 'cfg80211_send_unprot_deauth' sends a
11092 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11093 * of SME(Linux Kernel) state machine.
11094 *
11095 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11096 * the driver.
11097 *
11098 */
11099
11100 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011101 }
11102 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11103 pAdapterNode = pNext;
11104 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11105
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011106 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011107 /* Free the allocated management frame */
11108 kfree(mgmt);
11109
Jeff Johnsone7245742012-09-05 17:12:55 -070011110 /* Retry until we unload or reach max count */
11111 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11112 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11113
11114 return status;
11115
11116}
11117/**---------------------------------------------------------------------------
11118 *
11119 * \brief wlan_hdd_restart_timer_cb
11120 *
11121 * Restart timer callback. An internal function.
11122 *
11123 * \param - User data:
11124 *
11125 * \return - None
11126 *
11127 * --------------------------------------------------------------------------*/
11128
11129void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11130{
11131 hdd_context_t *pHddCtx = usrDataForCallback;
11132 wlan_hdd_framework_restart(pHddCtx);
11133 return;
11134
11135}
11136
11137
11138/**---------------------------------------------------------------------------
11139 *
11140 * \brief wlan_hdd_restart_driver
11141 *
11142 * This function sends an event to supplicant to restart the WLAN driver.
11143 *
11144 * This function is called from vos_wlanRestart.
11145 *
11146 * \param - pHddCtx
11147 *
11148 * \return - VOS_STATUS_SUCCESS: Success
11149 * VOS_STATUS_E_EMPTY: Adapter is Empty
11150 * VOS_STATUS_E_ALREADY: Request already in progress
11151
11152 * --------------------------------------------------------------------------*/
11153VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11154{
11155 VOS_STATUS status = VOS_STATUS_SUCCESS;
11156
11157 /* A tight check to make sure reentrancy */
11158 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11159 {
Mihir Shetefd528652014-06-23 19:07:50 +053011160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011161 "%s: WLAN restart is already in progress", __func__);
11162
11163 return VOS_STATUS_E_ALREADY;
11164 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011165 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011166#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011167 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011168#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011169
Jeff Johnsone7245742012-09-05 17:12:55 -070011170 return status;
11171}
11172
Mihir Shetee1093ba2014-01-21 20:13:32 +053011173/**---------------------------------------------------------------------------
11174 *
11175 * \brief wlan_hdd_init_channels
11176 *
11177 * This function is used to initialize the channel list in CSR
11178 *
11179 * This function is called from hdd_wlan_startup
11180 *
11181 * \param - pHddCtx: HDD context
11182 *
11183 * \return - VOS_STATUS_SUCCESS: Success
11184 * VOS_STATUS_E_FAULT: Failure reported by SME
11185
11186 * --------------------------------------------------------------------------*/
11187static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11188{
11189 eHalStatus status;
11190
11191 status = sme_InitChannels(pHddCtx->hHal);
11192 if (HAL_STATUS_SUCCESS(status))
11193 {
11194 return VOS_STATUS_SUCCESS;
11195 }
11196 else
11197 {
11198 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11199 __func__, status);
11200 return VOS_STATUS_E_FAULT;
11201 }
11202}
11203
Mihir Shete04206452014-11-20 17:50:58 +053011204#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011205VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011206{
11207 eHalStatus status;
11208
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011209 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011210 if (HAL_STATUS_SUCCESS(status))
11211 {
11212 return VOS_STATUS_SUCCESS;
11213 }
11214 else
11215 {
11216 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11217 __func__, status);
11218 return VOS_STATUS_E_FAULT;
11219 }
11220}
Mihir Shete04206452014-11-20 17:50:58 +053011221#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011222/*
11223 * API to find if there is any STA or P2P-Client is connected
11224 */
11225VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11226{
11227 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11228}
Jeff Johnsone7245742012-09-05 17:12:55 -070011229
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011230
11231/*
11232 * API to find if the firmware will send logs using DXE channel
11233 */
11234v_U8_t hdd_is_fw_logging_enabled(void)
11235{
11236 hdd_context_t *pHddCtx;
11237
11238 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11239 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11240
Sachin Ahuja084313e2015-05-21 17:57:10 +053011241 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011242}
11243
Agarwal Ashish57e84372014-12-05 18:26:53 +053011244/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011245 * API to find if the firmware will send trace logs using DXE channel
11246 */
11247v_U8_t hdd_is_fw_ev_logging_enabled(void)
11248{
11249 hdd_context_t *pHddCtx;
11250
11251 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11252 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11253
11254 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11255}
11256/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011257 * API to find if there is any session connected
11258 */
11259VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11260{
11261 return sme_is_any_session_connected(pHddCtx->hHal);
11262}
11263
11264
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011265int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11266{
11267 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11268 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011269 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011270 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011271
11272 pScanInfo = &pHddCtx->scan_info;
11273 if (pScanInfo->mScanPending)
11274 {
c_hpothua3d45d52015-01-05 14:11:17 +053011275 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11276 eCSR_SCAN_ABORT_DEFAULT);
11277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11278 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011279
c_hpothua3d45d52015-01-05 14:11:17 +053011280 /* If there is active scan command lets wait for the completion else
11281 * there is no need to wait as scan command might be in the SME pending
11282 * command list.
11283 */
11284 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11285 {
11286 INIT_COMPLETION(pScanInfo->abortscan_event_var);
11287 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011288 &pScanInfo->abortscan_event_var,
11289 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011290 if (0 >= status)
11291 {
11292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011293 "%s: Timeout or Interrupt occurred while waiting for abort"
11294 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011295 return -ETIMEDOUT;
11296 }
11297 }
11298 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11299 {
11300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11301 FL("hdd_abort_mac_scan failed"));
11302 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011303 }
11304 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011305 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011306}
11307
c_hpothu225aa7c2014-10-22 17:45:13 +053011308VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11309{
11310 hdd_adapter_t *pAdapter;
11311 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11312 VOS_STATUS vosStatus;
11313
11314 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11315 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11316 {
11317 pAdapter = pAdapterNode->pAdapter;
11318 if (NULL != pAdapter)
11319 {
11320 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11321 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11322 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11323 {
11324 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11325 pAdapter->device_mode);
11326 if (VOS_STATUS_SUCCESS !=
11327 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11328 {
11329 hddLog(LOGE, FL("failed to abort ROC"));
11330 return VOS_STATUS_E_FAILURE;
11331 }
11332 }
11333 }
11334 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11335 pAdapterNode = pNext;
11336 }
11337 return VOS_STATUS_SUCCESS;
11338}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011339
Mihir Shete0be28772015-02-17 18:42:14 +053011340hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11341{
11342 hdd_adapter_t *pAdapter;
11343 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11344 hdd_cfg80211_state_t *cfgState;
11345 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11346 VOS_STATUS vosStatus;
11347
11348 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11349 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11350 {
11351 pAdapter = pAdapterNode->pAdapter;
11352 if (NULL != pAdapter)
11353 {
11354 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11355 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11356 if (pRemainChanCtx)
11357 break;
11358 }
11359 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11360 pAdapterNode = pNext;
11361 }
11362 return pRemainChanCtx;
11363}
11364
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011365/**
11366 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11367 *
11368 * @pHddCtx: HDD context within host driver
11369 * @dfsScanMode: dfsScanMode passed from ioctl
11370 *
11371 */
11372
11373VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11374 tANI_U8 dfsScanMode)
11375{
11376 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11377 hdd_adapter_t *pAdapter;
11378 VOS_STATUS vosStatus;
11379 hdd_station_ctx_t *pHddStaCtx;
11380 eHalStatus status = eHAL_STATUS_SUCCESS;
11381
11382 if(!pHddCtx)
11383 {
11384 hddLog(LOGE, FL("HDD context is Null"));
11385 return eHAL_STATUS_FAILURE;
11386 }
11387
11388 if (pHddCtx->scan_info.mScanPending)
11389 {
11390 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11391 pHddCtx->scan_info.sessionId);
11392 hdd_abort_mac_scan(pHddCtx,
11393 pHddCtx->scan_info.sessionId,
11394 eCSR_SCAN_ABORT_DEFAULT);
11395 }
11396
11397 if (!dfsScanMode)
11398 {
11399 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11400 while ((NULL != pAdapterNode) &&
11401 (VOS_STATUS_SUCCESS == vosStatus))
11402 {
11403 pAdapter = pAdapterNode->pAdapter;
11404
11405 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11406 {
11407 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11408
11409 if(!pHddStaCtx)
11410 {
11411 hddLog(LOGE, FL("HDD STA context is Null"));
11412 return eHAL_STATUS_FAILURE;
11413 }
11414
11415 /* if STA is already connected on DFS channel,
11416 disconnect immediately*/
11417 if (hdd_connIsConnected(pHddStaCtx) &&
11418 (NV_CHANNEL_DFS ==
11419 vos_nv_getChannelEnabledState(
11420 pHddStaCtx->conn_info.operationChannel)))
11421 {
11422 status = sme_RoamDisconnect(pHddCtx->hHal,
11423 pAdapter->sessionId,
11424 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11425 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11426 "sme_RoamDisconnect returned with status: %d"
11427 "for sessionid: %d"), pHddStaCtx->conn_info.
11428 operationChannel, status, pAdapter->sessionId);
11429 }
11430 }
11431
11432 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11433 &pNext);
11434 pAdapterNode = pNext;
11435 }
11436 }
11437
11438 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11439 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11440 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11441
11442 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11443 if (!HAL_STATUS_SUCCESS(status))
11444 {
11445 hddLog(LOGE,
11446 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11447 return status;
11448 }
11449
11450 return status;
11451}
11452
Jeff Johnson295189b2012-06-20 16:38:30 -070011453//Register the module init/exit functions
11454module_init(hdd_module_init);
11455module_exit(hdd_module_exit);
11456
11457MODULE_LICENSE("Dual BSD/GPL");
11458MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11459MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11460
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011461module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11462 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011463
Jeff Johnson76052702013-04-16 13:55:05 -070011464module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011465 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011466
11467module_param(enable_dfs_chan_scan, int,
11468 S_IRUSR | S_IRGRP | S_IROTH);
11469
11470module_param(enable_11d, int,
11471 S_IRUSR | S_IRGRP | S_IROTH);
11472
11473module_param(country_code, charp,
11474 S_IRUSR | S_IRGRP | S_IROTH);