blob: 7e2075ac4d3f3d487fcc34623db47761782a87f3 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530197static vos_wake_lock_t wlan_wake_lock;
198
Jeff Johnson295189b2012-06-20 16:38:30 -0700199/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700200static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700203static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
204static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
206void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800207void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700208
Jeff Johnson295189b2012-06-20 16:38:30 -0700209v_U16_t hdd_select_queue(struct net_device *dev,
210 struct sk_buff *skb);
211
212#ifdef WLAN_FEATURE_PACKET_FILTERING
213static void hdd_set_multicast_list(struct net_device *dev);
214#endif
215
216void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
217
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800218#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800219void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
220static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700221static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
222 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
223 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700224static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
225 tANI_U8 *pTargetApBssid,
226 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800227#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530228
229/* Store WLAN driver info in a global variable such that crash debugger
230 can extract it from driver debug symbol and crashdump for post processing */
231tANI_U8 g_wlan_driver[ ] = "pronto_driver";
232
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800233#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700234VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800235#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700236
Mihir Shetee1093ba2014-01-21 20:13:32 +0530237static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530238const char * hdd_device_modetoString(v_U8_t device_mode)
239{
240 switch(device_mode)
241 {
242 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
243 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
244 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
246 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
247 CASE_RETURN_STRING( WLAN_HDD_FTM );
248 CASE_RETURN_STRING( WLAN_HDD_IBSS );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
250 default:
251 return "device_mode Unknown";
252 }
253}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530254
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530255static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700256 unsigned long state,
257 void *ndev)
258{
259 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700261 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262#ifdef WLAN_BTAMP_FEATURE
263 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700264#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530265 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700266
267 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700268 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700269 (strncmp(dev->name, "p2p", 3)))
270 return NOTIFY_DONE;
271
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700274
Jeff Johnson27cee452013-03-27 11:10:24 -0700275 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800277 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 VOS_ASSERT(0);
279 return NOTIFY_DONE;
280 }
281
Jeff Johnson27cee452013-03-27 11:10:24 -0700282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
283 if (NULL == pHddCtx)
284 {
285 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
286 VOS_ASSERT(0);
287 return NOTIFY_DONE;
288 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800289 if (pHddCtx->isLogpInProgress)
290 return NOTIFY_DONE;
291
Jeff Johnson27cee452013-03-27 11:10:24 -0700292
293 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
294 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700295
296 switch (state) {
297 case NETDEV_REGISTER:
298 break;
299
300 case NETDEV_UNREGISTER:
301 break;
302
303 case NETDEV_UP:
304 break;
305
306 case NETDEV_DOWN:
307 break;
308
309 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700310 if(TRUE == pAdapter->isLinkUpSvcNeeded)
311 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700312 break;
313
314 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530315 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530316 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530317 {
318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
319 "%s: Timeout occurred while waiting for abortscan %ld",
320 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 }
322 else
323 {
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530325 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 }
327#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700329 status = WLANBAP_StopAmp();
330 if(VOS_STATUS_SUCCESS != status )
331 {
332 pHddCtx->isAmpAllowed = VOS_TRUE;
333 hddLog(VOS_TRACE_LEVEL_FATAL,
334 "%s: Failed to stop AMP", __func__);
335 }
336 else
337 {
338 //a state m/c implementation in PAL is TBD to avoid this delay
339 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700340 if ( pHddCtx->isAmpAllowed )
341 {
342 WLANBAP_DeregisterFromHCI();
343 pHddCtx->isAmpAllowed = VOS_FALSE;
344 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700345 }
346#endif //WLAN_BTAMP_FEATURE
347 break;
348
349 default:
350 break;
351 }
352
353 return NOTIFY_DONE;
354}
355
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530356static int hdd_netdev_notifier_call(struct notifier_block * nb,
357 unsigned long state,
358 void *ndev)
359{
360 int ret;
361 vos_ssr_protect(__func__);
362 ret = __hdd_netdev_notifier_call( nb, state, ndev);
363 vos_ssr_unprotect(__func__);
364 return ret;
365}
366
Jeff Johnson295189b2012-06-20 16:38:30 -0700367struct notifier_block hdd_netdev_notifier = {
368 .notifier_call = hdd_netdev_notifier_call,
369};
370
371/*---------------------------------------------------------------------------
372 * Function definitions
373 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700374void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
375void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700376//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700377static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700378#ifndef MODULE
379/* current con_mode - used only for statically linked driver
380 * con_mode is changed by userspace to indicate a mode change which will
381 * result in calling the module exit and init functions. The module
382 * exit function will clean up based on the value of con_mode prior to it
383 * being changed by userspace. So curr_con_mode records the current con_mode
384 * for exit when con_mode becomes the next mode for init
385 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700386static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700387#endif
388
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800389/**---------------------------------------------------------------------------
390
391 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
392
393 Called immediately after the cfg.ini is read in order to configure
394 the desired trace levels.
395
396 \param - moduleId - module whose trace level is being configured
397 \param - bitmask - bitmask of log levels to be enabled
398
399 \return - void
400
401 --------------------------------------------------------------------------*/
402static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
403{
404 wpt_tracelevel level;
405
406 /* if the bitmask is the default value, then a bitmask was not
407 specified in cfg.ini, so leave the logging level alone (it
408 will remain at the "compiled in" default value) */
409 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
410 {
411 return;
412 }
413
414 /* a mask was specified. start by disabling all logging */
415 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
416
417 /* now cycle through the bitmask until all "set" bits are serviced */
418 level = VOS_TRACE_LEVEL_FATAL;
419 while (0 != bitmask)
420 {
421 if (bitmask & 1)
422 {
423 vos_trace_setValue(moduleId, level, 1);
424 }
425 level++;
426 bitmask >>= 1;
427 }
428}
429
430
Jeff Johnson295189b2012-06-20 16:38:30 -0700431/**---------------------------------------------------------------------------
432
433 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
434
435 Called immediately after the cfg.ini is read in order to configure
436 the desired trace levels in the WDI.
437
438 \param - moduleId - module whose trace level is being configured
439 \param - bitmask - bitmask of log levels to be enabled
440
441 \return - void
442
443 --------------------------------------------------------------------------*/
444static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
445{
446 wpt_tracelevel level;
447
448 /* if the bitmask is the default value, then a bitmask was not
449 specified in cfg.ini, so leave the logging level alone (it
450 will remain at the "compiled in" default value) */
451 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
452 {
453 return;
454 }
455
456 /* a mask was specified. start by disabling all logging */
457 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
458
459 /* now cycle through the bitmask until all "set" bits are serviced */
460 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
461 while (0 != bitmask)
462 {
463 if (bitmask & 1)
464 {
465 wpalTraceSetLevel(moduleId, level, 1);
466 }
467 level++;
468 bitmask >>= 1;
469 }
470}
Jeff Johnson295189b2012-06-20 16:38:30 -0700471
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530472/*
473 * FUNCTION: wlan_hdd_validate_context
474 * This function is used to check the HDD context
475 */
476int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
477{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530478
479 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
480 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530482 "%s: HDD context is Null", __func__);
483 return -ENODEV;
484 }
485
486 if (pHddCtx->isLogpInProgress)
487 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530489 "%s: LOGP %s. Ignore!!", __func__,
490 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
491 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530492 return -EAGAIN;
493 }
494
Mihir Shete18156292014-03-11 15:38:30 +0530495 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530496 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530498 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
499 return -EAGAIN;
500 }
501 return 0;
502}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700503#ifdef CONFIG_ENABLE_LINUX_REG
504void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
505{
506 hdd_adapter_t *pAdapter = NULL;
507 hdd_station_ctx_t *pHddStaCtx = NULL;
508 eCsrPhyMode phyMode;
509 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530510
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700511 if (NULL == pHddCtx)
512 {
513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
514 "HDD Context is null !!");
515 return ;
516 }
517
518 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
519 if (NULL == pAdapter)
520 {
521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
522 "pAdapter is null !!");
523 return ;
524 }
525
526 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
527 if (NULL == pHddStaCtx)
528 {
529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
530 "pHddStaCtx is null !!");
531 return ;
532 }
533
534 cfg_param = pHddCtx->cfg_ini;
535 if (NULL == cfg_param)
536 {
537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
538 "cfg_params not available !!");
539 return ;
540 }
541
542 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
543
544 if (!pHddCtx->isVHT80Allowed)
545 {
546 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
547 (eCSR_DOT11_MODE_11ac == phyMode) ||
548 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
549 {
550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
551 "Setting phymode to 11n!!");
552 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
553 }
554 }
555 else
556 {
557 /*New country Supports 11ac as well resetting value back from .ini*/
558 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
559 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
560 return ;
561 }
562
563 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
564 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
565 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
566 {
567 VOS_STATUS vosStatus;
568
569 // need to issue a disconnect to CSR.
570 INIT_COMPLETION(pAdapter->disconnect_comp_var);
571 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
572 pAdapter->sessionId,
573 eCSR_DISCONNECT_REASON_UNSPECIFIED );
574
575 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530576 {
577 long ret;
578
579 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700580 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530581 if (0 >= ret)
582 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
583 ret);
584 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700585
586 }
587}
588#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530589void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
590{
591 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
592 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
593 hdd_config_t *cfg_param;
594 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530595 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530596
597 if (NULL == pHddCtx)
598 {
599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
600 "HDD Context is null !!");
601 return ;
602 }
603
604 cfg_param = pHddCtx->cfg_ini;
605
606 if (NULL == cfg_param)
607 {
608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
609 "cfg_params not available !!");
610 return ;
611 }
612
613 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
614
615 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
616 {
617 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
618 (eCSR_DOT11_MODE_11ac == phyMode) ||
619 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
620 {
621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
622 "Setting phymode to 11n!!");
623 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
624 }
625 }
626 else
627 {
628 /*New country Supports 11ac as well resetting value back from .ini*/
629 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
630 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
631 return ;
632 }
633
634 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
635 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
636 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
637 {
638 VOS_STATUS vosStatus;
639
640 // need to issue a disconnect to CSR.
641 INIT_COMPLETION(pAdapter->disconnect_comp_var);
642 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
643 pAdapter->sessionId,
644 eCSR_DISCONNECT_REASON_UNSPECIFIED );
645
646 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530647 {
648 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530649 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530650 if (ret <= 0)
651 {
652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
653 "wait on disconnect_comp_var is failed %ld", ret);
654 }
655 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530656
657 }
658}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700659#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530660
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700661void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
662{
663 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
664 hdd_config_t *cfg_param;
665
666 if (NULL == pHddCtx)
667 {
668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
669 "HDD Context is null !!");
670 return ;
671 }
672
673 cfg_param = pHddCtx->cfg_ini;
674
675 if (NULL == cfg_param)
676 {
677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
678 "cfg_params not available !!");
679 return ;
680 }
681
Agarwal Ashish738843c2014-09-25 12:27:56 +0530682 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
683 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700684 {
685 /*New country doesn't support DFS */
686 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
687 }
688 else
689 {
690 /*New country Supports DFS as well resetting value back from .ini*/
691 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
692 }
693
694}
695
Rajeev79dbe4c2013-10-05 11:03:42 +0530696#ifdef FEATURE_WLAN_BATCH_SCAN
697
698/**---------------------------------------------------------------------------
699
700 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
701 input string
702
703 This function extracts assigned integer from string in below format:
704 "STRING=10" : extracts integer 10 from this string
705
706 \param - pInPtr Pointer to input string
707 \param - base Base for string to int conversion(10 for decimal 16 for hex)
708 \param - pOutPtr Pointer to variable in which extracted integer needs to be
709 assigned
710 \param - pLastArg to tell whether it is last arguement in input string or
711 not
712
713 \return - NULL for failure cases
714 pointer to next arguement in input string for success cases
715 --------------------------------------------------------------------------*/
716static tANI_U8 *
717hdd_extract_assigned_int_from_str
718(
719 tANI_U8 *pInPtr,
720 tANI_U8 base,
721 tANI_U32 *pOutPtr,
722 tANI_U8 *pLastArg
723)
724{
725 int tempInt;
726 int v = 0;
727 char buf[32];
728 int val = 0;
729 *pLastArg = FALSE;
730
731 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
732 if (NULL == pInPtr)
733 {
734 return NULL;
735 }
736
737 pInPtr++;
738
739 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
740
741 val = sscanf(pInPtr, "%32s ", buf);
742 if (val < 0 && val > strlen(pInPtr))
743 {
744 return NULL;
745 }
746 pInPtr += val;
747 v = kstrtos32(buf, base, &tempInt);
748 if (v < 0)
749 {
750 return NULL;
751 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800752 if (tempInt < 0)
753 {
754 tempInt = 0;
755 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530756 *pOutPtr = tempInt;
757
758 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
759 if (NULL == pInPtr)
760 {
761 *pLastArg = TRUE;
762 return NULL;
763 }
764 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
765
766 return pInPtr;
767}
768
769/**---------------------------------------------------------------------------
770
771 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
772 input string
773
774 This function extracts assigned character from string in below format:
775 "STRING=A" : extracts char 'A' from this string
776
777 \param - pInPtr Pointer to input string
778 \param - pOutPtr Pointer to variable in which extracted char needs to be
779 assigned
780 \param - pLastArg to tell whether it is last arguement in input string or
781 not
782
783 \return - NULL for failure cases
784 pointer to next arguement in input string for success cases
785 --------------------------------------------------------------------------*/
786static tANI_U8 *
787hdd_extract_assigned_char_from_str
788(
789 tANI_U8 *pInPtr,
790 tANI_U8 *pOutPtr,
791 tANI_U8 *pLastArg
792)
793{
794 *pLastArg = FALSE;
795
796 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
797 if (NULL == pInPtr)
798 {
799 return NULL;
800 }
801
802 pInPtr++;
803
804 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
805
806 *pOutPtr = *pInPtr;
807
808 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
809 if (NULL == pInPtr)
810 {
811 *pLastArg = TRUE;
812 return NULL;
813 }
814 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
815
816 return pInPtr;
817}
818
819
820/**---------------------------------------------------------------------------
821
822 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
823
824 This function parses set batch scan command in below format:
825 WLS_BATCHING_SET <space> followed by below arguements
826 "SCANFREQ=XX" : Optional defaults to 30 sec
827 "MSCAN=XX" : Required number of scans to attempt to batch
828 "BESTN=XX" : Best Network (RSSI) defaults to 16
829 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
830 A. implies only 5 GHz , B. implies only 2.4GHz
831 "RTT=X" : optional defaults to 0
832 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
833 error
834
835 For example input commands:
836 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
837 translated into set batch scan with following parameters:
838 a) Frequence 60 seconds
839 b) Batch 10 scans together
840 c) Best RSSI to be 20
841 d) 5GHz band only
842 e) RTT is equal to 0
843
844 \param - pValue Pointer to input channel list
845 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
846
847 \return - 0 for success non-zero for failure
848
849 --------------------------------------------------------------------------*/
850static int
851hdd_parse_set_batchscan_command
852(
853 tANI_U8 *pValue,
854 tSirSetBatchScanReq *pHddSetBatchScanReq
855)
856{
857 tANI_U8 *inPtr = pValue;
858 tANI_U8 val = 0;
859 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800860 tANI_U32 nScanFreq;
861 tANI_U32 nMscan;
862 tANI_U32 nBestN;
863 tANI_U8 ucRfBand;
864 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800865 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530866
867 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800868 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
869 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
870 nRtt = 0;
871 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530872
873 /*go to space after WLS_BATCHING_SET command*/
874 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
875 /*no argument after the command*/
876 if (NULL == inPtr)
877 {
878 return -EINVAL;
879 }
880
881 /*no space after the command*/
882 else if (SPACE_ASCII_VALUE != *inPtr)
883 {
884 return -EINVAL;
885 }
886
887 /*removing empty spaces*/
888 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
889
890 /*no argument followed by spaces*/
891 if ('\0' == *inPtr)
892 {
893 return -EINVAL;
894 }
895
896 /*check and parse SCANFREQ*/
897 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
898 {
899 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800900 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800901
Rajeev Kumarc933d982013-11-18 20:04:20 -0800902 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800903 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800904 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800905 }
906
Rajeev79dbe4c2013-10-05 11:03:42 +0530907 if ( (NULL == inPtr) || (TRUE == lastArg))
908 {
909 return -EINVAL;
910 }
911 }
912
913 /*check and parse MSCAN*/
914 if ((strncmp(inPtr, "MSCAN", 5) == 0))
915 {
916 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800917 &nMscan, &lastArg);
918
919 if (0 == nMscan)
920 {
921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
922 "invalid MSCAN=%d", nMscan);
923 return -EINVAL;
924 }
925
Rajeev79dbe4c2013-10-05 11:03:42 +0530926 if (TRUE == lastArg)
927 {
928 goto done;
929 }
930 else if (NULL == inPtr)
931 {
932 return -EINVAL;
933 }
934 }
935 else
936 {
937 return -EINVAL;
938 }
939
940 /*check and parse BESTN*/
941 if ((strncmp(inPtr, "BESTN", 5) == 0))
942 {
943 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800944 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800945
Rajeev Kumarc933d982013-11-18 20:04:20 -0800946 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800947 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800948 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800949 }
950
Rajeev79dbe4c2013-10-05 11:03:42 +0530951 if (TRUE == lastArg)
952 {
953 goto done;
954 }
955 else if (NULL == inPtr)
956 {
957 return -EINVAL;
958 }
959 }
960
961 /*check and parse CHANNEL*/
962 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
963 {
964 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800965
Rajeev79dbe4c2013-10-05 11:03:42 +0530966 if (('A' == val) || ('a' == val))
967 {
c_hpothuebf89732014-02-25 13:00:24 +0530968 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530969 }
970 else if (('B' == val) || ('b' == val))
971 {
c_hpothuebf89732014-02-25 13:00:24 +0530972 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530973 }
974 else
975 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800976 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
977 }
978
979 if (TRUE == lastArg)
980 {
981 goto done;
982 }
983 else if (NULL == inPtr)
984 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530985 return -EINVAL;
986 }
987 }
988
989 /*check and parse RTT*/
990 if ((strncmp(inPtr, "RTT", 3) == 0))
991 {
992 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800993 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530994 if (TRUE == lastArg)
995 {
996 goto done;
997 }
998 if (NULL == inPtr)
999 {
1000 return -EINVAL;
1001 }
1002 }
1003
1004
1005done:
1006
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001007 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1008 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1009 pHddSetBatchScanReq->bestNetwork = nBestN;
1010 pHddSetBatchScanReq->rfBand = ucRfBand;
1011 pHddSetBatchScanReq->rtt = nRtt;
1012
Rajeev79dbe4c2013-10-05 11:03:42 +05301013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1014 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1015 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1016 pHddSetBatchScanReq->scanFrequency,
1017 pHddSetBatchScanReq->numberOfScansToBatch,
1018 pHddSetBatchScanReq->bestNetwork,
1019 pHddSetBatchScanReq->rfBand,
1020 pHddSetBatchScanReq->rtt);
1021
1022 return 0;
1023}/*End of hdd_parse_set_batchscan_command*/
1024
1025/**---------------------------------------------------------------------------
1026
1027 \brief hdd_set_batch_scan_req_callback () - This function is called after
1028 receiving set batch scan response from FW and it saves set batch scan
1029 response data FW to HDD context and sets the completion event on
1030 which hdd_ioctl is waiting
1031
1032 \param - callbackContext Pointer to HDD adapter
1033 \param - pRsp Pointer to set batch scan response data received from FW
1034
1035 \return - nothing
1036
1037 --------------------------------------------------------------------------*/
1038static void hdd_set_batch_scan_req_callback
1039(
1040 void *callbackContext,
1041 tSirSetBatchScanRsp *pRsp
1042)
1043{
1044 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1045 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1046
1047 /*sanity check*/
1048 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1049 {
1050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1051 "%s: Invalid pAdapter magic", __func__);
1052 VOS_ASSERT(0);
1053 return;
1054 }
1055 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1056
1057 /*save set batch scan response*/
1058 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1059
1060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1061 "Received set batch scan rsp from FW with nScansToBatch=%d",
1062 pHddSetBatchScanRsp->nScansToBatch);
1063
1064 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1065 complete(&pAdapter->hdd_set_batch_scan_req_var);
1066
1067 return;
1068}/*End of hdd_set_batch_scan_req_callback*/
1069
1070
1071/**---------------------------------------------------------------------------
1072
1073 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1074 info in hdd batch scan response queue
1075
1076 \param - pAdapter Pointer to hdd adapter
1077 \param - pAPMetaInfo Pointer to access point meta info
1078 \param - scanId scan ID of batch scan response
1079 \param - isLastAp tells whether AP is last AP in batch scan response or not
1080
1081 \return - nothing
1082
1083 --------------------------------------------------------------------------*/
1084static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1085 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1086{
1087 tHddBatchScanRsp *pHead;
1088 tHddBatchScanRsp *pNode;
1089 tHddBatchScanRsp *pPrev;
1090 tHddBatchScanRsp *pTemp;
1091 tANI_U8 ssidLen;
1092
1093 /*head of hdd batch scan response queue*/
1094 pHead = pAdapter->pBatchScanRsp;
1095
1096 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1097 if (NULL == pNode)
1098 {
1099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1100 "%s: Could not allocate memory", __func__);
1101 VOS_ASSERT(0);
1102 return;
1103 }
1104
1105 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1106 sizeof(pNode->ApInfo.bssid));
1107 ssidLen = strlen(pApMetaInfo->ssid);
1108 if (SIR_MAX_SSID_SIZE < ssidLen)
1109 {
1110 /*invalid scan result*/
1111 vos_mem_free(pNode);
1112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1113 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1114 return;
1115 }
1116 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1117 /*null terminate ssid*/
1118 pNode->ApInfo.ssid[ssidLen] = '\0';
1119 pNode->ApInfo.ch = pApMetaInfo->ch;
1120 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1121 pNode->ApInfo.age = pApMetaInfo->timestamp;
1122 pNode->ApInfo.batchId = scanId;
1123 pNode->ApInfo.isLastAp = isLastAp;
1124
1125 pNode->pNext = NULL;
1126 if (NULL == pHead)
1127 {
1128 pAdapter->pBatchScanRsp = pNode;
1129 }
1130 else
1131 {
1132 pTemp = pHead;
1133 while (NULL != pTemp)
1134 {
1135 pPrev = pTemp;
1136 pTemp = pTemp->pNext;
1137 }
1138 pPrev->pNext = pNode;
1139 }
1140
1141 return;
1142}/*End of hdd_populate_batch_scan_rsp_queue*/
1143
1144/**---------------------------------------------------------------------------
1145
1146 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1147 receiving batch scan response indication from FW. It saves get batch scan
1148 response data in HDD batch scan response queue. This callback sets the
1149 completion event on which hdd_ioctl is waiting only after getting complete
1150 batch scan response data from FW
1151
1152 \param - callbackContext Pointer to HDD adapter
1153 \param - pRsp Pointer to get batch scan response data received from FW
1154
1155 \return - nothing
1156
1157 --------------------------------------------------------------------------*/
1158static void hdd_batch_scan_result_ind_callback
1159(
1160 void *callbackContext,
1161 void *pRsp
1162)
1163{
1164 v_BOOL_t isLastAp;
1165 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001166 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301167 tANI_U32 numberScanList;
1168 tANI_U32 nextScanListOffset;
1169 tANI_U32 nextApMetaInfoOffset;
1170 hdd_adapter_t* pAdapter;
1171 tpSirBatchScanList pScanList;
1172 tpSirBatchScanNetworkInfo pApMetaInfo;
1173 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1174 tSirSetBatchScanReq *pReq;
1175
1176 pAdapter = (hdd_adapter_t *)callbackContext;
1177 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001178 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301179 {
1180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1181 "%s: Invalid pAdapter magic", __func__);
1182 VOS_ASSERT(0);
1183 return;
1184 }
1185
1186 /*initialize locals*/
1187 pReq = &pAdapter->hddSetBatchScanReq;
1188 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1189 isLastAp = FALSE;
1190 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001191 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301192 numberScanList = 0;
1193 nextScanListOffset = 0;
1194 nextApMetaInfoOffset = 0;
1195 pScanList = NULL;
1196 pApMetaInfo = NULL;
1197
1198 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1199 {
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1202 isLastAp = TRUE;
1203 goto done;
1204 }
1205
1206 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1208 "Batch scan rsp: numberScalList %d", numberScanList);
1209
1210 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1211 {
1212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1213 "%s: numberScanList %d", __func__, numberScanList);
1214 isLastAp = TRUE;
1215 goto done;
1216 }
1217
1218 while (numberScanList)
1219 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001220 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301221 nextScanListOffset);
1222 if (NULL == pScanList)
1223 {
1224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1225 "%s: pScanList is %p", __func__, pScanList);
1226 isLastAp = TRUE;
1227 goto done;
1228 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001229 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001231 "Batch scan rsp: numApMetaInfo %d scanId %d",
1232 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301233
1234 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1235 {
1236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1237 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1238 isLastAp = TRUE;
1239 goto done;
1240 }
1241
Rajeev Kumarce651e42013-10-21 18:57:15 -07001242 /*Initialize next AP meta info offset for next scan list*/
1243 nextApMetaInfoOffset = 0;
1244
Rajeev79dbe4c2013-10-05 11:03:42 +05301245 while (numApMetaInfo)
1246 {
1247 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1248 nextApMetaInfoOffset);
1249 if (NULL == pApMetaInfo)
1250 {
1251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1252 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1253 isLastAp = TRUE;
1254 goto done;
1255 }
1256 /*calculate AP age*/
1257 pApMetaInfo->timestamp =
1258 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1259
1260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001261 "%s: bssId "MAC_ADDRESS_STR
1262 " ch %d rssi %d timestamp %d", __func__,
1263 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1264 pApMetaInfo->ch, pApMetaInfo->rssi,
1265 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301266
1267 /*mark last AP in batch scan response*/
1268 if ((TRUE == pBatchScanRsp->isLastResult) &&
1269 (1 == numberScanList) && (1 == numApMetaInfo))
1270 {
1271 isLastAp = TRUE;
1272 }
1273
1274 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1275 /*store batch scan repsonse in hdd queue*/
1276 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1277 pScanList->scanId, isLastAp);
1278 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1279
1280 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1281 numApMetaInfo--;
1282 }
1283
Rajeev Kumarce651e42013-10-21 18:57:15 -07001284 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1285 + (sizeof(tSirBatchScanNetworkInfo)
1286 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301287 numberScanList--;
1288 }
1289
1290done:
1291
1292 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1293 requested from hdd_ioctl*/
1294 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1295 (TRUE == isLastAp))
1296 {
1297 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1298 complete(&pAdapter->hdd_get_batch_scan_req_var);
1299 }
1300
1301 return;
1302}/*End of hdd_batch_scan_result_ind_callback*/
1303
1304/**---------------------------------------------------------------------------
1305
1306 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1307 response as per batch scan FR request format by putting proper markers
1308
1309 \param - pDest pointer to destination buffer
1310 \param - cur_len current length
1311 \param - tot_len total remaining size which can be written to user space
1312 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1313 \param - pAdapter Pointer to HDD adapter
1314
1315 \return - ret no of characters written
1316
1317 --------------------------------------------------------------------------*/
1318static tANI_U32
1319hdd_format_batch_scan_rsp
1320(
1321 tANI_U8 *pDest,
1322 tANI_U32 cur_len,
1323 tANI_U32 tot_len,
1324 tHddBatchScanRsp *pApMetaInfo,
1325 hdd_adapter_t* pAdapter
1326)
1327{
1328 tANI_U32 ret = 0;
1329 tANI_U32 rem_len = 0;
1330 tANI_U8 temp_len = 0;
1331 tANI_U8 temp_total_len = 0;
1332 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1333 tANI_U8 *pTemp = temp;
1334
1335 /*Batch scan reponse needs to be returned to user space in
1336 following format:
1337 "scancount=X\n" where X is the number of scans in current batch
1338 batch
1339 "trunc\n" optional present if current scan truncated
1340 "bssid=XX:XX:XX:XX:XX:XX\n"
1341 "ssid=XXXX\n"
1342 "freq=X\n" frequency in Mhz
1343 "level=XX\n"
1344 "age=X\n" ms
1345 "dist=X\n" cm (-1 if not available)
1346 "errror=X\n" (-1if not available)
1347 "====\n" (end of ap marker)
1348 "####\n" (end of scan marker)
1349 "----\n" (end of results)*/
1350 /*send scan result in above format to user space based on
1351 available length*/
1352 /*The GET response may have more data than the driver can return in its
1353 buffer. In that case the buffer should be filled to the nearest complete
1354 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1355 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1356 The final buffer should end with "----\n"*/
1357
1358 /*sanity*/
1359 if (cur_len > tot_len)
1360 {
1361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1362 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1363 return 0;
1364 }
1365 else
1366 {
1367 rem_len = (tot_len - cur_len);
1368 }
1369
1370 /*end scan marker*/
1371 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1372 {
1373 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1374 pTemp += temp_len;
1375 temp_total_len += temp_len;
1376 }
1377
1378 /*bssid*/
1379 temp_len = snprintf(pTemp, sizeof(temp),
1380 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1381 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1382 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1383 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1384 pTemp += temp_len;
1385 temp_total_len += temp_len;
1386
1387 /*ssid*/
1388 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1389 pApMetaInfo->ApInfo.ssid);
1390 pTemp += temp_len;
1391 temp_total_len += temp_len;
1392
1393 /*freq*/
1394 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001395 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301396 pTemp += temp_len;
1397 temp_total_len += temp_len;
1398
1399 /*level*/
1400 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1401 pApMetaInfo->ApInfo.rssi);
1402 pTemp += temp_len;
1403 temp_total_len += temp_len;
1404
1405 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001406 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301407 pApMetaInfo->ApInfo.age);
1408 pTemp += temp_len;
1409 temp_total_len += temp_len;
1410
1411 /*dist*/
1412 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1413 pTemp += temp_len;
1414 temp_total_len += temp_len;
1415
1416 /*error*/
1417 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1418 pTemp += temp_len;
1419 temp_total_len += temp_len;
1420
1421 /*end AP marker*/
1422 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1423 pTemp += temp_len;
1424 temp_total_len += temp_len;
1425
1426 /*last AP in batch scan response*/
1427 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1428 {
1429 /*end scan marker*/
1430 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1431 pTemp += temp_len;
1432 temp_total_len += temp_len;
1433
1434 /*end batch scan result marker*/
1435 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1436 pTemp += temp_len;
1437 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001438
Rajeev79dbe4c2013-10-05 11:03:42 +05301439 }
1440
1441 if (temp_total_len < rem_len)
1442 {
1443 ret = temp_total_len + 1;
1444 strlcpy(pDest, temp, ret);
1445 pAdapter->isTruncated = FALSE;
1446 }
1447 else
1448 {
1449 pAdapter->isTruncated = TRUE;
1450 if (rem_len >= strlen("%%%%"))
1451 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001452 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301453 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001454 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301455 {
1456 ret = 0;
1457 }
1458 }
1459
1460 return ret;
1461
1462}/*End of hdd_format_batch_scan_rsp*/
1463
1464/**---------------------------------------------------------------------------
1465
1466 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1467 buffer starting with head of hdd batch scan response queue
1468
1469 \param - pAdapter Pointer to HDD adapter
1470 \param - pDest Pointer to user data buffer
1471 \param - cur_len current offset in user buffer
1472 \param - rem_len remaining no of bytes in user buffer
1473
1474 \return - number of bytes written in user buffer
1475
1476 --------------------------------------------------------------------------*/
1477
1478tANI_U32 hdd_populate_user_batch_scan_rsp
1479(
1480 hdd_adapter_t* pAdapter,
1481 tANI_U8 *pDest,
1482 tANI_U32 cur_len,
1483 tANI_U32 rem_len
1484)
1485{
1486 tHddBatchScanRsp *pHead;
1487 tHddBatchScanRsp *pPrev;
1488 tANI_U32 len;
1489
Rajeev79dbe4c2013-10-05 11:03:42 +05301490 pAdapter->isTruncated = FALSE;
1491
1492 /*head of hdd batch scan response queue*/
1493 pHead = pAdapter->pBatchScanRsp;
1494 while (pHead)
1495 {
1496 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1497 pAdapter);
1498 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001499 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301500 cur_len += len;
1501 if(TRUE == pAdapter->isTruncated)
1502 {
1503 /*result is truncated return rest of scan rsp in next req*/
1504 cur_len = rem_len;
1505 break;
1506 }
1507 pPrev = pHead;
1508 pHead = pHead->pNext;
1509 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001510 if (TRUE == pPrev->ApInfo.isLastAp)
1511 {
1512 pAdapter->prev_batch_id = 0;
1513 }
1514 else
1515 {
1516 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1517 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301518 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001519 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301520 }
1521
1522 return cur_len;
1523}/*End of hdd_populate_user_batch_scan_rsp*/
1524
1525/**---------------------------------------------------------------------------
1526
1527 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1528 scan response data from HDD queue to user space
1529 It does following in detail:
1530 a) if HDD has enough data in its queue then it 1st copies data to user
1531 space and then send get batch scan indication message to FW. In this
1532 case it does not wait on any event and batch scan response data will
1533 be populated in HDD response queue in MC thread context after receiving
1534 indication from FW
1535 b) else send get batch scan indication message to FW and wait on an event
1536 which will be set once HDD receives complete batch scan response from
1537 FW and then this function returns batch scan response to user space
1538
1539 \param - pAdapter Pointer to HDD adapter
1540 \param - pPrivData Pointer to priv_data
1541
1542 \return - 0 for success -EFAULT for failure
1543
1544 --------------------------------------------------------------------------*/
1545
1546int hdd_return_batch_scan_rsp_to_user
1547(
1548 hdd_adapter_t* pAdapter,
1549 hdd_priv_data_t *pPrivData,
1550 tANI_U8 *command
1551)
1552{
1553 tANI_U8 *pDest;
1554 tANI_U32 count = 0;
1555 tANI_U32 len = 0;
1556 tANI_U32 cur_len = 0;
1557 tANI_U32 rem_len = 0;
1558 eHalStatus halStatus;
1559 unsigned long rc;
1560 tSirTriggerBatchScanResultInd *pReq;
1561
1562 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1563 pReq->param = 0;/*batch scan client*/
1564 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1565 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1566
1567 cur_len = pPrivData->used_len;
1568 if (pPrivData->total_len > pPrivData->used_len)
1569 {
1570 rem_len = pPrivData->total_len - pPrivData->used_len;
1571 }
1572 else
1573 {
1574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1575 "%s: Invalid user data buffer total_len %d used_len %d",
1576 __func__, pPrivData->total_len, pPrivData->used_len);
1577 return -EFAULT;
1578 }
1579
1580 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1581 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1582 cur_len, rem_len);
1583 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1584
1585 /*enough scan result available in cache to return to user space or
1586 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001587 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301588 {
1589 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1590 halStatus = sme_TriggerBatchScanResultInd(
1591 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1592 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1593 pAdapter);
1594 if ( eHAL_STATUS_SUCCESS == halStatus )
1595 {
1596 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1597 {
1598 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1599 rc = wait_for_completion_timeout(
1600 &pAdapter->hdd_get_batch_scan_req_var,
1601 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1602 if (0 == rc)
1603 {
1604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1605 "%s: Timeout waiting to fetch batch scan rsp from fw",
1606 __func__);
1607 return -EFAULT;
1608 }
1609 }
1610
1611 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001612 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301613 pDest += len;
1614 cur_len += len;
1615
1616 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1617 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1618 cur_len, rem_len);
1619 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1620
1621 count = 0;
1622 len = (len - pPrivData->used_len);
1623 pDest = (command + pPrivData->used_len);
1624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001625 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301626 while(count < len)
1627 {
1628 printk("%c", *(pDest + count));
1629 count++;
1630 }
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1632 "%s: copy %d data to user buffer", __func__, len);
1633 if (copy_to_user(pPrivData->buf, pDest, len))
1634 {
1635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "%s: failed to copy data to user buffer", __func__);
1637 return -EFAULT;
1638 }
1639 }
1640 else
1641 {
1642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1643 "sme_GetBatchScanScan returned failure halStatus %d",
1644 halStatus);
1645 return -EINVAL;
1646 }
1647 }
1648 else
1649 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301650 count = 0;
1651 len = (len - pPrivData->used_len);
1652 pDest = (command + pPrivData->used_len);
1653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001654 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301655 while(count < len)
1656 {
1657 printk("%c", *(pDest + count));
1658 count++;
1659 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1661 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301662 if (copy_to_user(pPrivData->buf, pDest, len))
1663 {
1664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1665 "%s: failed to copy data to user buffer", __func__);
1666 return -EFAULT;
1667 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301668 }
1669
1670 return 0;
1671} /*End of hdd_return_batch_scan_rsp_to_user*/
1672
Rajeev Kumar8b373292014-01-08 20:36:55 -08001673
1674/**---------------------------------------------------------------------------
1675
1676 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1677 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1678 WLS_BATCHING VERSION
1679 WLS_BATCHING SET
1680 WLS_BATCHING GET
1681 WLS_BATCHING STOP
1682
1683 \param - pAdapter Pointer to HDD adapter
1684 \param - pPrivdata Pointer to priv_data
1685 \param - command Pointer to command
1686
1687 \return - 0 for success -EFAULT for failure
1688
1689 --------------------------------------------------------------------------*/
1690
1691int hdd_handle_batch_scan_ioctl
1692(
1693 hdd_adapter_t *pAdapter,
1694 hdd_priv_data_t *pPrivdata,
1695 tANI_U8 *command
1696)
1697{
1698 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001699 hdd_context_t *pHddCtx;
1700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301701 ENTER();
1702
Yue Mae36e3552014-03-05 17:06:20 -08001703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1704 ret = wlan_hdd_validate_context(pHddCtx);
1705 if (ret)
1706 {
Yue Mae36e3552014-03-05 17:06:20 -08001707 goto exit;
1708 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001709
1710 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1711 {
1712 char extra[32];
1713 tANI_U8 len = 0;
1714 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1715
1716 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1717 {
1718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1719 "%s: Batch scan feature is not supported by FW", __func__);
1720 ret = -EINVAL;
1721 goto exit;
1722 }
1723
1724 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1725 version);
1726 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1727 {
1728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1729 "%s: failed to copy data to user buffer", __func__);
1730 ret = -EFAULT;
1731 goto exit;
1732 }
1733 ret = HDD_BATCH_SCAN_VERSION;
1734 }
1735 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1736 {
1737 int status;
1738 tANI_U8 *value = (command + 16);
1739 eHalStatus halStatus;
1740 unsigned long rc;
1741 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1742 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1743
1744 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1745 {
1746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1747 "%s: Batch scan feature is not supported by FW", __func__);
1748 ret = -EINVAL;
1749 goto exit;
1750 }
1751
1752 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1753 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1754 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1755 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1756 {
1757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301758 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001759 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301760 hdd_device_modetoString(pAdapter->device_mode),
1761 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001762 ret = -EINVAL;
1763 goto exit;
1764 }
1765
1766 status = hdd_parse_set_batchscan_command(value, pReq);
1767 if (status)
1768 {
1769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1770 "Invalid WLS_BATCHING SET command");
1771 ret = -EINVAL;
1772 goto exit;
1773 }
1774
1775
1776 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1777 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1778 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1779 pAdapter);
1780
1781 if ( eHAL_STATUS_SUCCESS == halStatus )
1782 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301783 char extra[32];
1784 tANI_U8 len = 0;
1785 tANI_U8 mScan = 0;
1786
Rajeev Kumar8b373292014-01-08 20:36:55 -08001787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1788 "sme_SetBatchScanReq returned success halStatus %d",
1789 halStatus);
1790 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1791 {
1792 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1793 rc = wait_for_completion_timeout(
1794 &pAdapter->hdd_set_batch_scan_req_var,
1795 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1796 if (0 == rc)
1797 {
1798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1799 "%s: Timeout waiting for set batch scan to complete",
1800 __func__);
1801 ret = -EINVAL;
1802 goto exit;
1803 }
1804 }
1805 if ( !pRsp->nScansToBatch )
1806 {
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1808 "%s: Received set batch scan failure response from FW",
1809 __func__);
1810 ret = -EINVAL;
1811 goto exit;
1812 }
1813 /*As per the Batch Scan Framework API we should return the MIN of
1814 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301815 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001816
1817 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1818
1819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301821 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1822 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1823 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1824 {
1825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "%s: failed to copy MSCAN value to user buffer", __func__);
1827 ret = -EFAULT;
1828 goto exit;
1829 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001830 }
1831 else
1832 {
1833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1834 "sme_SetBatchScanReq returned failure halStatus %d",
1835 halStatus);
1836 ret = -EINVAL;
1837 goto exit;
1838 }
1839 }
1840 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1841 {
1842 eHalStatus halStatus;
1843 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1844 pInd->param = 0;
1845
1846 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1847 {
1848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 "%s: Batch scan feature is not supported by FW", __func__);
1850 ret = -EINVAL;
1851 goto exit;
1852 }
1853
1854 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1855 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001857 "Batch scan is not yet enabled batch scan state %d",
1858 pAdapter->batchScanState);
1859 ret = -EINVAL;
1860 goto exit;
1861 }
1862
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001863 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1864 hdd_deinit_batch_scan(pAdapter);
1865 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1866
Rajeev Kumar8b373292014-01-08 20:36:55 -08001867 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1868
1869 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1870 pAdapter->sessionId);
1871 if ( eHAL_STATUS_SUCCESS == halStatus )
1872 {
1873 ret = 0;
1874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1875 "sme_StopBatchScanInd returned success halStatus %d",
1876 halStatus);
1877 }
1878 else
1879 {
1880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1881 "sme_StopBatchScanInd returned failure halStatus %d",
1882 halStatus);
1883 ret = -EINVAL;
1884 goto exit;
1885 }
1886 }
1887 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1888 {
1889 tANI_U32 remain_len;
1890
1891 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1892 {
1893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1894 "%s: Batch scan feature is not supported by FW", __func__);
1895 ret = -EINVAL;
1896 goto exit;
1897 }
1898
1899 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1900 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001902 "Batch scan is not yet enabled could not return results"
1903 "Batch Scan state %d",
1904 pAdapter->batchScanState);
1905 ret = -EINVAL;
1906 goto exit;
1907 }
1908
1909 pPrivdata->used_len = 16;
1910 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1911 if (remain_len < pPrivdata->total_len)
1912 {
1913 /*Clear previous batch scan response data if any*/
1914 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1915 }
1916 else
1917 {
1918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1919 "Invalid total length from user space can't fetch batch"
1920 " scan response total_len %d used_len %d remain len %d",
1921 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1922 ret = -EINVAL;
1923 goto exit;
1924 }
1925 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1926 }
1927
1928exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301929 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001930 return ret;
1931}
1932
1933
Rajeev79dbe4c2013-10-05 11:03:42 +05301934#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1935
c_hpothu92367912014-05-01 15:18:17 +05301936static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1937{
c_hpothu39eb1e32014-06-26 16:31:50 +05301938 bcnMissRateContext_t *pCBCtx;
1939
1940 if (NULL == data)
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1943 return;
1944 }
c_hpothu92367912014-05-01 15:18:17 +05301945
1946 /* there is a race condition that exists between this callback
1947 function and the caller since the caller could time out either
1948 before or while this code is executing. we use a spinlock to
1949 serialize these actions */
1950 spin_lock(&hdd_context_lock);
1951
c_hpothu39eb1e32014-06-26 16:31:50 +05301952 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301953 gbcnMissRate = -1;
1954
c_hpothu39eb1e32014-06-26 16:31:50 +05301955 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301956 {
1957 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301958 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301959 spin_unlock(&hdd_context_lock);
1960 return ;
1961 }
1962
1963 if (VOS_STATUS_SUCCESS == status)
1964 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301965 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301966 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301967 else
1968 {
1969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1970 }
1971
c_hpothu92367912014-05-01 15:18:17 +05301972 complete(&(pCBCtx->completion));
1973 spin_unlock(&hdd_context_lock);
1974
1975 return;
1976}
1977
Abhishek Singh08aa7762014-12-16 13:59:03 +05301978void hdd_FWStatisCB( VOS_STATUS status,
1979 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301980{
1981 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301982 hdd_adapter_t *pAdapter;
1983
1984 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1985
Abhishek Singh08aa7762014-12-16 13:59:03 +05301986 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301987 {
1988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1989 return;
1990 }
1991 /* there is a race condition that exists between this callback
1992 function and the caller since the caller could time out either
1993 before or while this code is executing. we use a spinlock to
1994 serialize these actions */
1995 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301996 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301997 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1998 {
1999 hddLog(VOS_TRACE_LEVEL_ERROR,
2000 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2001 spin_unlock(&hdd_context_lock);
2002 return;
2003 }
2004 pAdapter = fwStatsCtx->pAdapter;
2005 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2006 {
2007 hddLog(VOS_TRACE_LEVEL_ERROR,
2008 FL("pAdapter returned is NULL or invalid"));
2009 spin_unlock(&hdd_context_lock);
2010 return;
2011 }
2012 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302013 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302014 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302015 switch( fwStatsResult->type )
2016 {
2017 case FW_UBSP_STATS:
2018 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302019 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302020 hddLog(VOS_TRACE_LEVEL_INFO,
2021 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302022 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2023 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302024 }
2025 break;
2026 default:
2027 {
2028 hddLog(VOS_TRACE_LEVEL_ERROR,
2029 FL(" No handling for stats type %d"),fwStatsResult->type);
2030 }
2031 }
2032 }
2033 complete(&(fwStatsCtx->completion));
2034 spin_unlock(&hdd_context_lock);
2035 return;
2036}
2037
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302038static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2039{
2040 int ret = 0;
2041
2042 if (!pCfg || !command || !extra || !len)
2043 {
2044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2045 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2046 ret = -EINVAL;
2047 return ret;
2048 }
2049
2050 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2051 {
2052 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2053 (int)pCfg->nActiveMaxChnTime);
2054 return ret;
2055 }
2056 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2057 {
2058 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2059 (int)pCfg->nActiveMinChnTime);
2060 return ret;
2061 }
2062 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2063 {
2064 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2065 (int)pCfg->nPassiveMaxChnTime);
2066 return ret;
2067 }
2068 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2069 {
2070 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2071 (int)pCfg->nPassiveMinChnTime);
2072 return ret;
2073 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302074 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2075 {
2076 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2077 (int)pCfg->nActiveMaxChnTime);
2078 return ret;
2079 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302080 else
2081 {
2082 ret = -EINVAL;
2083 }
2084
2085 return ret;
2086}
2087
2088static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2089{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302090 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302091 hdd_config_t *pCfg;
2092 tANI_U8 *value = command;
2093 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302094 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302095
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302096 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2097 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302098 {
2099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2100 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2101 ret = -EINVAL;
2102 return ret;
2103 }
2104
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302105 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2106 sme_GetConfigParam(hHal, &smeConfig);
2107
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302108 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2109 {
2110 value = value + 24;
2111 temp = kstrtou32(value, 10, &val);
2112 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2113 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2114 {
2115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2116 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2117 ret = -EFAULT;
2118 return ret;
2119 }
2120 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302121 smeConfig.csrConfig.nActiveMaxChnTime = val;
2122 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302123 }
2124 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2125 {
2126 value = value + 24;
2127 temp = kstrtou32(value, 10, &val);
2128 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2129 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2130 {
2131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2132 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2133 ret = -EFAULT;
2134 return ret;
2135 }
2136 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302137 smeConfig.csrConfig.nActiveMinChnTime = val;
2138 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302139 }
2140 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2141 {
2142 value = value + 25;
2143 temp = kstrtou32(value, 10, &val);
2144 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2145 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2146 {
2147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2148 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2149 ret = -EFAULT;
2150 return ret;
2151 }
2152 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302153 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2154 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302155 }
2156 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2157 {
2158 value = value + 25;
2159 temp = kstrtou32(value, 10, &val);
2160 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2161 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2162 {
2163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2164 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2165 ret = -EFAULT;
2166 return ret;
2167 }
2168 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302169 smeConfig.csrConfig.nPassiveMinChnTime = val;
2170 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302171 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302172 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2173 {
2174 value = value + 13;
2175 temp = kstrtou32(value, 10, &val);
2176 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2177 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2178 {
2179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2180 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2181 ret = -EFAULT;
2182 return ret;
2183 }
2184 pCfg->nActiveMaxChnTime = val;
2185 smeConfig.csrConfig.nActiveMaxChnTime = val;
2186 sme_UpdateConfig(hHal, &smeConfig);
2187 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302188 else
2189 {
2190 ret = -EINVAL;
2191 }
2192
2193 return ret;
2194}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302195static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2196 tANI_U8 cmd_len)
2197{
2198 tANI_U8 *value;
2199 tANI_U8 fcc_constraint;
2200
2201 eHalStatus status;
2202 int ret = 0;
2203 value = cmd + cmd_len + 1;
2204
2205 ret = kstrtou8(value, 10, &fcc_constraint);
2206 if ((ret < 0) || (fcc_constraint > 1)) {
2207 /*
2208 * If the input value is greater than max value of datatype,
2209 * then also it is a failure
2210 */
2211 hddLog(VOS_TRACE_LEVEL_ERROR,
2212 "%s: value out of range", __func__);
2213 return -EINVAL;
2214 }
2215
2216 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2217 if (status != eHAL_STATUS_SUCCESS)
2218 ret = -EPERM;
2219
2220 return ret;
2221}
2222
2223
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302224
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002225static int hdd_driver_command(hdd_adapter_t *pAdapter,
2226 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002227{
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 hdd_priv_data_t priv_data;
2229 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302230 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2231 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002232 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302233 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302234
2235 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002236 /*
2237 * Note that valid pointers are provided by caller
2238 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002239
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002240 /* copy to local struct to avoid numerous changes to legacy code */
2241 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002242
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002243 if (priv_data.total_len <= 0 ||
2244 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002245 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002246 hddLog(VOS_TRACE_LEVEL_WARN,
2247 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2248 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002249 ret = -EINVAL;
2250 goto exit;
2251 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302252 status = wlan_hdd_validate_context(pHddCtx);
2253 if (0 != status)
2254 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302255 ret = -EINVAL;
2256 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302257 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002258 /* Allocate +1 for '\0' */
2259 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 if (!command)
2261 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002262 hddLog(VOS_TRACE_LEVEL_ERROR,
2263 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002264 ret = -ENOMEM;
2265 goto exit;
2266 }
2267
2268 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2269 {
2270 ret = -EFAULT;
2271 goto exit;
2272 }
2273
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002274 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002275 command[priv_data.total_len] = '\0';
2276
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002277 /* at one time the following block of code was conditional. braces
2278 * have been retained to avoid re-indenting the legacy code
2279 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002280 {
2281 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2282
2283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002284 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002285
2286 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2287 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302288 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2289 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2290 pAdapter->sessionId, (unsigned)
2291 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2292 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2293 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2294 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002295 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2296 sizeof(tSirMacAddr)))
2297 {
2298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002299 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002300 ret = -EFAULT;
2301 }
2302 }
Amar Singhal0974e402013-02-12 14:27:46 -08002303 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002304 {
Amar Singhal0974e402013-02-12 14:27:46 -08002305 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002306
Jeff Johnson295189b2012-06-20 16:38:30 -07002307 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002308
2309 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002310 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002312 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Anand N Sunkad27354cf2015-07-13 14:39:11 +05302313 if(VOS_FTM_MODE != hdd_get_conparam())
2314 {
2315 /* Change band request received */
2316 ret = hdd_setBand_helper(pAdapter->dev, ptr);
2317 if(ret < 0)
2318 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2319 "%s: failed to set band ret=%d", __func__, ret);
2320 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002321 }
Kiet Lamf040f472013-11-20 21:15:23 +05302322 else if(strncmp(command, "SETWMMPS", 8) == 0)
2323 {
2324 tANI_U8 *ptr = command;
2325 ret = hdd_wmmps_helper(pAdapter, ptr);
2326 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302327
2328 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2329 {
2330 tANI_U8 *ptr = command;
2331 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2332 }
2333
Jeff Johnson32d95a32012-09-10 13:15:23 -07002334 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2335 {
2336 char *country_code;
2337
2338 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002339
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002340 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002341 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002342#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302343 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002344#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002345 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2346 (void *)(tSmeChangeCountryCallback)
2347 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302348 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002349 if (eHAL_STATUS_SUCCESS == ret)
2350 {
2351 ret = wait_for_completion_interruptible_timeout(
2352 &pAdapter->change_country_code,
2353 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2354 if (0 >= ret)
2355 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302357 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002358 }
2359 }
2360 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002361 {
2362 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002363 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002364 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002365 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002366
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002367 }
2368 /*
2369 command should be a string having format
2370 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2371 */
Amar Singhal0974e402013-02-12 14:27:46 -08002372 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002373 {
Amar Singhal0974e402013-02-12 14:27:46 -08002374 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002375
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002377 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002378
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002379 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002380 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002381 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2382 {
2383 int suspend = 0;
2384 tANI_U8 *ptr = (tANI_U8*)command + 15;
2385
2386 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302387 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2388 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2389 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002390 hdd_set_wlan_suspend_mode(suspend);
2391 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002392#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2393 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2394 {
2395 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002396 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002397 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2398 eHalStatus status = eHAL_STATUS_SUCCESS;
2399
2400 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2401 value = value + 15;
2402
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002403 /* Convert the value from ascii to integer */
2404 ret = kstrtos8(value, 10, &rssi);
2405 if (ret < 0)
2406 {
2407 /* If the input value is greater than max value of datatype, then also
2408 kstrtou8 fails */
2409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2410 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002411 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002412 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2413 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2414 ret = -EINVAL;
2415 goto exit;
2416 }
2417
Srinivas Girigowdade697412013-02-14 16:31:48 -08002418 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002419
Srinivas Girigowdade697412013-02-14 16:31:48 -08002420 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2421 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2422 {
2423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2424 "Neighbor lookup threshold value %d is out of range"
2425 " (Min: %d Max: %d)", lookUpThreshold,
2426 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2427 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2428 ret = -EINVAL;
2429 goto exit;
2430 }
2431
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302432 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2433 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2434 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2436 "%s: Received Command to Set Roam trigger"
2437 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2438
2439 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2440 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2441 if (eHAL_STATUS_SUCCESS != status)
2442 {
2443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2444 "%s: Failed to set roam trigger, try again", __func__);
2445 ret = -EPERM;
2446 goto exit;
2447 }
2448
2449 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302450 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002451 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2452 }
2453 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2454 {
2455 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2456 int rssi = (-1) * lookUpThreshold;
2457 char extra[32];
2458 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2460 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2461 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002462 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05302463 len = VOS_MIN(priv_data.total_len, len + 1);
2464 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002465 {
2466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2467 "%s: failed to copy data to user buffer", __func__);
2468 ret = -EFAULT;
2469 goto exit;
2470 }
2471 }
2472 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2473 {
2474 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002475 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002476 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002477
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478 /* input refresh period is in terms of seconds */
2479 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2480 value = value + 18;
2481 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002482 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002483 if (ret < 0)
2484 {
2485 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002486 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002488 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002489 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002490 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2491 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002492 ret = -EINVAL;
2493 goto exit;
2494 }
2495
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2497 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002498 {
2499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002500 "Roam scan period value %d is out of range"
2501 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002502 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2503 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002504 ret = -EINVAL;
2505 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302506 }
2507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2508 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2509 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002510 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002511
2512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2513 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002514 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002515
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002516 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2517 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002518 }
2519 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2520 {
2521 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2522 char extra[32];
2523 tANI_U8 len = 0;
2524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2526 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2527 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002528 len = scnprintf(extra, sizeof(extra), "%s %d",
2529 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002530 /* Returned value is in units of seconds */
2531 if (copy_to_user(priv_data.buf, &extra, len + 1))
2532 {
2533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2534 "%s: failed to copy data to user buffer", __func__);
2535 ret = -EFAULT;
2536 goto exit;
2537 }
2538 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002539 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2540 {
2541 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002542 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002543 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002544
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002545 /* input refresh period is in terms of seconds */
2546 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2547 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002548
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002549 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002550 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002551 if (ret < 0)
2552 {
2553 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002554 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002556 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002557 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002558 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2559 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2560 ret = -EINVAL;
2561 goto exit;
2562 }
2563
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002564 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2565 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2566 {
2567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2568 "Neighbor scan results refresh period value %d is out of range"
2569 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2570 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2571 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2572 ret = -EINVAL;
2573 goto exit;
2574 }
2575 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2576
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2578 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002579 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002580
2581 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2582 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2583 }
2584 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2585 {
2586 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2587 char extra[32];
2588 tANI_U8 len = 0;
2589
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002590 len = scnprintf(extra, sizeof(extra), "%s %d",
2591 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002592 /* Returned value is in units of seconds */
2593 if (copy_to_user(priv_data.buf, &extra, len + 1))
2594 {
2595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2596 "%s: failed to copy data to user buffer", __func__);
2597 ret = -EFAULT;
2598 goto exit;
2599 }
2600 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002601#ifdef FEATURE_WLAN_LFR
2602 /* SETROAMMODE */
2603 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2604 {
2605 tANI_U8 *value = command;
2606 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2607
2608 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2609 value = value + SIZE_OF_SETROAMMODE + 1;
2610
2611 /* Convert the value from ascii to integer */
2612 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2613 if (ret < 0)
2614 {
2615 /* If the input value is greater than max value of datatype, then also
2616 kstrtou8 fails */
2617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2618 "%s: kstrtou8 failed range [%d - %d]", __func__,
2619 CFG_LFR_FEATURE_ENABLED_MIN,
2620 CFG_LFR_FEATURE_ENABLED_MAX);
2621 ret = -EINVAL;
2622 goto exit;
2623 }
2624 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2625 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2626 {
2627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2628 "Roam Mode value %d is out of range"
2629 " (Min: %d Max: %d)", roamMode,
2630 CFG_LFR_FEATURE_ENABLED_MIN,
2631 CFG_LFR_FEATURE_ENABLED_MAX);
2632 ret = -EINVAL;
2633 goto exit;
2634 }
2635
2636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2637 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2638 /*
2639 * Note that
2640 * SETROAMMODE 0 is to enable LFR while
2641 * SETROAMMODE 1 is to disable LFR, but
2642 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2643 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2644 */
2645 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2646 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2647 else
2648 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2649
2650 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2651 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2652 }
2653 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302654 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002655 {
2656 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2657 char extra[32];
2658 tANI_U8 len = 0;
2659
2660 /*
2661 * roamMode value shall be inverted because the sementics is different.
2662 */
2663 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2664 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2665 else
2666 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2667
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002668 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002669 if (copy_to_user(priv_data.buf, &extra, len + 1))
2670 {
2671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2672 "%s: failed to copy data to user buffer", __func__);
2673 ret = -EFAULT;
2674 goto exit;
2675 }
2676 }
2677#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002678#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002679#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002680 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2681 {
2682 tANI_U8 *value = command;
2683 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2684
2685 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2686 value = value + 13;
2687 /* Convert the value from ascii to integer */
2688 ret = kstrtou8(value, 10, &roamRssiDiff);
2689 if (ret < 0)
2690 {
2691 /* If the input value is greater than max value of datatype, then also
2692 kstrtou8 fails */
2693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2694 "%s: kstrtou8 failed range [%d - %d]", __func__,
2695 CFG_ROAM_RSSI_DIFF_MIN,
2696 CFG_ROAM_RSSI_DIFF_MAX);
2697 ret = -EINVAL;
2698 goto exit;
2699 }
2700
2701 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2702 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2703 {
2704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2705 "Roam rssi diff value %d is out of range"
2706 " (Min: %d Max: %d)", roamRssiDiff,
2707 CFG_ROAM_RSSI_DIFF_MIN,
2708 CFG_ROAM_RSSI_DIFF_MAX);
2709 ret = -EINVAL;
2710 goto exit;
2711 }
2712
2713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2714 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2715
2716 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2717 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2718 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302719 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002720 {
2721 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2722 char extra[32];
2723 tANI_U8 len = 0;
2724
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302725 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2726 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2727 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002728 len = scnprintf(extra, sizeof(extra), "%s %d",
2729 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002730 if (copy_to_user(priv_data.buf, &extra, len + 1))
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: failed to copy data to user buffer", __func__);
2734 ret = -EFAULT;
2735 goto exit;
2736 }
2737 }
2738#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002739#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002740 else if (strncmp(command, "GETBAND", 7) == 0)
2741 {
2742 int band = -1;
2743 char extra[32];
2744 tANI_U8 len = 0;
2745 hdd_getBand_helper(pHddCtx, &band);
2746
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302747 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2748 TRACE_CODE_HDD_GETBAND_IOCTL,
2749 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002750 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002751 if (copy_to_user(priv_data.buf, &extra, len + 1))
2752 {
2753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 "%s: failed to copy data to user buffer", __func__);
2755 ret = -EFAULT;
2756 goto exit;
2757 }
2758 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002759 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2760 {
2761 tANI_U8 *value = command;
2762 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2763 tANI_U8 numChannels = 0;
2764 eHalStatus status = eHAL_STATUS_SUCCESS;
2765
2766 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2767 if (eHAL_STATUS_SUCCESS != status)
2768 {
2769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2770 "%s: Failed to parse channel list information", __func__);
2771 ret = -EINVAL;
2772 goto exit;
2773 }
2774
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302775 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2776 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2777 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002778 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2781 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2782 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2783 ret = -EINVAL;
2784 goto exit;
2785 }
2786 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2787 numChannels);
2788 if (eHAL_STATUS_SUCCESS != status)
2789 {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s: Failed to update channel list information", __func__);
2792 ret = -EINVAL;
2793 goto exit;
2794 }
2795 }
2796 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2797 {
2798 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2799 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002800 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002801 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002802 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002803
2804 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2805 ChannelList, &numChannels ))
2806 {
2807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2808 "%s: failed to get roam scan channel list", __func__);
2809 ret = -EFAULT;
2810 goto exit;
2811 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302812 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2813 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2814 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002815 /* output channel list is of the format
2816 [Number of roam scan channels][Channel1][Channel2]... */
2817 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002818 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002819 for (j = 0; (j < numChannels); j++)
2820 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002821 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2822 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002823 }
2824
2825 if (copy_to_user(priv_data.buf, &extra, len + 1))
2826 {
2827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2828 "%s: failed to copy data to user buffer", __func__);
2829 ret = -EFAULT;
2830 goto exit;
2831 }
2832 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002833 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2834 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002835 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002836 char extra[32];
2837 tANI_U8 len = 0;
2838
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002839 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002840 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002841 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002842 hdd_is_okc_mode_enabled(pHddCtx) &&
2843 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2844 {
2845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002846 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002847 " hence this operation is not permitted!", __func__);
2848 ret = -EPERM;
2849 goto exit;
2850 }
2851
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002852 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002853 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05302854 len = VOS_MIN(priv_data.total_len, len + 1);
2855 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002856 {
2857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2858 "%s: failed to copy data to user buffer", __func__);
2859 ret = -EFAULT;
2860 goto exit;
2861 }
2862 }
2863 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2864 {
2865 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2866 char extra[32];
2867 tANI_U8 len = 0;
2868
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002869 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002870 then this operation is not permitted (return FAILURE) */
2871 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002872 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002873 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2874 {
2875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002876 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002877 " hence this operation is not permitted!", __func__);
2878 ret = -EPERM;
2879 goto exit;
2880 }
2881
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002882 len = scnprintf(extra, sizeof(extra), "%s %d",
2883 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002884 if (copy_to_user(priv_data.buf, &extra, len + 1))
2885 {
2886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2887 "%s: failed to copy data to user buffer", __func__);
2888 ret = -EFAULT;
2889 goto exit;
2890 }
2891 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002892 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002893 {
2894 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2895 char extra[32];
2896 tANI_U8 len = 0;
2897
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002898 len = scnprintf(extra, sizeof(extra), "%s %d",
2899 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05302900 len = VOS_MIN(priv_data.total_len, len + 1);
2901 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002902 {
2903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2904 "%s: failed to copy data to user buffer", __func__);
2905 ret = -EFAULT;
2906 goto exit;
2907 }
2908 }
2909 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2910 {
2911 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2912 char extra[32];
2913 tANI_U8 len = 0;
2914
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002915 len = scnprintf(extra, sizeof(extra), "%s %d",
2916 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05302917 len = VOS_MIN(priv_data.total_len, len + 1);
2918 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002919 {
2920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2921 "%s: failed to copy data to user buffer", __func__);
2922 ret = -EFAULT;
2923 goto exit;
2924 }
2925 }
2926 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2927 {
2928 tANI_U8 *value = command;
2929 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2930
2931 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2932 value = value + 26;
2933 /* Convert the value from ascii to integer */
2934 ret = kstrtou8(value, 10, &minTime);
2935 if (ret < 0)
2936 {
2937 /* If the input value is greater than max value of datatype, then also
2938 kstrtou8 fails */
2939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2940 "%s: kstrtou8 failed range [%d - %d]", __func__,
2941 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2942 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2943 ret = -EINVAL;
2944 goto exit;
2945 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002946 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2947 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2948 {
2949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2950 "scan min channel time value %d is out of range"
2951 " (Min: %d Max: %d)", minTime,
2952 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2953 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2954 ret = -EINVAL;
2955 goto exit;
2956 }
2957
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302958 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2959 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2960 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2962 "%s: Received Command to change channel min time = %d", __func__, minTime);
2963
2964 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2965 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2966 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002967 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2968 {
2969 tANI_U8 *value = command;
2970 tANI_U8 channel = 0;
2971 tANI_U8 dwellTime = 0;
2972 tANI_U8 bufLen = 0;
2973 tANI_U8 *buf = NULL;
2974 tSirMacAddr targetApBssid;
2975 eHalStatus status = eHAL_STATUS_SUCCESS;
2976 struct ieee80211_channel chan;
2977 tANI_U8 finalLen = 0;
2978 tANI_U8 *finalBuf = NULL;
2979 tANI_U8 temp = 0;
2980 u64 cookie;
2981 hdd_station_ctx_t *pHddStaCtx = NULL;
2982 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2983
2984 /* if not associated, no need to send action frame */
2985 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2986 {
2987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2988 ret = -EINVAL;
2989 goto exit;
2990 }
2991
2992 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2993 &dwellTime, &buf, &bufLen);
2994 if (eHAL_STATUS_SUCCESS != status)
2995 {
2996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2997 "%s: Failed to parse send action frame data", __func__);
2998 ret = -EINVAL;
2999 goto exit;
3000 }
3001
3002 /* if the target bssid is different from currently associated AP,
3003 then no need to send action frame */
3004 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3005 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3006 {
3007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3008 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003009 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003010 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003011 goto exit;
3012 }
3013
3014 /* if the channel number is different from operating channel then
3015 no need to send action frame */
3016 if (channel != pHddStaCtx->conn_info.operationChannel)
3017 {
3018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3019 "%s: channel(%d) is different from operating channel(%d)",
3020 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3021 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003022 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003023 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003024 goto exit;
3025 }
3026 chan.center_freq = sme_ChnToFreq(channel);
3027
3028 finalLen = bufLen + 24;
3029 finalBuf = vos_mem_malloc(finalLen);
3030 if (NULL == finalBuf)
3031 {
3032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3033 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003034 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003035 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003036 goto exit;
3037 }
3038 vos_mem_zero(finalBuf, finalLen);
3039
3040 /* Fill subtype */
3041 temp = SIR_MAC_MGMT_ACTION << 4;
3042 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3043
3044 /* Fill type */
3045 temp = SIR_MAC_MGMT_FRAME;
3046 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3047
3048 /* Fill destination address (bssid of the AP) */
3049 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3050
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003051 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003052 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3053
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003054 /* Fill BSSID (AP mac address) */
3055 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003056
3057 /* Fill received buffer from 24th address */
3058 vos_mem_copy(finalBuf + 24, buf, bufLen);
3059
Jeff Johnson11c33152013-04-16 17:52:40 -07003060 /* done with the parsed buffer */
3061 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003062 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003063
DARAM SUDHA39eede62014-02-12 11:16:40 +05303064 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3066 &(pAdapter->wdev),
3067#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003068 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003069#endif
3070 &chan, 0,
3071#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3072 NL80211_CHAN_HT20, 1,
3073#endif
3074 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003075 1, &cookie );
3076 vos_mem_free(finalBuf);
3077 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003078 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3079 {
3080 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3081 char extra[32];
3082 tANI_U8 len = 0;
3083
3084 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003085 len = scnprintf(extra, sizeof(extra), "%s %d",
3086 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303087 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3088 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3089 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303090 len = VOS_MIN(priv_data.total_len, len + 1);
3091 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003092 {
3093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3094 "%s: failed to copy data to user buffer", __func__);
3095 ret = -EFAULT;
3096 goto exit;
3097 }
3098 }
3099 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3100 {
3101 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003102 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003103
3104 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3105 value = value + 19;
3106 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003107 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003108 if (ret < 0)
3109 {
3110 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003111 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003113 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003114 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3115 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3116 ret = -EINVAL;
3117 goto exit;
3118 }
3119
3120 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3121 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3122 {
3123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3124 "lfr mode value %d is out of range"
3125 " (Min: %d Max: %d)", maxTime,
3126 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3127 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3128 ret = -EINVAL;
3129 goto exit;
3130 }
3131
3132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3133 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3134
3135 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3136 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3137 }
3138 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3139 {
3140 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3141 char extra[32];
3142 tANI_U8 len = 0;
3143
3144 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003145 len = scnprintf(extra, sizeof(extra), "%s %d",
3146 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003147 if (copy_to_user(priv_data.buf, &extra, len + 1))
3148 {
3149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3150 "%s: failed to copy data to user buffer", __func__);
3151 ret = -EFAULT;
3152 goto exit;
3153 }
3154 }
3155 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3156 {
3157 tANI_U8 *value = command;
3158 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3159
3160 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3161 value = value + 16;
3162 /* Convert the value from ascii to integer */
3163 ret = kstrtou16(value, 10, &val);
3164 if (ret < 0)
3165 {
3166 /* If the input value is greater than max value of datatype, then also
3167 kstrtou16 fails */
3168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3169 "%s: kstrtou16 failed range [%d - %d]", __func__,
3170 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3171 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3172 ret = -EINVAL;
3173 goto exit;
3174 }
3175
3176 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3177 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3178 {
3179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3180 "scan home time value %d is out of range"
3181 " (Min: %d Max: %d)", val,
3182 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3183 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3184 ret = -EINVAL;
3185 goto exit;
3186 }
3187
3188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3189 "%s: Received Command to change scan home time = %d", __func__, val);
3190
3191 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3192 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3193 }
3194 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3195 {
3196 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3197 char extra[32];
3198 tANI_U8 len = 0;
3199
3200 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003201 len = scnprintf(extra, sizeof(extra), "%s %d",
3202 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003203 if (copy_to_user(priv_data.buf, &extra, len + 1))
3204 {
3205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3206 "%s: failed to copy data to user buffer", __func__);
3207 ret = -EFAULT;
3208 goto exit;
3209 }
3210 }
3211 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3212 {
3213 tANI_U8 *value = command;
3214 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3215
3216 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3217 value = value + 17;
3218 /* Convert the value from ascii to integer */
3219 ret = kstrtou8(value, 10, &val);
3220 if (ret < 0)
3221 {
3222 /* If the input value is greater than max value of datatype, then also
3223 kstrtou8 fails */
3224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3225 "%s: kstrtou8 failed range [%d - %d]", __func__,
3226 CFG_ROAM_INTRA_BAND_MIN,
3227 CFG_ROAM_INTRA_BAND_MAX);
3228 ret = -EINVAL;
3229 goto exit;
3230 }
3231
3232 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3233 (val > CFG_ROAM_INTRA_BAND_MAX))
3234 {
3235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3236 "intra band mode value %d is out of range"
3237 " (Min: %d Max: %d)", val,
3238 CFG_ROAM_INTRA_BAND_MIN,
3239 CFG_ROAM_INTRA_BAND_MAX);
3240 ret = -EINVAL;
3241 goto exit;
3242 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3244 "%s: Received Command to change intra band = %d", __func__, val);
3245
3246 pHddCtx->cfg_ini->nRoamIntraBand = val;
3247 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3248 }
3249 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3250 {
3251 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3252 char extra[32];
3253 tANI_U8 len = 0;
3254
3255 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003256 len = scnprintf(extra, sizeof(extra), "%s %d",
3257 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003258 if (copy_to_user(priv_data.buf, &extra, len + 1))
3259 {
3260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3261 "%s: failed to copy data to user buffer", __func__);
3262 ret = -EFAULT;
3263 goto exit;
3264 }
3265 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003266 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3267 {
3268 tANI_U8 *value = command;
3269 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3270
3271 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3272 value = value + 15;
3273 /* Convert the value from ascii to integer */
3274 ret = kstrtou8(value, 10, &nProbes);
3275 if (ret < 0)
3276 {
3277 /* If the input value is greater than max value of datatype, then also
3278 kstrtou8 fails */
3279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3280 "%s: kstrtou8 failed range [%d - %d]", __func__,
3281 CFG_ROAM_SCAN_N_PROBES_MIN,
3282 CFG_ROAM_SCAN_N_PROBES_MAX);
3283 ret = -EINVAL;
3284 goto exit;
3285 }
3286
3287 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3288 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3289 {
3290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3291 "NProbes value %d is out of range"
3292 " (Min: %d Max: %d)", nProbes,
3293 CFG_ROAM_SCAN_N_PROBES_MIN,
3294 CFG_ROAM_SCAN_N_PROBES_MAX);
3295 ret = -EINVAL;
3296 goto exit;
3297 }
3298
3299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3300 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3301
3302 pHddCtx->cfg_ini->nProbes = nProbes;
3303 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3304 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303305 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003306 {
3307 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3308 char extra[32];
3309 tANI_U8 len = 0;
3310
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003311 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003312 if (copy_to_user(priv_data.buf, &extra, len + 1))
3313 {
3314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3315 "%s: failed to copy data to user buffer", __func__);
3316 ret = -EFAULT;
3317 goto exit;
3318 }
3319 }
3320 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3321 {
3322 tANI_U8 *value = command;
3323 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3324
3325 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3326 /* input value is in units of msec */
3327 value = value + 20;
3328 /* Convert the value from ascii to integer */
3329 ret = kstrtou16(value, 10, &homeAwayTime);
3330 if (ret < 0)
3331 {
3332 /* If the input value is greater than max value of datatype, then also
3333 kstrtou8 fails */
3334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3335 "%s: kstrtou8 failed range [%d - %d]", __func__,
3336 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3337 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3338 ret = -EINVAL;
3339 goto exit;
3340 }
3341
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003342 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3343 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3344 {
3345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3346 "homeAwayTime value %d is out of range"
3347 " (Min: %d Max: %d)", homeAwayTime,
3348 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3349 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3350 ret = -EINVAL;
3351 goto exit;
3352 }
3353
3354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3355 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003356 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3357 {
3358 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3359 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3360 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003361 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303362 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003363 {
3364 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3365 char extra[32];
3366 tANI_U8 len = 0;
3367
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003368 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003369 if (copy_to_user(priv_data.buf, &extra, len + 1))
3370 {
3371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3372 "%s: failed to copy data to user buffer", __func__);
3373 ret = -EFAULT;
3374 goto exit;
3375 }
3376 }
3377 else if (strncmp(command, "REASSOC", 7) == 0)
3378 {
3379 tANI_U8 *value = command;
3380 tANI_U8 channel = 0;
3381 tSirMacAddr targetApBssid;
3382 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003383#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3384 tCsrHandoffRequest handoffInfo;
3385#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003386 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003387 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3388
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003389 /* if not associated, no need to proceed with reassoc */
3390 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3391 {
3392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3393 ret = -EINVAL;
3394 goto exit;
3395 }
3396
3397 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3398 if (eHAL_STATUS_SUCCESS != status)
3399 {
3400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3401 "%s: Failed to parse reassoc command data", __func__);
3402 ret = -EINVAL;
3403 goto exit;
3404 }
3405
3406 /* if the target bssid is same as currently associated AP,
3407 then no need to proceed with reassoc */
3408 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3409 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3410 {
3411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3412 ret = -EINVAL;
3413 goto exit;
3414 }
3415
3416 /* Check channel number is a valid channel number */
3417 if(VOS_STATUS_SUCCESS !=
3418 wlan_hdd_validate_operation_channel(pAdapter, channel))
3419 {
3420 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003421 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003422 return -EINVAL;
3423 }
3424
3425 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003426#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3427 handoffInfo.channel = channel;
3428 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3429 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3430#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003431 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003432 else if (strncmp(command, "SETWESMODE", 10) == 0)
3433 {
3434 tANI_U8 *value = command;
3435 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3436
3437 /* Move pointer to ahead of SETWESMODE<delimiter> */
3438 value = value + 11;
3439 /* Convert the value from ascii to integer */
3440 ret = kstrtou8(value, 10, &wesMode);
3441 if (ret < 0)
3442 {
3443 /* If the input value is greater than max value of datatype, then also
3444 kstrtou8 fails */
3445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3446 "%s: kstrtou8 failed range [%d - %d]", __func__,
3447 CFG_ENABLE_WES_MODE_NAME_MIN,
3448 CFG_ENABLE_WES_MODE_NAME_MAX);
3449 ret = -EINVAL;
3450 goto exit;
3451 }
3452
3453 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3454 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3455 {
3456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3457 "WES Mode value %d is out of range"
3458 " (Min: %d Max: %d)", wesMode,
3459 CFG_ENABLE_WES_MODE_NAME_MIN,
3460 CFG_ENABLE_WES_MODE_NAME_MAX);
3461 ret = -EINVAL;
3462 goto exit;
3463 }
3464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3465 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3466
3467 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3468 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3469 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303470 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003471 {
3472 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3473 char extra[32];
3474 tANI_U8 len = 0;
3475
Arif Hussain826d9412013-11-12 16:44:54 -08003476 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003477 if (copy_to_user(priv_data.buf, &extra, len + 1))
3478 {
3479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3480 "%s: failed to copy data to user buffer", __func__);
3481 ret = -EFAULT;
3482 goto exit;
3483 }
3484 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003485#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003486#ifdef FEATURE_WLAN_LFR
3487 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3488 {
3489 tANI_U8 *value = command;
3490 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3491
3492 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3493 value = value + 12;
3494 /* Convert the value from ascii to integer */
3495 ret = kstrtou8(value, 10, &lfrMode);
3496 if (ret < 0)
3497 {
3498 /* If the input value is greater than max value of datatype, then also
3499 kstrtou8 fails */
3500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3501 "%s: kstrtou8 failed range [%d - %d]", __func__,
3502 CFG_LFR_FEATURE_ENABLED_MIN,
3503 CFG_LFR_FEATURE_ENABLED_MAX);
3504 ret = -EINVAL;
3505 goto exit;
3506 }
3507
3508 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3509 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3510 {
3511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3512 "lfr mode value %d is out of range"
3513 " (Min: %d Max: %d)", lfrMode,
3514 CFG_LFR_FEATURE_ENABLED_MIN,
3515 CFG_LFR_FEATURE_ENABLED_MAX);
3516 ret = -EINVAL;
3517 goto exit;
3518 }
3519
3520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3521 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3522
3523 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3524 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3525 }
3526#endif
3527#ifdef WLAN_FEATURE_VOWIFI_11R
3528 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3529 {
3530 tANI_U8 *value = command;
3531 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3532
3533 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3534 value = value + 18;
3535 /* Convert the value from ascii to integer */
3536 ret = kstrtou8(value, 10, &ft);
3537 if (ret < 0)
3538 {
3539 /* If the input value is greater than max value of datatype, then also
3540 kstrtou8 fails */
3541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3542 "%s: kstrtou8 failed range [%d - %d]", __func__,
3543 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3544 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3545 ret = -EINVAL;
3546 goto exit;
3547 }
3548
3549 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3550 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3551 {
3552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3553 "ft mode value %d is out of range"
3554 " (Min: %d Max: %d)", ft,
3555 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3556 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3557 ret = -EINVAL;
3558 goto exit;
3559 }
3560
3561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3562 "%s: Received Command to change ft mode = %d", __func__, ft);
3563
3564 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3565 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3566 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303567 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3568 {
3569 tANI_U8 *value = command;
3570 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303571
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303572 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3573 value = value + 15;
3574 /* Convert the value from ascii to integer */
3575 ret = kstrtou8(value, 10, &dfsScanMode);
3576 if (ret < 0)
3577 {
3578 /* If the input value is greater than max value of
3579 datatype, then also kstrtou8 fails
3580 */
3581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3582 "%s: kstrtou8 failed range [%d - %d]", __func__,
3583 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3584 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3585 ret = -EINVAL;
3586 goto exit;
3587 }
3588
3589 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3590 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3591 {
3592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3593 "dfsScanMode value %d is out of range"
3594 " (Min: %d Max: %d)", dfsScanMode,
3595 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3596 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3597 ret = -EINVAL;
3598 goto exit;
3599 }
3600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3601 "%s: Received Command to Set DFS Scan Mode = %d",
3602 __func__, dfsScanMode);
3603
3604 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3605 }
3606 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3607 {
3608 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3609 char extra[32];
3610 tANI_U8 len = 0;
3611
3612 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3613 if (copy_to_user(priv_data.buf, &extra, len + 1))
3614 {
3615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3616 "%s: failed to copy data to user buffer", __func__);
3617 ret = -EFAULT;
3618 goto exit;
3619 }
3620 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303621 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3622 {
3623 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303624 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303625 tSirMacAddr targetApBssid;
3626 tANI_U8 trigger = 0;
3627 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303628 tHalHandle hHal;
3629 v_U32_t roamId = 0;
3630 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303631 hdd_station_ctx_t *pHddStaCtx = NULL;
3632 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303633 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303634
3635 /* if not associated, no need to proceed with reassoc */
3636 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3637 {
3638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3639 ret = -EINVAL;
3640 goto exit;
3641 }
3642
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303643 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303644 if (eHAL_STATUS_SUCCESS != status)
3645 {
3646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3647 "%s: Failed to parse reassoc command data", __func__);
3648 ret = -EINVAL;
3649 goto exit;
3650 }
3651
3652 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303653 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303654 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3655 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3656 {
3657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3658 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3659 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303660 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3661 &modProfileFields);
3662 sme_RoamReassoc(hHal, pAdapter->sessionId,
3663 NULL, modProfileFields, &roamId, 1);
3664 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303665 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303666
3667 /* Check channel number is a valid channel number */
3668 if(VOS_STATUS_SUCCESS !=
3669 wlan_hdd_validate_operation_channel(pAdapter, channel))
3670 {
3671 hddLog(VOS_TRACE_LEVEL_ERROR,
3672 "%s: Invalid Channel [%d]", __func__, channel);
3673 return -EINVAL;
3674 }
3675
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303676 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303677
3678 /* Proceed with scan/roam */
3679 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3680 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303681 (tSmeFastRoamTrigger)(trigger),
3682 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303683 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003684#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003685#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003686 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3687 {
3688 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003689 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003690
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003691 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003692 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003693 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003694 hdd_is_okc_mode_enabled(pHddCtx) &&
3695 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3696 {
3697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003698 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003699 " hence this operation is not permitted!", __func__);
3700 ret = -EPERM;
3701 goto exit;
3702 }
3703
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003704 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3705 value = value + 11;
3706 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003707 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003708 if (ret < 0)
3709 {
3710 /* If the input value is greater than max value of datatype, then also
3711 kstrtou8 fails */
3712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3713 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003714 CFG_ESE_FEATURE_ENABLED_MIN,
3715 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003716 ret = -EINVAL;
3717 goto exit;
3718 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003719 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3720 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003721 {
3722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003723 "Ese mode value %d is out of range"
3724 " (Min: %d Max: %d)", eseMode,
3725 CFG_ESE_FEATURE_ENABLED_MIN,
3726 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003727 ret = -EINVAL;
3728 goto exit;
3729 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003731 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003732
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003733 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3734 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003735 }
3736#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003737 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3738 {
3739 tANI_U8 *value = command;
3740 tANI_BOOLEAN roamScanControl = 0;
3741
3742 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3743 value = value + 19;
3744 /* Convert the value from ascii to integer */
3745 ret = kstrtou8(value, 10, &roamScanControl);
3746 if (ret < 0)
3747 {
3748 /* If the input value is greater than max value of datatype, then also
3749 kstrtou8 fails */
3750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3751 "%s: kstrtou8 failed ", __func__);
3752 ret = -EINVAL;
3753 goto exit;
3754 }
3755
3756 if (0 != roamScanControl)
3757 {
3758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3759 "roam scan control invalid value = %d",
3760 roamScanControl);
3761 ret = -EINVAL;
3762 goto exit;
3763 }
3764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3765 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3766
3767 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3768 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003769#ifdef FEATURE_WLAN_OKC
3770 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3771 {
3772 tANI_U8 *value = command;
3773 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3774
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003775 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003776 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003777 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003778 hdd_is_okc_mode_enabled(pHddCtx) &&
3779 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3780 {
3781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003782 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003783 " hence this operation is not permitted!", __func__);
3784 ret = -EPERM;
3785 goto exit;
3786 }
3787
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003788 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3789 value = value + 11;
3790 /* Convert the value from ascii to integer */
3791 ret = kstrtou8(value, 10, &okcMode);
3792 if (ret < 0)
3793 {
3794 /* If the input value is greater than max value of datatype, then also
3795 kstrtou8 fails */
3796 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3797 "%s: kstrtou8 failed range [%d - %d]", __func__,
3798 CFG_OKC_FEATURE_ENABLED_MIN,
3799 CFG_OKC_FEATURE_ENABLED_MAX);
3800 ret = -EINVAL;
3801 goto exit;
3802 }
3803
3804 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3805 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3806 {
3807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3808 "Okc mode value %d is out of range"
3809 " (Min: %d Max: %d)", okcMode,
3810 CFG_OKC_FEATURE_ENABLED_MIN,
3811 CFG_OKC_FEATURE_ENABLED_MAX);
3812 ret = -EINVAL;
3813 goto exit;
3814 }
3815
3816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3817 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3818
3819 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3820 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003821#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303822 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003823 {
3824 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3825 char extra[32];
3826 tANI_U8 len = 0;
3827
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003828 len = scnprintf(extra, sizeof(extra), "%s %d",
3829 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003830 if (copy_to_user(priv_data.buf, &extra, len + 1))
3831 {
3832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3833 "%s: failed to copy data to user buffer", __func__);
3834 ret = -EFAULT;
3835 goto exit;
3836 }
3837 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303838#ifdef WLAN_FEATURE_PACKET_FILTERING
3839 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3840 {
3841 tANI_U8 filterType = 0;
3842 tANI_U8 *value = command;
3843
3844 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3845 value = value + 22;
3846
3847 /* Convert the value from ascii to integer */
3848 ret = kstrtou8(value, 10, &filterType);
3849 if (ret < 0)
3850 {
3851 /* If the input value is greater than max value of datatype,
3852 * then also kstrtou8 fails
3853 */
3854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3855 "%s: kstrtou8 failed range ", __func__);
3856 ret = -EINVAL;
3857 goto exit;
3858 }
3859
3860 if (filterType != 0 && filterType != 1)
3861 {
3862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3863 "%s: Accepted Values are 0 and 1 ", __func__);
3864 ret = -EINVAL;
3865 goto exit;
3866 }
3867 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3868 pAdapter->sessionId);
3869 }
3870#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303871 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3872 {
Kiet Lamad161252014-07-22 11:23:32 -07003873 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303874 int ret;
3875
Kiet Lamad161252014-07-22 11:23:32 -07003876 dhcpPhase = command + 11;
3877 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303878 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003880 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303881
3882 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003883
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303884 ret = wlan_hdd_scan_abort(pAdapter);
3885 if (ret < 0)
3886 {
3887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3888 FL("failed to abort existing scan %d"), ret);
3889 }
3890
Kiet Lamad161252014-07-22 11:23:32 -07003891 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3892 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303893 }
Kiet Lamad161252014-07-22 11:23:32 -07003894 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303895 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003897 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303898
3899 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003900
3901 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3902 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303903 }
3904 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003905 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3906 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3908 FL("making default scan to ACTIVE"));
3909 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003910 }
3911 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3912 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3914 FL("making default scan to PASSIVE"));
3915 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003916 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303917 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3918 {
3919 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3920 char extra[32];
3921 tANI_U8 len = 0;
3922
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303923 memset(extra, 0, sizeof(extra));
3924 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3925 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303926 {
3927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3928 "%s: failed to copy data to user buffer", __func__);
3929 ret = -EFAULT;
3930 goto exit;
3931 }
3932 ret = len;
3933 }
3934 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3935 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303936 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303937 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003938 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3939 {
3940 tANI_U8 filterType = 0;
3941 tANI_U8 *value;
3942 value = command + 9;
3943
3944 /* Convert the value from ascii to integer */
3945 ret = kstrtou8(value, 10, &filterType);
3946 if (ret < 0)
3947 {
3948 /* If the input value is greater than max value of datatype,
3949 * then also kstrtou8 fails
3950 */
3951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3952 "%s: kstrtou8 failed range ", __func__);
3953 ret = -EINVAL;
3954 goto exit;
3955 }
3956 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3957 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3958 {
3959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3960 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3961 " 2-Sink ", __func__);
3962 ret = -EINVAL;
3963 goto exit;
3964 }
3965 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3966 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303967 pScanInfo = &pHddCtx->scan_info;
3968 if (filterType && pScanInfo != NULL &&
3969 pHddCtx->scan_info.mScanPending)
3970 {
3971 /*Miracast Session started. Abort Scan */
3972 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3973 "%s, Aborting Scan For Miracast",__func__);
3974 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3975 eCSR_SCAN_ABORT_DEFAULT);
3976 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003977 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303978 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003979 }
Leo Chang614d2072013-08-22 14:59:44 -07003980 else if (strncmp(command, "SETMCRATE", 9) == 0)
3981 {
Leo Chang614d2072013-08-22 14:59:44 -07003982 tANI_U8 *value = command;
3983 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003984 tSirRateUpdateInd *rateUpdate;
3985 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003986
3987 /* Only valid for SAP mode */
3988 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3989 {
3990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3991 "%s: SAP mode is not running", __func__);
3992 ret = -EFAULT;
3993 goto exit;
3994 }
3995
3996 /* Move pointer to ahead of SETMCRATE<delimiter> */
3997 /* input value is in units of hundred kbps */
3998 value = value + 10;
3999 /* Convert the value from ascii to integer, decimal base */
4000 ret = kstrtouint(value, 10, &targetRate);
4001
Leo Chang1f98cbd2013-10-17 15:03:52 -07004002 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4003 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004004 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004005 hddLog(VOS_TRACE_LEVEL_ERROR,
4006 "%s: SETMCRATE indication alloc fail", __func__);
4007 ret = -EFAULT;
4008 goto exit;
4009 }
4010 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4011
4012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4013 "MC Target rate %d", targetRate);
4014 /* Ignore unicast */
4015 rateUpdate->ucastDataRate = -1;
4016 rateUpdate->mcastDataRate24GHz = targetRate;
4017 rateUpdate->mcastDataRate5GHz = targetRate;
4018 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4019 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4020 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4021 if (eHAL_STATUS_SUCCESS != status)
4022 {
4023 hddLog(VOS_TRACE_LEVEL_ERROR,
4024 "%s: SET_MC_RATE failed", __func__);
4025 vos_mem_free(rateUpdate);
4026 ret = -EFAULT;
4027 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004028 }
4029 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304030#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004031 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304032 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004033 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304034 }
4035#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004036#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004037 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
4038 {
4039 tANI_U8 *value = command;
4040 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4041 tANI_U8 numChannels = 0;
4042 eHalStatus status = eHAL_STATUS_SUCCESS;
4043
4044 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4045 if (eHAL_STATUS_SUCCESS != status)
4046 {
4047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4048 "%s: Failed to parse channel list information", __func__);
4049 ret = -EINVAL;
4050 goto exit;
4051 }
4052
4053 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4054 {
4055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4056 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4057 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4058 ret = -EINVAL;
4059 goto exit;
4060 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004061 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004062 ChannelList,
4063 numChannels);
4064 if (eHAL_STATUS_SUCCESS != status)
4065 {
4066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4067 "%s: Failed to update channel list information", __func__);
4068 ret = -EINVAL;
4069 goto exit;
4070 }
4071 }
4072 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4073 {
4074 tANI_U8 *value = command;
4075 char extra[128] = {0};
4076 int len = 0;
4077 tANI_U8 tid = 0;
4078 hdd_station_ctx_t *pHddStaCtx = NULL;
4079 tAniTrafStrmMetrics tsmMetrics;
4080 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4081
4082 /* if not associated, return error */
4083 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4084 {
4085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4086 ret = -EINVAL;
4087 goto exit;
4088 }
4089
4090 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4091 value = value + 12;
4092 /* Convert the value from ascii to integer */
4093 ret = kstrtou8(value, 10, &tid);
4094 if (ret < 0)
4095 {
4096 /* If the input value is greater than max value of datatype, then also
4097 kstrtou8 fails */
4098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4099 "%s: kstrtou8 failed range [%d - %d]", __func__,
4100 TID_MIN_VALUE,
4101 TID_MAX_VALUE);
4102 ret = -EINVAL;
4103 goto exit;
4104 }
4105
4106 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4107 {
4108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4109 "tid value %d is out of range"
4110 " (Min: %d Max: %d)", tid,
4111 TID_MIN_VALUE,
4112 TID_MAX_VALUE);
4113 ret = -EINVAL;
4114 goto exit;
4115 }
4116
4117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4118 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4119
4120 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4121 {
4122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4123 "%s: failed to get tsm stats", __func__);
4124 ret = -EFAULT;
4125 goto exit;
4126 }
4127
4128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4129 "UplinkPktQueueDly(%d)\n"
4130 "UplinkPktQueueDlyHist[0](%d)\n"
4131 "UplinkPktQueueDlyHist[1](%d)\n"
4132 "UplinkPktQueueDlyHist[2](%d)\n"
4133 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304134 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004135 "UplinkPktLoss(%d)\n"
4136 "UplinkPktCount(%d)\n"
4137 "RoamingCount(%d)\n"
4138 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4139 tsmMetrics.UplinkPktQueueDlyHist[0],
4140 tsmMetrics.UplinkPktQueueDlyHist[1],
4141 tsmMetrics.UplinkPktQueueDlyHist[2],
4142 tsmMetrics.UplinkPktQueueDlyHist[3],
4143 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4144 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4145
4146 /* Output TSM stats is of the format
4147 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4148 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004149 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004150 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4151 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4152 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4153 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4154 tsmMetrics.RoamingDly);
4155
4156 if (copy_to_user(priv_data.buf, &extra, len + 1))
4157 {
4158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4159 "%s: failed to copy data to user buffer", __func__);
4160 ret = -EFAULT;
4161 goto exit;
4162 }
4163 }
4164 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4165 {
4166 tANI_U8 *value = command;
4167 tANI_U8 *cckmIe = NULL;
4168 tANI_U8 cckmIeLen = 0;
4169 eHalStatus status = eHAL_STATUS_SUCCESS;
4170
4171 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4172 if (eHAL_STATUS_SUCCESS != status)
4173 {
4174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4175 "%s: Failed to parse cckm ie data", __func__);
4176 ret = -EINVAL;
4177 goto exit;
4178 }
4179
4180 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4181 {
4182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4183 "%s: CCKM Ie input length is more than max[%d]", __func__,
4184 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004185 vos_mem_free(cckmIe);
4186 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004187 ret = -EINVAL;
4188 goto exit;
4189 }
4190 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004191 vos_mem_free(cckmIe);
4192 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004193 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004194 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4195 {
4196 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004197 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004198 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004199
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004200 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004201 if (eHAL_STATUS_SUCCESS != status)
4202 {
4203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004204 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004205 ret = -EINVAL;
4206 goto exit;
4207 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004208 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4209 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4210 hdd_indicateEseBcnReportNoResults (pAdapter,
4211 eseBcnReq.bcnReq[0].measurementToken,
4212 0x02, //BIT(1) set for measurement done
4213 0); // no BSS
4214 goto exit;
4215 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004216
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004217 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4218 if (eHAL_STATUS_SUCCESS != status)
4219 {
4220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4221 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4222 ret = -EINVAL;
4223 goto exit;
4224 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004225 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004226#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304227 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4228 {
4229 eHalStatus status;
4230 char buf[32], len;
4231 long waitRet;
4232 bcnMissRateContext_t getBcnMissRateCtx;
4233
4234 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4235
4236 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4237 {
4238 hddLog(VOS_TRACE_LEVEL_WARN,
4239 FL("GETBCNMISSRATE: STA is not in connected state"));
4240 ret = -1;
4241 goto exit;
4242 }
4243
4244 init_completion(&(getBcnMissRateCtx.completion));
4245 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4246
4247 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4248 pAdapter->sessionId,
4249 (void *)getBcnMissRateCB,
4250 (void *)(&getBcnMissRateCtx));
4251 if( eHAL_STATUS_SUCCESS != status)
4252 {
4253 hddLog(VOS_TRACE_LEVEL_INFO,
4254 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4255 ret = -EINVAL;
4256 goto exit;
4257 }
4258
4259 waitRet = wait_for_completion_interruptible_timeout
4260 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4261 if(waitRet <= 0)
4262 {
4263 hddLog(VOS_TRACE_LEVEL_ERROR,
4264 FL("failed to wait on bcnMissRateComp %d"), ret);
4265
4266 //Make magic number to zero so that callback is not called.
4267 spin_lock(&hdd_context_lock);
4268 getBcnMissRateCtx.magic = 0x0;
4269 spin_unlock(&hdd_context_lock);
4270 ret = -EINVAL;
4271 goto exit;
4272 }
4273
4274 hddLog(VOS_TRACE_LEVEL_INFO,
4275 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4276
4277 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4278 if (copy_to_user(priv_data.buf, &buf, len + 1))
4279 {
4280 hddLog(VOS_TRACE_LEVEL_ERROR,
4281 "%s: failed to copy data to user buffer", __func__);
4282 ret = -EFAULT;
4283 goto exit;
4284 }
4285 ret = len;
4286 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304287#ifdef FEATURE_WLAN_TDLS
4288 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4289 tANI_U8 *value = command;
4290 int set_value;
4291 /* Move pointer to ahead of TDLSOFFCH*/
4292 value += 26;
4293 sscanf(value, "%d", &set_value);
4294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4295 "%s: Tdls offchannel offset:%d",
4296 __func__, set_value);
4297 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4298 if (ret < 0)
4299 {
4300 ret = -EINVAL;
4301 goto exit;
4302 }
4303
4304 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4305 tANI_U8 *value = command;
4306 int set_value;
4307 /* Move pointer to ahead of tdlsoffchnmode*/
4308 value += 18;
4309 sscanf(value, "%d", &set_value);
4310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4311 "%s: Tdls offchannel mode:%d",
4312 __func__, set_value);
4313 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4314 if (ret < 0)
4315 {
4316 ret = -EINVAL;
4317 goto exit;
4318 }
4319 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4320 tANI_U8 *value = command;
4321 int set_value;
4322 /* Move pointer to ahead of TDLSOFFCH*/
4323 value += 14;
4324 sscanf(value, "%d", &set_value);
4325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4326 "%s: Tdls offchannel num: %d",
4327 __func__, set_value);
4328 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4329 if (ret < 0)
4330 {
4331 ret = -EINVAL;
4332 goto exit;
4333 }
4334 }
4335#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304336 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4337 {
4338 eHalStatus status;
4339 char *buf = NULL;
4340 char len;
4341 long waitRet;
4342 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304343 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304344 tANI_U8 *ptr = command;
4345 int stats = *(ptr + 11) - '0';
4346
4347 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4348 if (!IS_FEATURE_FW_STATS_ENABLE)
4349 {
4350 hddLog(VOS_TRACE_LEVEL_INFO,
4351 FL("Get Firmware stats feature not supported"));
4352 ret = -EINVAL;
4353 goto exit;
4354 }
4355
4356 if (FW_STATS_MAX <= stats || 0 >= stats)
4357 {
4358 hddLog(VOS_TRACE_LEVEL_INFO,
4359 FL(" stats %d not supported"),stats);
4360 ret = -EINVAL;
4361 goto exit;
4362 }
4363
4364 init_completion(&(fwStatsCtx.completion));
4365 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4366 fwStatsCtx.pAdapter = pAdapter;
4367 fwStatsRsp->type = 0;
4368 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304369 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304370 if (eHAL_STATUS_SUCCESS != status)
4371 {
4372 hddLog(VOS_TRACE_LEVEL_ERROR,
4373 FL(" fail to post WDA cmd status = %d"), status);
4374 ret = -EINVAL;
4375 goto exit;
4376 }
4377 waitRet = wait_for_completion_timeout
4378 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4379 if (waitRet <= 0)
4380 {
4381 hddLog(VOS_TRACE_LEVEL_ERROR,
4382 FL("failed to wait on GwtFwstats"));
4383 //Make magic number to zero so that callback is not executed.
4384 spin_lock(&hdd_context_lock);
4385 fwStatsCtx.magic = 0x0;
4386 spin_unlock(&hdd_context_lock);
4387 ret = -EINVAL;
4388 goto exit;
4389 }
4390 if (fwStatsRsp->type)
4391 {
4392 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4393 if (!buf)
4394 {
4395 hddLog(VOS_TRACE_LEVEL_ERROR,
4396 FL(" failed to allocate memory"));
4397 ret = -ENOMEM;
4398 goto exit;
4399 }
4400 switch( fwStatsRsp->type )
4401 {
4402 case FW_UBSP_STATS:
4403 {
4404 len = snprintf(buf, FW_STATE_RSP_LEN,
4405 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304406 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4407 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304408 }
4409 break;
4410 default:
4411 {
4412 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4413 ret = -EFAULT;
4414 kfree(buf);
4415 goto exit;
4416 }
4417 }
4418 if (copy_to_user(priv_data.buf, buf, len + 1))
4419 {
4420 hddLog(VOS_TRACE_LEVEL_ERROR,
4421 FL(" failed to copy data to user buffer"));
4422 ret = -EFAULT;
4423 kfree(buf);
4424 goto exit;
4425 }
4426 ret = len;
4427 kfree(buf);
4428 }
4429 else
4430 {
4431 hddLog(VOS_TRACE_LEVEL_ERROR,
4432 FL("failed to fetch the stats"));
4433 ret = -EFAULT;
4434 goto exit;
4435 }
4436
4437 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05304438 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
4439 {
4440 /*
4441 * this command wld be called by user-space when it detects WLAN
4442 * ON after airplane mode is set. When APM is set, WLAN turns off.
4443 * But it can be turned back on. Otherwise; when APM is turned back
4444 * off, WLAN wld turn back on. So at that point the command is
4445 * expected to come down. 0 means disable, 1 means enable. The
4446 * constraint is removed when parameter 1 is set or different
4447 * country code is set
4448 */
4449 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
4450 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004451 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304452 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4453 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4454 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304455 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4456 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004458 }
4459exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304460 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004461 if (command)
4462 {
4463 kfree(command);
4464 }
4465 return ret;
4466}
4467
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004468#ifdef CONFIG_COMPAT
4469static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4470{
4471 struct {
4472 compat_uptr_t buf;
4473 int used_len;
4474 int total_len;
4475 } compat_priv_data;
4476 hdd_priv_data_t priv_data;
4477 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004478
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004479 /*
4480 * Note that pAdapter and ifr have already been verified by caller,
4481 * and HDD context has also been validated
4482 */
4483 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4484 sizeof(compat_priv_data))) {
4485 ret = -EFAULT;
4486 goto exit;
4487 }
4488 priv_data.buf = compat_ptr(compat_priv_data.buf);
4489 priv_data.used_len = compat_priv_data.used_len;
4490 priv_data.total_len = compat_priv_data.total_len;
4491 ret = hdd_driver_command(pAdapter, &priv_data);
4492 exit:
4493 return ret;
4494}
4495#else /* CONFIG_COMPAT */
4496static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4497{
4498 /* will never be invoked */
4499 return 0;
4500}
4501#endif /* CONFIG_COMPAT */
4502
4503static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4504{
4505 hdd_priv_data_t priv_data;
4506 int ret = 0;
4507
4508 /*
4509 * Note that pAdapter and ifr have already been verified by caller,
4510 * and HDD context has also been validated
4511 */
4512 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4513 ret = -EFAULT;
4514 } else {
4515 ret = hdd_driver_command(pAdapter, &priv_data);
4516 }
4517 return ret;
4518}
4519
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304520int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004521{
4522 hdd_adapter_t *pAdapter;
4523 hdd_context_t *pHddCtx;
4524 int ret;
4525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304526 ENTER();
4527
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004528 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4529 if (NULL == pAdapter) {
4530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4531 "%s: HDD adapter context is Null", __func__);
4532 ret = -ENODEV;
4533 goto exit;
4534 }
4535 if (dev != pAdapter->dev) {
4536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4537 "%s: HDD adapter/dev inconsistency", __func__);
4538 ret = -ENODEV;
4539 goto exit;
4540 }
4541
4542 if ((!ifr) || (!ifr->ifr_data)) {
4543 ret = -EINVAL;
4544 goto exit;
4545 }
4546
4547 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4548 ret = wlan_hdd_validate_context(pHddCtx);
4549 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004550 ret = -EBUSY;
4551 goto exit;
4552 }
4553
4554 switch (cmd) {
4555 case (SIOCDEVPRIVATE + 1):
4556 if (is_compat_task())
4557 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4558 else
4559 ret = hdd_driver_ioctl(pAdapter, ifr);
4560 break;
4561 default:
4562 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4563 __func__, cmd);
4564 ret = -EINVAL;
4565 break;
4566 }
4567 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304568 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004569 return ret;
4570}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004571
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304572int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4573{
4574 int ret;
4575
4576 vos_ssr_protect(__func__);
4577 ret = __hdd_ioctl(dev, ifr, cmd);
4578 vos_ssr_unprotect(__func__);
4579
4580 return ret;
4581}
4582
Katya Nigame7b69a82015-04-28 15:24:06 +05304583int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4584{
4585 return 0;
4586}
4587
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004588#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004589/**---------------------------------------------------------------------------
4590
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004591 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004592
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004593 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004594 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4595 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4596 <space>Scan Mode N<space>Meas Duration N
4597 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4598 then take N.
4599 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4600 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4601 This function does not take care of removing duplicate channels from the list
4602
4603 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004604 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004605
4606 \return - 0 for success non-zero for failure
4607
4608 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004609static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4610 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004611{
4612 tANI_U8 *inPtr = pValue;
4613 int tempInt = 0;
4614 int j = 0, i = 0, v = 0;
4615 char buf[32];
4616
4617 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4618 /*no argument after the command*/
4619 if (NULL == inPtr)
4620 {
4621 return -EINVAL;
4622 }
4623 /*no space after the command*/
4624 else if (SPACE_ASCII_VALUE != *inPtr)
4625 {
4626 return -EINVAL;
4627 }
4628
4629 /*removing empty spaces*/
4630 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4631
4632 /*no argument followed by spaces*/
4633 if ('\0' == *inPtr) return -EINVAL;
4634
4635 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004636 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004637 if (1 != v) return -EINVAL;
4638
4639 v = kstrtos32(buf, 10, &tempInt);
4640 if ( v < 0) return -EINVAL;
4641
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004642 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004643
4644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004645 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004646
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004647 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004648 {
4649 for (i = 0; i < 4; i++)
4650 {
4651 /*inPtr pointing to the beginning of first space after number of ie fields*/
4652 inPtr = strpbrk( inPtr, " " );
4653 /*no ie data after the number of ie fields argument*/
4654 if (NULL == inPtr) return -EINVAL;
4655
4656 /*removing empty space*/
4657 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4658
4659 /*no ie data after the number of ie fields argument and spaces*/
4660 if ( '\0' == *inPtr ) return -EINVAL;
4661
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004662 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004663 if (1 != v) return -EINVAL;
4664
4665 v = kstrtos32(buf, 10, &tempInt);
4666 if (v < 0) return -EINVAL;
4667
4668 switch (i)
4669 {
4670 case 0: /* Measurement token */
4671 if (tempInt <= 0)
4672 {
4673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4674 "Invalid Measurement Token(%d)", tempInt);
4675 return -EINVAL;
4676 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004677 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004678 break;
4679
4680 case 1: /* Channel number */
4681 if ((tempInt <= 0) ||
4682 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4683 {
4684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4685 "Invalid Channel Number(%d)", tempInt);
4686 return -EINVAL;
4687 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004688 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004689 break;
4690
4691 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004692 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004693 {
4694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4695 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4696 return -EINVAL;
4697 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004698 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004699 break;
4700
4701 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004702 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4703 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004704 {
4705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4706 "Invalid Measurement Duration(%d)", tempInt);
4707 return -EINVAL;
4708 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004709 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004710 break;
4711 }
4712 }
4713 }
4714
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004715 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004716 {
4717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304718 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004719 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004720 pEseBcnReq->bcnReq[j].measurementToken,
4721 pEseBcnReq->bcnReq[j].channel,
4722 pEseBcnReq->bcnReq[j].scanMode,
4723 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004724 }
4725
4726 return VOS_STATUS_SUCCESS;
4727}
4728
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004729static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4730{
4731 struct statsContext *pStatsContext = NULL;
4732 hdd_adapter_t *pAdapter = NULL;
4733
4734 if (NULL == pContext)
4735 {
4736 hddLog(VOS_TRACE_LEVEL_ERROR,
4737 "%s: Bad param, pContext [%p]",
4738 __func__, pContext);
4739 return;
4740 }
4741
Jeff Johnson72a40512013-12-19 10:14:15 -08004742 /* there is a race condition that exists between this callback
4743 function and the caller since the caller could time out either
4744 before or while this code is executing. we use a spinlock to
4745 serialize these actions */
4746 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004747
4748 pStatsContext = pContext;
4749 pAdapter = pStatsContext->pAdapter;
4750 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4751 {
4752 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004753 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004754 hddLog(VOS_TRACE_LEVEL_WARN,
4755 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4756 __func__, pAdapter, pStatsContext->magic);
4757 return;
4758 }
4759
Jeff Johnson72a40512013-12-19 10:14:15 -08004760 /* context is valid so caller is still waiting */
4761
4762 /* paranoia: invalidate the magic */
4763 pStatsContext->magic = 0;
4764
4765 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004766 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4767 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4768 tsmMetrics.UplinkPktQueueDlyHist,
4769 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4770 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4771 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4772 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4773 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4774 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4775 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4776
Jeff Johnson72a40512013-12-19 10:14:15 -08004777 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004778 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004779
4780 /* serialization is complete */
4781 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004782}
4783
4784
4785
4786static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4787 tAniTrafStrmMetrics* pTsmMetrics)
4788{
4789 hdd_station_ctx_t *pHddStaCtx = NULL;
4790 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004791 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004792 long lrc;
4793 struct statsContext context;
4794 hdd_context_t *pHddCtx = NULL;
4795
4796 if (NULL == pAdapter)
4797 {
4798 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4799 return VOS_STATUS_E_FAULT;
4800 }
4801
4802 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4803 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4804
4805 /* we are connected prepare our callback context */
4806 init_completion(&context.completion);
4807 context.pAdapter = pAdapter;
4808 context.magic = STATS_CONTEXT_MAGIC;
4809
4810 /* query tsm stats */
4811 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4812 pHddStaCtx->conn_info.staId[ 0 ],
4813 pHddStaCtx->conn_info.bssId,
4814 &context, pHddCtx->pvosContext, tid);
4815
4816 if (eHAL_STATUS_SUCCESS != hstatus)
4817 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004818 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4819 __func__);
4820 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004821 }
4822 else
4823 {
4824 /* request was sent -- wait for the response */
4825 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4826 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004827 if (lrc <= 0)
4828 {
4829 hddLog(VOS_TRACE_LEVEL_ERROR,
4830 "%s: SME %s while retrieving statistics",
4831 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004832 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004833 }
4834 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004835
Jeff Johnson72a40512013-12-19 10:14:15 -08004836 /* either we never sent a request, we sent a request and received a
4837 response or we sent a request and timed out. if we never sent a
4838 request or if we sent a request and got a response, we want to
4839 clear the magic out of paranoia. if we timed out there is a
4840 race condition such that the callback function could be
4841 executing at the same time we are. of primary concern is if the
4842 callback function had already verified the "magic" but had not
4843 yet set the completion variable when a timeout occurred. we
4844 serialize these activities by invalidating the magic while
4845 holding a shared spinlock which will cause us to block if the
4846 callback is currently executing */
4847 spin_lock(&hdd_context_lock);
4848 context.magic = 0;
4849 spin_unlock(&hdd_context_lock);
4850
4851 if (VOS_STATUS_SUCCESS == vstatus)
4852 {
4853 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4854 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4855 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4856 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4857 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4858 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4859 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4860 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4861 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4862 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4863 }
4864 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004865}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004866#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004867
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004868#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004869void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4870{
4871 eCsrBand band = -1;
4872 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4873 switch (band)
4874 {
4875 case eCSR_BAND_ALL:
4876 *pBand = WLAN_HDD_UI_BAND_AUTO;
4877 break;
4878
4879 case eCSR_BAND_24:
4880 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4881 break;
4882
4883 case eCSR_BAND_5G:
4884 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4885 break;
4886
4887 default:
4888 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4889 *pBand = -1;
4890 break;
4891 }
4892}
4893
4894/**---------------------------------------------------------------------------
4895
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004896 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4897
4898 This function parses the send action frame data passed in the format
4899 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4900
Srinivas Girigowda56076852013-08-20 14:00:50 -07004901 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004902 \param - pTargetApBssid Pointer to target Ap bssid
4903 \param - pChannel Pointer to the Target AP channel
4904 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4905 \param - pBuf Pointer to data
4906 \param - pBufLen Pointer to data length
4907
4908 \return - 0 for success non-zero for failure
4909
4910 --------------------------------------------------------------------------*/
4911VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4912 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4913{
4914 tANI_U8 *inPtr = pValue;
4915 tANI_U8 *dataEnd;
4916 int tempInt;
4917 int j = 0;
4918 int i = 0;
4919 int v = 0;
4920 tANI_U8 tempBuf[32];
4921 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004922 /* 12 hexa decimal digits, 5 ':' and '\0' */
4923 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004924
4925 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4926 /*no argument after the command*/
4927 if (NULL == inPtr)
4928 {
4929 return -EINVAL;
4930 }
4931
4932 /*no space after the command*/
4933 else if (SPACE_ASCII_VALUE != *inPtr)
4934 {
4935 return -EINVAL;
4936 }
4937
4938 /*removing empty spaces*/
4939 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4940
4941 /*no argument followed by spaces*/
4942 if ('\0' == *inPtr)
4943 {
4944 return -EINVAL;
4945 }
4946
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004947 v = sscanf(inPtr, "%17s", macAddress);
4948 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004949 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4951 "Invalid MAC address or All hex inputs are not read (%d)", v);
4952 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004953 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004954
4955 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4956 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4957 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4958 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4959 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4960 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004961
4962 /* point to the next argument */
4963 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4964 /*no argument after the command*/
4965 if (NULL == inPtr) return -EINVAL;
4966
4967 /*removing empty spaces*/
4968 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4969
4970 /*no argument followed by spaces*/
4971 if ('\0' == *inPtr)
4972 {
4973 return -EINVAL;
4974 }
4975
4976 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004977 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004978 if (1 != v) return -EINVAL;
4979
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004980 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304981 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304982 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004983
4984 *pChannel = tempInt;
4985
4986 /* point to the next argument */
4987 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4988 /*no argument after the command*/
4989 if (NULL == inPtr) return -EINVAL;
4990 /*removing empty spaces*/
4991 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4992
4993 /*no argument followed by spaces*/
4994 if ('\0' == *inPtr)
4995 {
4996 return -EINVAL;
4997 }
4998
4999 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005000 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005001 if (1 != v) return -EINVAL;
5002
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005003 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08005004 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005005
5006 *pDwellTime = tempInt;
5007
5008 /* point to the next argument */
5009 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5010 /*no argument after the command*/
5011 if (NULL == inPtr) return -EINVAL;
5012 /*removing empty spaces*/
5013 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5014
5015 /*no argument followed by spaces*/
5016 if ('\0' == *inPtr)
5017 {
5018 return -EINVAL;
5019 }
5020
5021 /* find the length of data */
5022 dataEnd = inPtr;
5023 while(('\0' != *dataEnd) )
5024 {
5025 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005026 }
Kiet Lambe150c22013-11-21 16:30:32 +05305027 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005028 if ( *pBufLen <= 0) return -EINVAL;
5029
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07005030 /* Allocate the number of bytes based on the number of input characters
5031 whether it is even or odd.
5032 if the number of input characters are even, then we need N/2 byte.
5033 if the number of input characters are odd, then we need do (N+1)/2 to
5034 compensate rounding off.
5035 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5036 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5037 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005038 if (NULL == *pBuf)
5039 {
5040 hddLog(VOS_TRACE_LEVEL_FATAL,
5041 "%s: vos_mem_alloc failed ", __func__);
5042 return -EINVAL;
5043 }
5044
5045 /* the buffer received from the upper layer is character buffer,
5046 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5047 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5048 and f0 in 3rd location */
5049 for (i = 0, j = 0; j < *pBufLen; j += 2)
5050 {
Kiet Lambe150c22013-11-21 16:30:32 +05305051 if( j+1 == *pBufLen)
5052 {
5053 tempByte = hdd_parse_hex(inPtr[j]);
5054 }
5055 else
5056 {
5057 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5058 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005059 (*pBuf)[i++] = tempByte;
5060 }
5061 *pBufLen = i;
5062 return VOS_STATUS_SUCCESS;
5063}
5064
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005065/**---------------------------------------------------------------------------
5066
Srinivas Girigowdade697412013-02-14 16:31:48 -08005067 \brief hdd_parse_channellist() - HDD Parse channel list
5068
5069 This function parses the channel list passed in the format
5070 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005071 if the Number of channels (N) does not match with the actual number of channels passed
5072 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5073 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5074 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5075 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005076
5077 \param - pValue Pointer to input channel list
5078 \param - ChannelList Pointer to local output array to record channel list
5079 \param - pNumChannels Pointer to number of roam scan channels
5080
5081 \return - 0 for success non-zero for failure
5082
5083 --------------------------------------------------------------------------*/
5084VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5085{
5086 tANI_U8 *inPtr = pValue;
5087 int tempInt;
5088 int j = 0;
5089 int v = 0;
5090 char buf[32];
5091
5092 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5093 /*no argument after the command*/
5094 if (NULL == inPtr)
5095 {
5096 return -EINVAL;
5097 }
5098
5099 /*no space after the command*/
5100 else if (SPACE_ASCII_VALUE != *inPtr)
5101 {
5102 return -EINVAL;
5103 }
5104
5105 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005106 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005107
5108 /*no argument followed by spaces*/
5109 if ('\0' == *inPtr)
5110 {
5111 return -EINVAL;
5112 }
5113
5114 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005115 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005116 if (1 != v) return -EINVAL;
5117
Srinivas Girigowdade697412013-02-14 16:31:48 -08005118 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005119 if ((v < 0) ||
5120 (tempInt <= 0) ||
5121 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5122 {
5123 return -EINVAL;
5124 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005125
5126 *pNumChannels = tempInt;
5127
5128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5129 "Number of channels are: %d", *pNumChannels);
5130
5131 for (j = 0; j < (*pNumChannels); j++)
5132 {
5133 /*inPtr pointing to the beginning of first space after number of channels*/
5134 inPtr = strpbrk( inPtr, " " );
5135 /*no channel list after the number of channels argument*/
5136 if (NULL == inPtr)
5137 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005138 if (0 != j)
5139 {
5140 *pNumChannels = j;
5141 return VOS_STATUS_SUCCESS;
5142 }
5143 else
5144 {
5145 return -EINVAL;
5146 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005147 }
5148
5149 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005150 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005151
5152 /*no channel list after the number of channels argument and spaces*/
5153 if ( '\0' == *inPtr )
5154 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005155 if (0 != j)
5156 {
5157 *pNumChannels = j;
5158 return VOS_STATUS_SUCCESS;
5159 }
5160 else
5161 {
5162 return -EINVAL;
5163 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005164 }
5165
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005166 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005167 if (1 != v) return -EINVAL;
5168
Srinivas Girigowdade697412013-02-14 16:31:48 -08005169 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005170 if ((v < 0) ||
5171 (tempInt <= 0) ||
5172 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5173 {
5174 return -EINVAL;
5175 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005176 pChannelList[j] = tempInt;
5177
5178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5179 "Channel %d added to preferred channel list",
5180 pChannelList[j] );
5181 }
5182
Srinivas Girigowdade697412013-02-14 16:31:48 -08005183 return VOS_STATUS_SUCCESS;
5184}
5185
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005186
5187/**---------------------------------------------------------------------------
5188
5189 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5190
5191 This function parses the reasoc command data passed in the format
5192 REASSOC<space><bssid><space><channel>
5193
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005194 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005195 \param - pTargetApBssid Pointer to target Ap bssid
5196 \param - pChannel Pointer to the Target AP channel
5197
5198 \return - 0 for success non-zero for failure
5199
5200 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005201VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5202 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005203{
5204 tANI_U8 *inPtr = pValue;
5205 int tempInt;
5206 int v = 0;
5207 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005208 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005209 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005210
5211 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5212 /*no argument after the command*/
5213 if (NULL == inPtr)
5214 {
5215 return -EINVAL;
5216 }
5217
5218 /*no space after the command*/
5219 else if (SPACE_ASCII_VALUE != *inPtr)
5220 {
5221 return -EINVAL;
5222 }
5223
5224 /*removing empty spaces*/
5225 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5226
5227 /*no argument followed by spaces*/
5228 if ('\0' == *inPtr)
5229 {
5230 return -EINVAL;
5231 }
5232
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005233 v = sscanf(inPtr, "%17s", macAddress);
5234 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005235 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5237 "Invalid MAC address or All hex inputs are not read (%d)", v);
5238 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005239 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005240
5241 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5242 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5243 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5244 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5245 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5246 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005247
5248 /* point to the next argument */
5249 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5250 /*no argument after the command*/
5251 if (NULL == inPtr) return -EINVAL;
5252
5253 /*removing empty spaces*/
5254 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5255
5256 /*no argument followed by spaces*/
5257 if ('\0' == *inPtr)
5258 {
5259 return -EINVAL;
5260 }
5261
5262 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005263 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005264 if (1 != v) return -EINVAL;
5265
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005266 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005267 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305268 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005269 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5270 {
5271 return -EINVAL;
5272 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005273
5274 *pChannel = tempInt;
5275 return VOS_STATUS_SUCCESS;
5276}
5277
5278#endif
5279
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005280#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005281/**---------------------------------------------------------------------------
5282
5283 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5284
5285 This function parses the SETCCKM IE command
5286 SETCCKMIE<space><ie data>
5287
5288 \param - pValue Pointer to input data
5289 \param - pCckmIe Pointer to output cckm Ie
5290 \param - pCckmIeLen Pointer to output cckm ie length
5291
5292 \return - 0 for success non-zero for failure
5293
5294 --------------------------------------------------------------------------*/
5295VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5296 tANI_U8 *pCckmIeLen)
5297{
5298 tANI_U8 *inPtr = pValue;
5299 tANI_U8 *dataEnd;
5300 int j = 0;
5301 int i = 0;
5302 tANI_U8 tempByte = 0;
5303
5304 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5305 /*no argument after the command*/
5306 if (NULL == inPtr)
5307 {
5308 return -EINVAL;
5309 }
5310
5311 /*no space after the command*/
5312 else if (SPACE_ASCII_VALUE != *inPtr)
5313 {
5314 return -EINVAL;
5315 }
5316
5317 /*removing empty spaces*/
5318 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5319
5320 /*no argument followed by spaces*/
5321 if ('\0' == *inPtr)
5322 {
5323 return -EINVAL;
5324 }
5325
5326 /* find the length of data */
5327 dataEnd = inPtr;
5328 while(('\0' != *dataEnd) )
5329 {
5330 dataEnd++;
5331 ++(*pCckmIeLen);
5332 }
5333 if ( *pCckmIeLen <= 0) return -EINVAL;
5334
5335 /* Allocate the number of bytes based on the number of input characters
5336 whether it is even or odd.
5337 if the number of input characters are even, then we need N/2 byte.
5338 if the number of input characters are odd, then we need do (N+1)/2 to
5339 compensate rounding off.
5340 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5341 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5342 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5343 if (NULL == *pCckmIe)
5344 {
5345 hddLog(VOS_TRACE_LEVEL_FATAL,
5346 "%s: vos_mem_alloc failed ", __func__);
5347 return -EINVAL;
5348 }
5349 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5350 /* the buffer received from the upper layer is character buffer,
5351 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5352 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5353 and f0 in 3rd location */
5354 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5355 {
5356 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5357 (*pCckmIe)[i++] = tempByte;
5358 }
5359 *pCckmIeLen = i;
5360
5361 return VOS_STATUS_SUCCESS;
5362}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005363#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005364
Jeff Johnson295189b2012-06-20 16:38:30 -07005365/**---------------------------------------------------------------------------
5366
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005367 \brief hdd_is_valid_mac_address() - Validate MAC address
5368
5369 This function validates whether the given MAC address is valid or not
5370 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5371 where X is the hexa decimal digit character and separated by ':'
5372 This algorithm works even if MAC address is not separated by ':'
5373
5374 This code checks given input string mac contains exactly 12 hexadecimal digits.
5375 and a separator colon : appears in the input string only after
5376 an even number of hex digits.
5377
5378 \param - pMacAddr pointer to the input MAC address
5379 \return - 1 for valid and 0 for invalid
5380
5381 --------------------------------------------------------------------------*/
5382
5383v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5384{
5385 int xdigit = 0;
5386 int separator = 0;
5387 while (*pMacAddr)
5388 {
5389 if (isxdigit(*pMacAddr))
5390 {
5391 xdigit++;
5392 }
5393 else if (':' == *pMacAddr)
5394 {
5395 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5396 break;
5397
5398 ++separator;
5399 }
5400 else
5401 {
5402 separator = -1;
5403 /* Invalid MAC found */
5404 return 0;
5405 }
5406 ++pMacAddr;
5407 }
5408 return (xdigit == 12 && (separator == 5 || separator == 0));
5409}
5410
5411/**---------------------------------------------------------------------------
5412
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305413 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005414
5415 \param - dev Pointer to net_device structure
5416
5417 \return - 0 for success non-zero for failure
5418
5419 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305420int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005421{
5422 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5423 hdd_context_t *pHddCtx;
5424 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5425 VOS_STATUS status;
5426 v_BOOL_t in_standby = TRUE;
5427
5428 if (NULL == pAdapter)
5429 {
5430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305431 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 return -ENODEV;
5433 }
5434
5435 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305436 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5437 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 if (NULL == pHddCtx)
5439 {
5440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005441 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 return -ENODEV;
5443 }
5444
5445 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5446 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5447 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005448 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5449 {
5450 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305451 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005452 in_standby = FALSE;
5453 break;
5454 }
5455 else
5456 {
5457 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5458 pAdapterNode = pNext;
5459 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005460 }
5461
5462 if (TRUE == in_standby)
5463 {
5464 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5465 {
5466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5467 "wlan out of power save", __func__);
5468 return -EINVAL;
5469 }
5470 }
5471
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005472 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5474 {
5475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005476 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305478 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 netif_tx_start_all_queues(dev);
5480 }
5481
5482 return 0;
5483}
5484
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305485/**---------------------------------------------------------------------------
5486
5487 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5488
5489 This is called in response to ifconfig up
5490
5491 \param - dev Pointer to net_device structure
5492
5493 \return - 0 for success non-zero for failure
5494
5495 --------------------------------------------------------------------------*/
5496int hdd_open(struct net_device *dev)
5497{
5498 int ret;
5499
5500 vos_ssr_protect(__func__);
5501 ret = __hdd_open(dev);
5502 vos_ssr_unprotect(__func__);
5503
5504 return ret;
5505}
5506
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305507int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005508{
5509 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5510
5511 if(pAdapter == NULL) {
5512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005513 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005514 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005515 }
5516
Jeff Johnson295189b2012-06-20 16:38:30 -07005517 return 0;
5518}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305519
5520int hdd_mon_open (struct net_device *dev)
5521{
5522 int ret;
5523
5524 vos_ssr_protect(__func__);
5525 ret = __hdd_mon_open(dev);
5526 vos_ssr_unprotect(__func__);
5527
5528 return ret;
5529}
5530
Katya Nigame7b69a82015-04-28 15:24:06 +05305531int hdd_mon_stop(struct net_device *dev)
5532{
5533 return 0;
5534}
5535
Jeff Johnson295189b2012-06-20 16:38:30 -07005536/**---------------------------------------------------------------------------
5537
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305538 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005539
5540 \param - dev Pointer to net_device structure
5541
5542 \return - 0 for success non-zero for failure
5543
5544 --------------------------------------------------------------------------*/
5545
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305546int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005547{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305548 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005549 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5550 hdd_context_t *pHddCtx;
5551 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5552 VOS_STATUS status;
5553 v_BOOL_t enter_standby = TRUE;
5554
5555 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 if (NULL == pAdapter)
5557 {
5558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305559 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 return -ENODEV;
5561 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305562 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305563 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305564
5565 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5566 ret = wlan_hdd_validate_context(pHddCtx);
5567 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005568 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305569 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 }
5571
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305572 /* Nothing to be done if the interface is not opened */
5573 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5574 {
5575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5576 "%s: NETDEV Interface is not OPENED", __func__);
5577 return -ENODEV;
5578 }
5579
5580 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005581 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005582 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305583
5584 /* Disable TX on the interface, after this hard_start_xmit() will not
5585 * be called on that interface
5586 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305587 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305589
5590 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005591 netif_carrier_off(pAdapter->dev);
5592
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305593 /* The interface is marked as down for outside world (aka kernel)
5594 * But the driver is pretty much alive inside. The driver needs to
5595 * tear down the existing connection on the netdev (session)
5596 * cleanup the data pipes and wait until the control plane is stabilized
5597 * for this interface. The call also needs to wait until the above
5598 * mentioned actions are completed before returning to the caller.
5599 * Notice that the hdd_stop_adapter is requested not to close the session
5600 * That is intentional to be able to scan if it is a STA/P2P interface
5601 */
5602 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305603#ifdef FEATURE_WLAN_TDLS
5604 mutex_lock(&pHddCtx->tdls_lock);
5605#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305606 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305607 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305608#ifdef FEATURE_WLAN_TDLS
5609 mutex_unlock(&pHddCtx->tdls_lock);
5610#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 /* SoftAP ifaces should never go in power save mode
5612 making sure same here. */
5613 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5614 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005616 )
5617 {
5618 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5620 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 EXIT();
5622 return 0;
5623 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305624 /* Find if any iface is up. If any iface is up then can't put device to
5625 * sleep/power save mode
5626 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005627 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5628 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5629 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005630 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5631 {
5632 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305633 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005634 enter_standby = FALSE;
5635 break;
5636 }
5637 else
5638 {
5639 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5640 pAdapterNode = pNext;
5641 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005642 }
5643
5644 if (TRUE == enter_standby)
5645 {
5646 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5647 "entering standby", __func__);
5648 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5649 {
5650 /*log and return success*/
5651 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5652 "wlan in power save", __func__);
5653 }
5654 }
5655
5656 EXIT();
5657 return 0;
5658}
5659
5660/**---------------------------------------------------------------------------
5661
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305662 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005663
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305664 This is called in response to ifconfig down
5665
5666 \param - dev Pointer to net_device structure
5667
5668 \return - 0 for success non-zero for failure
5669-----------------------------------------------------------------------------*/
5670int hdd_stop (struct net_device *dev)
5671{
5672 int ret;
5673
5674 vos_ssr_protect(__func__);
5675 ret = __hdd_stop(dev);
5676 vos_ssr_unprotect(__func__);
5677
5678 return ret;
5679}
5680
5681/**---------------------------------------------------------------------------
5682
5683 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005684
5685 \param - dev Pointer to net_device structure
5686
5687 \return - void
5688
5689 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305690static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005691{
5692 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305693 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005694 ENTER();
5695
5696 do
5697 {
5698 if (NULL == pAdapter)
5699 {
5700 hddLog(VOS_TRACE_LEVEL_FATAL,
5701 "%s: NULL pAdapter", __func__);
5702 break;
5703 }
5704
5705 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5706 {
5707 hddLog(VOS_TRACE_LEVEL_FATAL,
5708 "%s: Invalid magic", __func__);
5709 break;
5710 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305711 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5712 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005713 {
5714 hddLog(VOS_TRACE_LEVEL_FATAL,
5715 "%s: NULL pHddCtx", __func__);
5716 break;
5717 }
5718
5719 if (dev != pAdapter->dev)
5720 {
5721 hddLog(VOS_TRACE_LEVEL_FATAL,
5722 "%s: Invalid device reference", __func__);
5723 /* we haven't validated all cases so let this go for now */
5724 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305725#ifdef FEATURE_WLAN_TDLS
5726 mutex_lock(&pHddCtx->tdls_lock);
5727#endif
c_hpothu002231a2015-02-05 14:58:51 +05305728 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305729#ifdef FEATURE_WLAN_TDLS
5730 mutex_unlock(&pHddCtx->tdls_lock);
5731#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005732
5733 /* after uninit our adapter structure will no longer be valid */
5734 pAdapter->dev = NULL;
5735 pAdapter->magic = 0;
5736 } while (0);
5737
5738 EXIT();
5739}
5740
5741/**---------------------------------------------------------------------------
5742
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305743 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5744
5745 This is called during the netdev unregister to uninitialize all data
5746associated with the device
5747
5748 \param - dev Pointer to net_device structure
5749
5750 \return - void
5751
5752 --------------------------------------------------------------------------*/
5753static void hdd_uninit (struct net_device *dev)
5754{
5755 vos_ssr_protect(__func__);
5756 __hdd_uninit(dev);
5757 vos_ssr_unprotect(__func__);
5758}
5759
5760/**---------------------------------------------------------------------------
5761
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 \brief hdd_release_firmware() -
5763
5764 This function calls the release firmware API to free the firmware buffer.
5765
5766 \param - pFileName Pointer to the File Name.
5767 pCtx - Pointer to the adapter .
5768
5769
5770 \return - 0 for success, non zero for failure
5771
5772 --------------------------------------------------------------------------*/
5773
5774VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5775{
5776 VOS_STATUS status = VOS_STATUS_SUCCESS;
5777 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5778 ENTER();
5779
5780
5781 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5782
5783 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5784
5785 if(pHddCtx->fw) {
5786 release_firmware(pHddCtx->fw);
5787 pHddCtx->fw = NULL;
5788 }
5789 else
5790 status = VOS_STATUS_E_FAILURE;
5791 }
5792 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5793 if(pHddCtx->nv) {
5794 release_firmware(pHddCtx->nv);
5795 pHddCtx->nv = NULL;
5796 }
5797 else
5798 status = VOS_STATUS_E_FAILURE;
5799
5800 }
5801
5802 EXIT();
5803 return status;
5804}
5805
5806/**---------------------------------------------------------------------------
5807
5808 \brief hdd_request_firmware() -
5809
5810 This function reads the firmware file using the request firmware
5811 API and returns the the firmware data and the firmware file size.
5812
5813 \param - pfileName - Pointer to the file name.
5814 - pCtx - Pointer to the adapter .
5815 - ppfw_data - Pointer to the pointer of the firmware data.
5816 - pSize - Pointer to the file size.
5817
5818 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5819
5820 --------------------------------------------------------------------------*/
5821
5822
5823VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5824{
5825 int status;
5826 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5827 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5828 ENTER();
5829
5830 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5831
5832 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5833
5834 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5835 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5836 __func__, pfileName);
5837 retval = VOS_STATUS_E_FAILURE;
5838 }
5839
5840 else {
5841 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5842 *pSize = pHddCtx->fw->size;
5843 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5844 __func__, *pSize);
5845 }
5846 }
5847 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5848
5849 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5850
5851 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5852 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5853 __func__, pfileName);
5854 retval = VOS_STATUS_E_FAILURE;
5855 }
5856
5857 else {
5858 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5859 *pSize = pHddCtx->nv->size;
5860 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5861 __func__, *pSize);
5862 }
5863 }
5864
5865 EXIT();
5866 return retval;
5867}
5868/**---------------------------------------------------------------------------
5869 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5870
5871 This is the function invoked by SME to inform the result of a full power
5872 request issued by HDD
5873
5874 \param - callbackcontext - Pointer to cookie
5875 status - result of request
5876
5877 \return - None
5878
5879--------------------------------------------------------------------------*/
5880void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5881{
5882 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5883
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005884 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005885 if(&pHddCtx->full_pwr_comp_var)
5886 {
5887 complete(&pHddCtx->full_pwr_comp_var);
5888 }
5889}
5890
5891/**---------------------------------------------------------------------------
5892
5893 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5894
5895 This is the function invoked by SME to inform the result of BMPS
5896 request issued by HDD
5897
5898 \param - callbackcontext - Pointer to cookie
5899 status - result of request
5900
5901 \return - None
5902
5903--------------------------------------------------------------------------*/
5904void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5905{
5906
5907 struct completion *completion_var = (struct completion*) callbackContext;
5908
Arif Hussain6d2a3322013-11-17 19:50:10 -08005909 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 if(completion_var != NULL)
5911 {
5912 complete(completion_var);
5913 }
5914}
5915
5916/**---------------------------------------------------------------------------
5917
5918 \brief hdd_get_cfg_file_size() -
5919
5920 This function reads the configuration file using the request firmware
5921 API and returns the configuration file size.
5922
5923 \param - pCtx - Pointer to the adapter .
5924 - pFileName - Pointer to the file name.
5925 - pBufSize - Pointer to the buffer size.
5926
5927 \return - 0 for success, non zero for failure
5928
5929 --------------------------------------------------------------------------*/
5930
5931VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5932{
5933 int status;
5934 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5935
5936 ENTER();
5937
5938 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5939
5940 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5941 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5942 status = VOS_STATUS_E_FAILURE;
5943 }
5944 else {
5945 *pBufSize = pHddCtx->fw->size;
5946 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5947 release_firmware(pHddCtx->fw);
5948 pHddCtx->fw = NULL;
5949 }
5950
5951 EXIT();
5952 return VOS_STATUS_SUCCESS;
5953}
5954
5955/**---------------------------------------------------------------------------
5956
5957 \brief hdd_read_cfg_file() -
5958
5959 This function reads the configuration file using the request firmware
5960 API and returns the cfg data and the buffer size of the configuration file.
5961
5962 \param - pCtx - Pointer to the adapter .
5963 - pFileName - Pointer to the file name.
5964 - pBuffer - Pointer to the data buffer.
5965 - pBufSize - Pointer to the buffer size.
5966
5967 \return - 0 for success, non zero for failure
5968
5969 --------------------------------------------------------------------------*/
5970
5971VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5972 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5973{
5974 int status;
5975 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5976
5977 ENTER();
5978
5979 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5980
5981 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5982 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5983 return VOS_STATUS_E_FAILURE;
5984 }
5985 else {
5986 if(*pBufSize != pHddCtx->fw->size) {
5987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5988 "file size", __func__);
5989 release_firmware(pHddCtx->fw);
5990 pHddCtx->fw = NULL;
5991 return VOS_STATUS_E_FAILURE;
5992 }
5993 else {
5994 if(pBuffer) {
5995 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5996 }
5997 release_firmware(pHddCtx->fw);
5998 pHddCtx->fw = NULL;
5999 }
6000 }
6001
6002 EXIT();
6003
6004 return VOS_STATUS_SUCCESS;
6005}
6006
6007/**---------------------------------------------------------------------------
6008
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306009 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07006010
6011 This function sets the user specified mac address using
6012 the command ifconfig wlanX hw ether <mac adress>.
6013
6014 \param - dev - Pointer to the net device.
6015 - addr - Pointer to the sockaddr.
6016 \return - 0 for success, non zero for failure
6017
6018 --------------------------------------------------------------------------*/
6019
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306020static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07006021{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306022 hdd_adapter_t *pAdapter;
6023 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 struct sockaddr *psta_mac_addr = addr;
6025 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306026 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006027
6028 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306029 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6030 if (NULL == pAdapter)
6031 {
6032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6033 "%s: Adapter is NULL",__func__);
6034 return -EINVAL;
6035 }
6036 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6037 ret = wlan_hdd_validate_context(pHddCtx);
6038 if (0 != ret)
6039 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05306040 return ret;
6041 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006042
6043 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
6045
6046 EXIT();
6047 return halStatus;
6048}
6049
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306050/**---------------------------------------------------------------------------
6051
6052 \brief hdd_set_mac_address() -
6053
6054 Wrapper function to protect __hdd_set_mac_address() function from ssr
6055
6056 \param - dev - Pointer to the net device.
6057 - addr - Pointer to the sockaddr.
6058 \return - 0 for success, non zero for failure
6059
6060 --------------------------------------------------------------------------*/
6061static int hdd_set_mac_address(struct net_device *dev, void *addr)
6062{
6063 int ret;
6064
6065 vos_ssr_protect(__func__);
6066 ret = __hdd_set_mac_address(dev, addr);
6067 vos_ssr_unprotect(__func__);
6068
6069 return ret;
6070}
6071
Jeff Johnson295189b2012-06-20 16:38:30 -07006072tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6073{
6074 int i;
6075 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6076 {
Abhishek Singheb183782014-02-06 13:37:21 +05306077 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 break;
6079 }
6080
6081 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6082 return NULL;
6083
6084 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6085 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6086}
6087
6088void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6089{
6090 int i;
6091 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6092 {
6093 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6094 {
6095 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6096 break;
6097 }
6098 }
6099 return;
6100}
6101
6102#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6103 static struct net_device_ops wlan_drv_ops = {
6104 .ndo_open = hdd_open,
6105 .ndo_stop = hdd_stop,
6106 .ndo_uninit = hdd_uninit,
6107 .ndo_start_xmit = hdd_hard_start_xmit,
6108 .ndo_tx_timeout = hdd_tx_timeout,
6109 .ndo_get_stats = hdd_stats,
6110 .ndo_do_ioctl = hdd_ioctl,
6111 .ndo_set_mac_address = hdd_set_mac_address,
6112 .ndo_select_queue = hdd_select_queue,
6113#ifdef WLAN_FEATURE_PACKET_FILTERING
6114#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6115 .ndo_set_rx_mode = hdd_set_multicast_list,
6116#else
6117 .ndo_set_multicast_list = hdd_set_multicast_list,
6118#endif //LINUX_VERSION_CODE
6119#endif
6120 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006121 static struct net_device_ops wlan_mon_drv_ops = {
6122 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05306123 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 .ndo_uninit = hdd_uninit,
6125 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6126 .ndo_tx_timeout = hdd_tx_timeout,
6127 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05306128 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07006129 .ndo_set_mac_address = hdd_set_mac_address,
6130 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306131
Jeff Johnson295189b2012-06-20 16:38:30 -07006132#endif
6133
6134void hdd_set_station_ops( struct net_device *pWlanDev )
6135{
6136#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006137 pWlanDev->netdev_ops = &wlan_drv_ops;
6138#else
6139 pWlanDev->open = hdd_open;
6140 pWlanDev->stop = hdd_stop;
6141 pWlanDev->uninit = hdd_uninit;
6142 pWlanDev->hard_start_xmit = NULL;
6143 pWlanDev->tx_timeout = hdd_tx_timeout;
6144 pWlanDev->get_stats = hdd_stats;
6145 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006146 pWlanDev->set_mac_address = hdd_set_mac_address;
6147#endif
6148}
6149
Katya Nigam1fd24402015-02-16 14:52:19 +05306150void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6151{
6152 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6153 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6154 #else
6155 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6156 #endif
6157}
6158
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006159static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006160{
6161 struct net_device *pWlanDev = NULL;
6162 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006163 /*
6164 * cfg80211 initialization and registration....
6165 */
6166 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6167
Jeff Johnson295189b2012-06-20 16:38:30 -07006168 if(pWlanDev != NULL)
6169 {
6170
6171 //Save the pointer to the net_device in the HDD adapter
6172 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6173
Jeff Johnson295189b2012-06-20 16:38:30 -07006174 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6175
6176 pAdapter->dev = pWlanDev;
6177 pAdapter->pHddCtx = pHddCtx;
6178 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306179 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006180
6181 init_completion(&pAdapter->session_open_comp_var);
6182 init_completion(&pAdapter->session_close_comp_var);
6183 init_completion(&pAdapter->disconnect_comp_var);
6184 init_completion(&pAdapter->linkup_event_var);
6185 init_completion(&pAdapter->cancel_rem_on_chan_var);
6186 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306187 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006188#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6189 init_completion(&pAdapter->offchannel_tx_event);
6190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006191 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006192#ifdef FEATURE_WLAN_TDLS
6193 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006194 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006195 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306196 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006197#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 init_completion(&pHddCtx->mc_sus_event_var);
6199 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306200 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006201 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006202 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006203
Rajeev79dbe4c2013-10-05 11:03:42 +05306204#ifdef FEATURE_WLAN_BATCH_SCAN
6205 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6206 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6207 pAdapter->pBatchScanRsp = NULL;
6208 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006209 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006210 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306211 mutex_init(&pAdapter->hdd_batch_scan_lock);
6212#endif
6213
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 pAdapter->isLinkUpSvcNeeded = FALSE;
6215 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6216 //Init the net_device structure
6217 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6218
6219 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6220 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6221 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6222 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6223
6224 hdd_set_station_ops( pAdapter->dev );
6225
6226 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6228 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6229 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006230 /* set pWlanDev's parent to underlying device */
6231 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006232
6233 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 }
6235
6236 return pAdapter;
6237}
6238
6239VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6240{
6241 struct net_device *pWlanDev = pAdapter->dev;
6242 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6243 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6244 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6245
6246 if( rtnl_lock_held )
6247 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006248 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006249 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6250 {
6251 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6252 return VOS_STATUS_E_FAILURE;
6253 }
6254 }
6255 if (register_netdevice(pWlanDev))
6256 {
6257 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6258 return VOS_STATUS_E_FAILURE;
6259 }
6260 }
6261 else
6262 {
6263 if(register_netdev(pWlanDev))
6264 {
6265 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6266 return VOS_STATUS_E_FAILURE;
6267 }
6268 }
6269 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6270
6271 return VOS_STATUS_SUCCESS;
6272}
6273
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006274static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006275{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006276 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006277
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006278 if (NULL == pAdapter)
6279 {
6280 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6281 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006282 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006283
6284 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6285 {
6286 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6287 return eHAL_STATUS_NOT_INITIALIZED;
6288 }
6289
6290 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6291
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006292#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006293 /* need to make sure all of our scheduled work has completed.
6294 * This callback is called from MC thread context, so it is safe to
6295 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006296 *
6297 * Even though this is called from MC thread context, if there is a faulty
6298 * work item in the system, that can hang this call forever. So flushing
6299 * this global work queue is not safe; and now we make sure that
6300 * individual work queues are stopped correctly. But the cancel work queue
6301 * is a GPL only API, so the proprietary version of the driver would still
6302 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006303 */
6304 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006305#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006306
6307 /* We can be blocked while waiting for scheduled work to be
6308 * flushed, and the adapter structure can potentially be freed, in
6309 * which case the magic will have been reset. So make sure the
6310 * magic is still good, and hence the adapter structure is still
6311 * valid, before signaling completion */
6312 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6313 {
6314 complete(&pAdapter->session_close_comp_var);
6315 }
6316
Jeff Johnson295189b2012-06-20 16:38:30 -07006317 return eHAL_STATUS_SUCCESS;
6318}
6319
6320VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6321{
6322 struct net_device *pWlanDev = pAdapter->dev;
6323 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6324 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6325 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6326 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306327 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006328
Nirav Shah7e3c8132015-06-22 23:51:42 +05306329 spin_lock_init( &pAdapter->sta_hash_lock);
6330 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
6331
Jeff Johnson295189b2012-06-20 16:38:30 -07006332 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006333 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 //Open a SME session for future operation
6335 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006336 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6338 {
6339 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006340 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006341 halStatus, halStatus );
6342 status = VOS_STATUS_E_FAILURE;
6343 goto error_sme_open;
6344 }
6345
6346 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306347 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 &pAdapter->session_open_comp_var,
6349 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306350 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 {
6352 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306353 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 status = VOS_STATUS_E_FAILURE;
6355 goto error_sme_open;
6356 }
6357
6358 // Register wireless extensions
6359 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6360 {
6361 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006362 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 halStatus, halStatus );
6364 status = VOS_STATUS_E_FAILURE;
6365 goto error_register_wext;
6366 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306367
Jeff Johnson295189b2012-06-20 16:38:30 -07006368 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306369 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6370 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6371 #else
6372 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6373 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006374
6375 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306376 hddLog(VOS_TRACE_LEVEL_INFO,
6377 "%s: Set HDD connState to eConnectionState_NotConnected",
6378 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6380
6381 //Set the default operation channel
6382 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6383
6384 /* Make the default Auth Type as OPEN*/
6385 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6386
6387 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6388 {
6389 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006390 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 status, status );
6392 goto error_init_txrx;
6393 }
6394
6395 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6396
6397 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6398 {
6399 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006400 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006401 status, status );
6402 goto error_wmm_init;
6403 }
6404
6405 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6406
6407 return VOS_STATUS_SUCCESS;
6408
6409error_wmm_init:
6410 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6411 hdd_deinit_tx_rx(pAdapter);
6412error_init_txrx:
6413 hdd_UnregisterWext(pWlanDev);
6414error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006415 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 {
6417 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006418 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
mukul sharmabab477d2015-06-11 17:14:55 +05306419 pAdapter->sessionId, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006420 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306422 unsigned long rc;
6423
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306425 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006427 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306428 if (rc <= 0)
6429 hddLog(VOS_TRACE_LEVEL_ERROR,
6430 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 }
6432}
6433error_sme_open:
6434 return status;
6435}
6436
Jeff Johnson295189b2012-06-20 16:38:30 -07006437void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6438{
6439 hdd_cfg80211_state_t *cfgState;
6440
6441 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6442
6443 if( NULL != cfgState->buf )
6444 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306445 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006446 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6447 rc = wait_for_completion_interruptible_timeout(
6448 &pAdapter->tx_action_cnf_event,
6449 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306450 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306453 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6454 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 }
6456 }
6457 return;
6458}
Jeff Johnson295189b2012-06-20 16:38:30 -07006459
c_hpothu002231a2015-02-05 14:58:51 +05306460void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006461{
6462 ENTER();
6463 switch ( pAdapter->device_mode )
6464 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306465 case WLAN_HDD_IBSS:
6466 {
6467 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6468 {
6469 hdd_ibss_deinit_tx_rx( pAdapter );
6470 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6471 }
6472 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006473 case WLAN_HDD_INFRA_STATION:
6474 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006475 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 {
6477 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6478 {
6479 hdd_deinit_tx_rx( pAdapter );
6480 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6481 }
6482
6483 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6484 {
6485 hdd_wmm_adapter_close( pAdapter );
6486 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6487 }
6488
Jeff Johnson295189b2012-06-20 16:38:30 -07006489 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 break;
6491 }
6492
6493 case WLAN_HDD_SOFTAP:
6494 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006495 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306496
6497 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6498 {
6499 hdd_wmm_adapter_close( pAdapter );
6500 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6501 }
6502
Jeff Johnson295189b2012-06-20 16:38:30 -07006503 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006504
c_hpothu002231a2015-02-05 14:58:51 +05306505 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006507 break;
6508 }
6509
6510 case WLAN_HDD_MONITOR:
6511 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6513 {
6514 hdd_deinit_tx_rx( pAdapter );
6515 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6516 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 break;
6518 }
6519
6520
6521 default:
6522 break;
6523 }
6524
6525 EXIT();
6526}
6527
6528void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6529{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006530 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306531
6532 ENTER();
6533 if (NULL == pAdapter)
6534 {
6535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6536 "%s: HDD adapter is Null", __func__);
6537 return;
6538 }
6539
6540 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006541
Rajeev79dbe4c2013-10-05 11:03:42 +05306542#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306543 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6544 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006545 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306546 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6547 )
6548 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006549 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306550 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006551 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6552 {
6553 hdd_deinit_batch_scan(pAdapter);
6554 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306555 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006556 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306557#endif
6558
Jeff Johnson295189b2012-06-20 16:38:30 -07006559 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6560 if( rtnl_held )
6561 {
6562 unregister_netdevice(pWlanDev);
6563 }
6564 else
6565 {
6566 unregister_netdev(pWlanDev);
6567 }
6568 // note that the pAdapter is no longer valid at this point
6569 // since the memory has been reclaimed
6570 }
6571
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306572 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006573}
6574
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006575void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6576{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306577 VOS_STATUS status;
6578 hdd_adapter_t *pAdapter = NULL;
6579 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006580
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306581 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006582
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306583 /*loop through all adapters.*/
6584 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006585 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306586 pAdapter = pAdapterNode->pAdapter;
6587 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6588 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006589
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306590 { // we skip this registration for modes other than STA and P2P client modes.
6591 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6592 pAdapterNode = pNext;
6593 continue;
6594 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006595
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306596 //Apply Dynamic DTIM For P2P
6597 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6598 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6599 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6600 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6601 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6602 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6603 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6604 (eConnectionState_Associated ==
6605 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6606 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6607 {
6608 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006609
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306610 powerRequest.uIgnoreDTIM = 1;
6611 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6612
6613 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6614 {
6615 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6616 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6617 }
6618 else
6619 {
6620 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6621 }
6622
6623 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6624 * specified during Enter/Exit BMPS when LCD off*/
6625 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6626 NULL, eANI_BOOLEAN_FALSE);
6627 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6628 NULL, eANI_BOOLEAN_FALSE);
6629
6630 /* switch to the DTIM specified in cfg.ini */
6631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6632 "Switch to DTIM %d", powerRequest.uListenInterval);
6633 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6634 break;
6635
6636 }
6637
6638 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6639 pAdapterNode = pNext;
6640 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006641}
6642
6643void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6644{
6645 /*Switch back to DTIM 1*/
6646 tSirSetPowerParamsReq powerRequest = { 0 };
6647
6648 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6649 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006650 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006651
6652 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6653 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6654 NULL, eANI_BOOLEAN_FALSE);
6655 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6656 NULL, eANI_BOOLEAN_FALSE);
6657
6658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6659 "Switch to DTIM%d",powerRequest.uListenInterval);
6660 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6661
6662}
6663
Jeff Johnson295189b2012-06-20 16:38:30 -07006664VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6665{
6666 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306667 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6668 {
6669 hddLog( LOGE, FL("Wlan Unload in progress"));
6670 return VOS_STATUS_E_PERM;
6671 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006672 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6673 {
6674 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6675 }
6676
6677 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6678 {
6679 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6680 }
6681
6682 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6683 {
6684 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6685 }
6686
6687 return status;
6688}
6689
6690VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6691{
6692 hdd_adapter_t *pAdapter = NULL;
6693 eHalStatus halStatus;
6694 VOS_STATUS status = VOS_STATUS_E_INVAL;
6695 v_BOOL_t disableBmps = FALSE;
6696 v_BOOL_t disableImps = FALSE;
6697
6698 switch(session_type)
6699 {
6700 case WLAN_HDD_INFRA_STATION:
6701 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 case WLAN_HDD_P2P_CLIENT:
6703 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006704 //Exit BMPS -> Is Sta/P2P Client is already connected
6705 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6706 if((NULL != pAdapter)&&
6707 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6708 {
6709 disableBmps = TRUE;
6710 }
6711
6712 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6713 if((NULL != pAdapter)&&
6714 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6715 {
6716 disableBmps = TRUE;
6717 }
6718
6719 //Exit both Bmps and Imps incase of Go/SAP Mode
6720 if((WLAN_HDD_SOFTAP == session_type) ||
6721 (WLAN_HDD_P2P_GO == session_type))
6722 {
6723 disableBmps = TRUE;
6724 disableImps = TRUE;
6725 }
6726
6727 if(TRUE == disableImps)
6728 {
6729 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6730 {
6731 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6732 }
6733 }
6734
6735 if(TRUE == disableBmps)
6736 {
6737 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6738 {
6739 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6740
6741 if(eHAL_STATUS_SUCCESS != halStatus)
6742 {
6743 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006744 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006745 VOS_ASSERT(0);
6746 return status;
6747 }
6748 }
6749
6750 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6751 {
6752 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6753
6754 if(eHAL_STATUS_SUCCESS != halStatus)
6755 {
6756 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006757 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 VOS_ASSERT(0);
6759 return status;
6760 }
6761 }
6762 }
6763
6764 if((TRUE == disableBmps) ||
6765 (TRUE == disableImps))
6766 {
6767 /* Now, get the chip into Full Power now */
6768 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6769 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6770 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6771
6772 if(halStatus != eHAL_STATUS_SUCCESS)
6773 {
6774 if(halStatus == eHAL_STATUS_PMC_PENDING)
6775 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306776 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306778 ret = wait_for_completion_interruptible_timeout(
6779 &pHddCtx->full_pwr_comp_var,
6780 msecs_to_jiffies(1000));
6781 if (ret <= 0)
6782 {
6783 hddLog(VOS_TRACE_LEVEL_ERROR,
6784 "%s: wait on full_pwr_comp_var failed %ld",
6785 __func__, ret);
6786 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 }
6788 else
6789 {
6790 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006791 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 VOS_ASSERT(0);
6793 return status;
6794 }
6795 }
6796
6797 status = VOS_STATUS_SUCCESS;
6798 }
6799
6800 break;
6801 }
6802 return status;
6803}
Katya Nigame7b69a82015-04-28 15:24:06 +05306804void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
6805 {
6806 hdd_mon_ctx_t *pMonCtx = NULL;
6807 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
6808
6809 pMonCtx->state = 0;
6810 pMonCtx->ChannelNo = 1;
6811 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05306812 pMonCtx->crcCheckEnabled = 1;
6813 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
6814 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05306815 pMonCtx->numOfMacFilters = 0;
6816 }
6817
Jeff Johnson295189b2012-06-20 16:38:30 -07006818
6819hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006820 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006821 tANI_U8 rtnl_held )
6822{
6823 hdd_adapter_t *pAdapter = NULL;
6824 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6825 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6826 VOS_STATUS exitbmpsStatus;
6827
Arif Hussain6d2a3322013-11-17 19:50:10 -08006828 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006829
Nirav Shah436658f2014-02-28 17:05:45 +05306830 if(macAddr == NULL)
6831 {
6832 /* Not received valid macAddr */
6833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6834 "%s:Unable to add virtual intf: Not able to get"
6835 "valid mac address",__func__);
6836 return NULL;
6837 }
6838
Jeff Johnson295189b2012-06-20 16:38:30 -07006839 //Disable BMPS incase of Concurrency
6840 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6841
6842 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6843 {
6844 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306845 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 VOS_ASSERT(0);
6847 return NULL;
6848 }
6849
6850 switch(session_type)
6851 {
6852 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006854 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 {
6856 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6857
6858 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306859 {
6860 hddLog(VOS_TRACE_LEVEL_FATAL,
6861 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306863 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006864
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306865#ifdef FEATURE_WLAN_TDLS
6866 /* A Mutex Lock is introduced while changing/initializing the mode to
6867 * protect the concurrent access for the Adapters by TDLS module.
6868 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306869 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306870#endif
6871
Jeff Johnsone7245742012-09-05 17:12:55 -07006872 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6873 NL80211_IFTYPE_P2P_CLIENT:
6874 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006875
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306877#ifdef FEATURE_WLAN_TDLS
6878 mutex_unlock(&pHddCtx->tdls_lock);
6879#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306880
6881 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 if( VOS_STATUS_SUCCESS != status )
6883 goto err_free_netdev;
6884
6885 status = hdd_register_interface( pAdapter, rtnl_held );
6886 if( VOS_STATUS_SUCCESS != status )
6887 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306888#ifdef FEATURE_WLAN_TDLS
6889 mutex_lock(&pHddCtx->tdls_lock);
6890#endif
c_hpothu002231a2015-02-05 14:58:51 +05306891 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306892#ifdef FEATURE_WLAN_TDLS
6893 mutex_unlock(&pHddCtx->tdls_lock);
6894#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006895 goto err_free_netdev;
6896 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306897
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306898 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306899 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306900
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306901#ifdef WLAN_NS_OFFLOAD
6902 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306903 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306904#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006905 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306906 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 netif_tx_disable(pAdapter->dev);
6908 //netif_tx_disable(pWlanDev);
6909 netif_carrier_off(pAdapter->dev);
6910
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306911 if (WLAN_HDD_P2P_CLIENT == session_type ||
6912 WLAN_HDD_P2P_DEVICE == session_type)
6913 {
6914 /* Initialize the work queue to defer the
6915 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05306916 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306917 hdd_p2p_roc_work_queue);
6918 }
6919
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 break;
6921 }
6922
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 case WLAN_HDD_SOFTAP:
6925 {
6926 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6927 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306928 {
6929 hddLog(VOS_TRACE_LEVEL_FATAL,
6930 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006931 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306932 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006933
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6935 NL80211_IFTYPE_AP:
6936 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 pAdapter->device_mode = session_type;
6938
6939 status = hdd_init_ap_mode(pAdapter);
6940 if( VOS_STATUS_SUCCESS != status )
6941 goto err_free_netdev;
6942
Nirav Shah7e3c8132015-06-22 23:51:42 +05306943 status = hdd_sta_id_hash_attach(pAdapter);
6944 if (VOS_STATUS_SUCCESS != status)
6945 {
6946 hddLog(VOS_TRACE_LEVEL_FATAL,
6947 FL("failed to attach hash for session %d"), session_type);
6948 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
6949 goto err_free_netdev;
6950 }
6951
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 status = hdd_register_hostapd( pAdapter, rtnl_held );
6953 if( VOS_STATUS_SUCCESS != status )
6954 {
c_hpothu002231a2015-02-05 14:58:51 +05306955 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 goto err_free_netdev;
6957 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 netif_tx_disable(pAdapter->dev);
6960 netif_carrier_off(pAdapter->dev);
6961
6962 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306963
6964 if (WLAN_HDD_P2P_GO == session_type)
6965 {
6966 /* Initialize the work queue to
6967 * defer the back to back RoC request */
6968 INIT_DELAYED_WORK(&pAdapter->roc_work,
6969 hdd_p2p_roc_work_queue);
6970 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006971 break;
6972 }
6973 case WLAN_HDD_MONITOR:
6974 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6976 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306977 {
6978 hddLog(VOS_TRACE_LEVEL_FATAL,
6979 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006980 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306981 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006982
Katya Nigame7b69a82015-04-28 15:24:06 +05306983 // Register wireless extensions
6984 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
6985 {
6986 hddLog(VOS_TRACE_LEVEL_FATAL,
6987 "hdd_register_wext() failed with status code %08d [x%08x]",
6988 status, status );
6989 status = VOS_STATUS_E_FAILURE;
6990 }
6991
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6993 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006994#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6995 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6996#else
6997 pAdapter->dev->open = hdd_mon_open;
6998 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05306999 pAdapter->dev->stop = hdd_mon_stop;
7000 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007001#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05307002 status = hdd_register_interface( pAdapter, rtnl_held );
7003 hdd_init_mon_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007004 hdd_init_tx_rx( pAdapter );
7005 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05307006 //Stop the Interface TX queue.
7007 netif_tx_disable(pAdapter->dev);
7008 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007009 }
7010 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 case WLAN_HDD_FTM:
7012 {
7013 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
7014
7015 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307016 {
7017 hddLog(VOS_TRACE_LEVEL_FATAL,
7018 FL("failed to allocate adapter for session %d"), session_type);
7019 return NULL;
7020 }
7021
Jeff Johnson295189b2012-06-20 16:38:30 -07007022 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
7023 * message while loading driver in FTM mode. */
7024 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
7025 pAdapter->device_mode = session_type;
7026 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307027
7028 hdd_init_tx_rx( pAdapter );
7029
7030 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307031 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05307032 netif_tx_disable(pAdapter->dev);
7033 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 }
7035 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07007036 default:
7037 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307038 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
7039 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 VOS_ASSERT(0);
7041 return NULL;
7042 }
7043 }
7044
Jeff Johnson295189b2012-06-20 16:38:30 -07007045 if( VOS_STATUS_SUCCESS == status )
7046 {
7047 //Add it to the hdd's session list.
7048 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
7049 if( NULL == pHddAdapterNode )
7050 {
7051 status = VOS_STATUS_E_NOMEM;
7052 }
7053 else
7054 {
7055 pHddAdapterNode->pAdapter = pAdapter;
7056 status = hdd_add_adapter_back ( pHddCtx,
7057 pHddAdapterNode );
7058 }
7059 }
7060
7061 if( VOS_STATUS_SUCCESS != status )
7062 {
7063 if( NULL != pAdapter )
7064 {
7065 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
7066 pAdapter = NULL;
7067 }
7068 if( NULL != pHddAdapterNode )
7069 {
7070 vos_mem_free( pHddAdapterNode );
7071 }
7072
7073 goto resume_bmps;
7074 }
7075
7076 if(VOS_STATUS_SUCCESS == status)
7077 {
7078 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
7079
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007080 //Initialize the WoWL service
7081 if(!hdd_init_wowl(pAdapter))
7082 {
7083 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7084 goto err_free_netdev;
7085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007086 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007087 return pAdapter;
7088
7089err_free_netdev:
7090 free_netdev(pAdapter->dev);
7091 wlan_hdd_release_intf_addr( pHddCtx,
7092 pAdapter->macAddressCurrent.bytes );
7093
7094resume_bmps:
7095 //If bmps disabled enable it
7096 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7097 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307098 if (pHddCtx->hdd_wlan_suspended)
7099 {
7100 hdd_set_pwrparams(pHddCtx);
7101 }
7102 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007103 }
7104 return NULL;
7105}
7106
7107VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7108 tANI_U8 rtnl_held )
7109{
7110 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7111 VOS_STATUS status;
7112
7113 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7114 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307115 {
7116 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7117 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007118 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307119 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007120
7121 while ( pCurrent->pAdapter != pAdapter )
7122 {
7123 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7124 if( VOS_STATUS_SUCCESS != status )
7125 break;
7126
7127 pCurrent = pNext;
7128 }
7129 pAdapterNode = pCurrent;
7130 if( VOS_STATUS_SUCCESS == status )
7131 {
7132 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7133 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307134
7135#ifdef FEATURE_WLAN_TDLS
7136
7137 /* A Mutex Lock is introduced while changing/initializing the mode to
7138 * protect the concurrent access for the Adapters by TDLS module.
7139 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307140 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307141#endif
7142
Jeff Johnson295189b2012-06-20 16:38:30 -07007143 hdd_remove_adapter( pHddCtx, pAdapterNode );
7144 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007145 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007146
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307147#ifdef FEATURE_WLAN_TDLS
7148 mutex_unlock(&pHddCtx->tdls_lock);
7149#endif
7150
Jeff Johnson295189b2012-06-20 16:38:30 -07007151
7152 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307153 if ((!vos_concurrent_open_sessions_running()) &&
7154 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7155 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007156 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307157 if (pHddCtx->hdd_wlan_suspended)
7158 {
7159 hdd_set_pwrparams(pHddCtx);
7160 }
7161 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007162 }
7163
7164 return VOS_STATUS_SUCCESS;
7165 }
7166
7167 return VOS_STATUS_E_FAILURE;
7168}
7169
7170VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7171{
7172 hdd_adapter_list_node_t *pHddAdapterNode;
7173 VOS_STATUS status;
7174
7175 ENTER();
7176
7177 do
7178 {
7179 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7180 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7181 {
7182 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7183 vos_mem_free( pHddAdapterNode );
7184 }
7185 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7186
7187 EXIT();
7188
7189 return VOS_STATUS_SUCCESS;
7190}
7191
7192void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7193{
7194 v_U8_t addIE[1] = {0};
7195
7196 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7197 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7198 eANI_BOOLEAN_FALSE) )
7199 {
7200 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007201 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007202 }
7203
7204 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7205 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7206 eANI_BOOLEAN_FALSE) )
7207 {
7208 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007209 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007210 }
7211
7212 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7213 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7214 eANI_BOOLEAN_FALSE) )
7215 {
7216 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007217 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 }
7219}
7220
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307221VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7222 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007223{
7224 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7225 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307226 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307228 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307229 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05307230 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007231
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307232 if (pHddCtx->isLogpInProgress) {
7233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7234 "%s:LOGP in Progress. Ignore!!!",__func__);
7235 return VOS_STATUS_E_FAILURE;
7236 }
7237
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307239
Nirav Shah7e3c8132015-06-22 23:51:42 +05307240 status = hdd_sta_id_hash_detach(pAdapter);
7241 if (status != VOS_STATUS_SUCCESS)
7242 hddLog(VOS_TRACE_LEVEL_ERROR,
7243 FL("sta id hash detach failed"));
7244
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307245 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007246 switch(pAdapter->device_mode)
7247 {
7248 case WLAN_HDD_INFRA_STATION:
7249 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007250 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307251 {
7252 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05307253#ifdef FEATURE_WLAN_TDLS
7254 mutex_lock(&pHddCtx->tdls_lock);
7255 wlan_hdd_tdls_exit(pAdapter, TRUE);
7256 mutex_unlock(&pHddCtx->tdls_lock);
7257#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307258 if( hdd_connIsConnected(pstation) ||
7259 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007260 {
7261 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7262 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7263 pAdapter->sessionId,
7264 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7265 else
7266 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7267 pAdapter->sessionId,
7268 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7269 //success implies disconnect command got queued up successfully
7270 if(halStatus == eHAL_STATUS_SUCCESS)
7271 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307272 ret = wait_for_completion_interruptible_timeout(
7273 &pAdapter->disconnect_comp_var,
7274 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7275 if (ret <= 0)
7276 {
7277 hddLog(VOS_TRACE_LEVEL_ERROR,
7278 "%s: wait on disconnect_comp_var failed %ld",
7279 __func__, ret);
7280 }
7281 }
7282 else
7283 {
7284 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7285 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007286 }
7287 memset(&wrqu, '\0', sizeof(wrqu));
7288 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7289 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7290 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7291 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307292 else if(pstation->conn_info.connState ==
7293 eConnectionState_Disconnecting)
7294 {
7295 ret = wait_for_completion_interruptible_timeout(
7296 &pAdapter->disconnect_comp_var,
7297 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7298 if (ret <= 0)
7299 {
7300 hddLog(VOS_TRACE_LEVEL_ERROR,
7301 FL("wait on disconnect_comp_var failed %ld"), ret);
7302 }
7303 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307304 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307306 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307307 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007308 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307309 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7310 {
7311 while (pAdapter->is_roc_inprogress)
7312 {
7313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7314 "%s: ROC in progress for session %d!!!",
7315 __func__, pAdapter->sessionId);
7316 // waiting for ROC to expire
7317 msleep(500);
7318 /* In GO present case , if retry exceeds 3,
7319 it means something went wrong. */
7320 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7321 {
7322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7323 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307324 if (eHAL_STATUS_SUCCESS !=
7325 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7326 pAdapter->sessionId ))
7327 {
7328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7329 FL("Failed to Cancel Remain on Channel"));
7330 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307331 wait_for_completion_interruptible_timeout(
7332 &pAdapter->cancel_rem_on_chan_var,
7333 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7334 break;
7335 }
7336 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307337 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307338 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307339#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307340 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307341#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307342
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307343 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307344
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307345 /* It is possible that the caller of this function does not
7346 * wish to close the session
7347 */
7348 if (VOS_TRUE == bCloseSession &&
7349 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007350 {
7351 INIT_COMPLETION(pAdapter->session_close_comp_var);
7352 if (eHAL_STATUS_SUCCESS ==
mukul sharmabab477d2015-06-11 17:14:55 +05307353 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, VOS_FALSE,
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307354 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307356 unsigned long ret;
7357
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307359 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307360 &pAdapter->session_close_comp_var,
7361 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307362 if ( 0 >= ret)
7363 {
7364 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307365 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307366 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007367 }
7368 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307369 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007370 break;
7371
7372 case WLAN_HDD_SOFTAP:
7373 case WLAN_HDD_P2P_GO:
7374 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307375 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7376 while (pAdapter->is_roc_inprogress) {
7377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7378 "%s: ROC in progress for session %d!!!",
7379 __func__, pAdapter->sessionId);
7380 msleep(500);
7381 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7383 "%s: ROC completion is not received.!!!", __func__);
7384 WLANSAP_CancelRemainOnChannel(
7385 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7386 wait_for_completion_interruptible_timeout(
7387 &pAdapter->cancel_rem_on_chan_var,
7388 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7389 break;
7390 }
7391 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307392
Anand N Sunkaddc63c792015-06-03 14:33:24 +05307393 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307394 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007395 mutex_lock(&pHddCtx->sap_lock);
7396 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7397 {
7398 VOS_STATUS status;
7399 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7400
7401 //Stop Bss.
7402 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7403 if (VOS_IS_STATUS_SUCCESS(status))
7404 {
7405 hdd_hostapd_state_t *pHostapdState =
7406 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7407
7408 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7409
7410 if (!VOS_IS_STATUS_SUCCESS(status))
7411 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307412 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7413 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007414 }
7415 }
7416 else
7417 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007418 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007419 }
7420 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307421 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007422
7423 if (eHAL_STATUS_FAILURE ==
7424 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7425 0, NULL, eANI_BOOLEAN_FALSE))
7426 {
7427 hddLog(LOGE,
7428 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007429 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007430 }
7431
7432 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7433 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7434 eANI_BOOLEAN_FALSE) )
7435 {
7436 hddLog(LOGE,
7437 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7438 }
7439
7440 // Reset WNI_CFG_PROBE_RSP Flags
7441 wlan_hdd_reset_prob_rspies(pAdapter);
7442 kfree(pAdapter->sessionCtx.ap.beacon);
7443 pAdapter->sessionCtx.ap.beacon = NULL;
7444 }
7445 mutex_unlock(&pHddCtx->sap_lock);
7446 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007447
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 case WLAN_HDD_MONITOR:
7449 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007450
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 default:
7452 break;
7453 }
7454
7455 EXIT();
7456 return VOS_STATUS_SUCCESS;
7457}
7458
7459VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7460{
7461 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7462 VOS_STATUS status;
7463 hdd_adapter_t *pAdapter;
7464
7465 ENTER();
7466
7467 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7468
7469 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7470 {
7471 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007472
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307473 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007474
7475 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7476 pAdapterNode = pNext;
7477 }
7478
7479 EXIT();
7480
7481 return VOS_STATUS_SUCCESS;
7482}
7483
Rajeev Kumarf999e582014-01-09 17:33:29 -08007484
7485#ifdef FEATURE_WLAN_BATCH_SCAN
7486/**---------------------------------------------------------------------------
7487
7488 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7489 structures
7490
7491 \param - pAdapter Pointer to HDD adapter
7492
7493 \return - None
7494
7495 --------------------------------------------------------------------------*/
7496void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7497{
7498 tHddBatchScanRsp *pNode;
7499 tHddBatchScanRsp *pPrev;
7500
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307501 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007502 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307503 hddLog(VOS_TRACE_LEVEL_ERROR,
7504 "%s: Adapter context is Null", __func__);
7505 return;
7506 }
7507
7508 pNode = pAdapter->pBatchScanRsp;
7509 while (pNode)
7510 {
7511 pPrev = pNode;
7512 pNode = pNode->pNext;
7513 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007514 }
7515
7516 pAdapter->pBatchScanRsp = NULL;
7517 pAdapter->numScanList = 0;
7518 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7519 pAdapter->prev_batch_id = 0;
7520
7521 return;
7522}
7523#endif
7524
7525
Jeff Johnson295189b2012-06-20 16:38:30 -07007526VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7527{
7528 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7529 VOS_STATUS status;
7530 hdd_adapter_t *pAdapter;
7531
7532 ENTER();
7533
7534 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7535
7536 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7537 {
7538 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307539 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007540 netif_tx_disable(pAdapter->dev);
7541 netif_carrier_off(pAdapter->dev);
7542
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007543 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7544
Jeff Johnson295189b2012-06-20 16:38:30 -07007545 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307546
Katya Nigam1fd24402015-02-16 14:52:19 +05307547 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7548 hdd_ibss_deinit_tx_rx(pAdapter);
7549
Nirav Shah7e3c8132015-06-22 23:51:42 +05307550 status = hdd_sta_id_hash_detach(pAdapter);
7551 if (status != VOS_STATUS_SUCCESS)
7552 hddLog(VOS_TRACE_LEVEL_ERROR,
7553 FL("sta id hash detach failed for session id %d"),
7554 pAdapter->sessionId);
7555
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307556 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7557
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307558 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7559 {
7560 hdd_wmm_adapter_close( pAdapter );
7561 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7562 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007563
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307564 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7565 {
7566 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7567 }
7568
Rajeev Kumarf999e582014-01-09 17:33:29 -08007569#ifdef FEATURE_WLAN_BATCH_SCAN
7570 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7571 {
7572 hdd_deinit_batch_scan(pAdapter);
7573 }
7574#endif
7575
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307576#ifdef FEATURE_WLAN_TDLS
7577 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307578 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307579 mutex_unlock(&pHddCtx->tdls_lock);
7580#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7582 pAdapterNode = pNext;
7583 }
7584
7585 EXIT();
7586
7587 return VOS_STATUS_SUCCESS;
7588}
7589
7590VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7591{
7592 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7593 VOS_STATUS status;
7594 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307595 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007596
7597 ENTER();
7598
7599 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7600
7601 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7602 {
7603 pAdapter = pAdapterNode->pAdapter;
7604
Kumar Anand82c009f2014-05-29 00:29:42 -07007605 hdd_wmm_init( pAdapter );
7606
Jeff Johnson295189b2012-06-20 16:38:30 -07007607 switch(pAdapter->device_mode)
7608 {
7609 case WLAN_HDD_INFRA_STATION:
7610 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007611 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307612
7613 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7614
Jeff Johnson295189b2012-06-20 16:38:30 -07007615 hdd_init_station_mode(pAdapter);
7616 /* Open the gates for HDD to receive Wext commands */
7617 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007618 pHddCtx->scan_info.mScanPending = FALSE;
7619 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007620
7621 //Trigger the initial scan
7622 hdd_wlan_initial_scan(pAdapter);
7623
7624 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307625 if (eConnectionState_Associated == connState ||
7626 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007627 {
7628 union iwreq_data wrqu;
7629 memset(&wrqu, '\0', sizeof(wrqu));
7630 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7631 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7632 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007633 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007634
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 /* indicate disconnected event to nl80211 */
7636 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7637 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007638 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307639 else if (eConnectionState_Connecting == connState)
7640 {
7641 /*
7642 * Indicate connect failure to supplicant if we were in the
7643 * process of connecting
7644 */
7645 cfg80211_connect_result(pAdapter->dev, NULL,
7646 NULL, 0, NULL, 0,
7647 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7648 GFP_KERNEL);
7649 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007650 break;
7651
7652 case WLAN_HDD_SOFTAP:
7653 /* softAP can handle SSR */
7654 break;
7655
7656 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007657 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007658 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007659 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007660 break;
7661
7662 case WLAN_HDD_MONITOR:
7663 /* monitor interface start */
7664 break;
7665 default:
7666 break;
7667 }
7668
7669 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7670 pAdapterNode = pNext;
7671 }
7672
7673 EXIT();
7674
7675 return VOS_STATUS_SUCCESS;
7676}
7677
7678VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7679{
7680 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7681 hdd_adapter_t *pAdapter;
7682 VOS_STATUS status;
7683 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307684 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007685
7686 ENTER();
7687
7688 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7689
7690 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7691 {
7692 pAdapter = pAdapterNode->pAdapter;
7693
7694 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7695 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7696 {
7697 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7698 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7699
Abhishek Singhf4669da2014-05-26 15:07:49 +05307700 hddLog(VOS_TRACE_LEVEL_INFO,
7701 "%s: Set HDD connState to eConnectionState_NotConnected",
7702 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007703 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7704 init_completion(&pAdapter->disconnect_comp_var);
7705 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7706 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7707
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307708 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007709 &pAdapter->disconnect_comp_var,
7710 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307711 if (0 >= ret)
7712 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7713 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007714
7715 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7716 pHddCtx->isAmpAllowed = VOS_FALSE;
7717 sme_RoamConnect(pHddCtx->hHal,
7718 pAdapter->sessionId, &(pWextState->roamProfile),
7719 &roamId);
7720 }
7721
7722 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7723 pAdapterNode = pNext;
7724 }
7725
7726 EXIT();
7727
7728 return VOS_STATUS_SUCCESS;
7729}
7730
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007731void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7732{
7733 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7734 VOS_STATUS status;
7735 hdd_adapter_t *pAdapter;
7736 hdd_station_ctx_t *pHddStaCtx;
7737 hdd_ap_ctx_t *pHddApCtx;
7738 hdd_hostapd_state_t * pHostapdState;
7739 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7740 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7741 const char *p2pMode = "DEV";
7742 const char *ccMode = "Standalone";
7743 int n;
7744
7745 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7746 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7747 {
7748 pAdapter = pAdapterNode->pAdapter;
7749 switch (pAdapter->device_mode) {
7750 case WLAN_HDD_INFRA_STATION:
7751 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7752 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7753 staChannel = pHddStaCtx->conn_info.operationChannel;
7754 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7755 }
7756 break;
7757 case WLAN_HDD_P2P_CLIENT:
7758 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7759 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7760 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7761 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7762 p2pMode = "CLI";
7763 }
7764 break;
7765 case WLAN_HDD_P2P_GO:
7766 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7767 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7768 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7769 p2pChannel = pHddApCtx->operatingChannel;
7770 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7771 }
7772 p2pMode = "GO";
7773 break;
7774 case WLAN_HDD_SOFTAP:
7775 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7776 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7777 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7778 apChannel = pHddApCtx->operatingChannel;
7779 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7780 }
7781 break;
7782 default:
7783 break;
7784 }
7785 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7786 pAdapterNode = pNext;
7787 }
7788 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7789 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7790 }
7791 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7792 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7793 if (p2pChannel > 0) {
7794 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7795 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7796 }
7797 if (apChannel > 0) {
7798 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7799 apChannel, MAC_ADDR_ARRAY(apBssid));
7800 }
7801
7802 if (p2pChannel > 0 && apChannel > 0) {
7803 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7804 }
7805}
7806
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007807bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007808{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007809 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007810}
7811
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007812/* Once SSR is disabled then it cannot be set. */
7813void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007814{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007815 if (HDD_SSR_DISABLED == isSsrRequired)
7816 return;
7817
Jeff Johnson295189b2012-06-20 16:38:30 -07007818 isSsrRequired = value;
7819}
7820
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05307821void hdd_set_pre_close( hdd_context_t *pHddCtx)
7822{
7823 sme_PreClose(pHddCtx->hHal);
7824}
7825
Jeff Johnson295189b2012-06-20 16:38:30 -07007826VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7827 hdd_adapter_list_node_t** ppAdapterNode)
7828{
7829 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307830 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007831 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7832 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307833 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007834 return status;
7835}
7836
7837VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7838 hdd_adapter_list_node_t* pAdapterNode,
7839 hdd_adapter_list_node_t** pNextAdapterNode)
7840{
7841 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307842 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007843 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7844 (hdd_list_node_t*) pAdapterNode,
7845 (hdd_list_node_t**)pNextAdapterNode );
7846
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307847 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007848 return status;
7849}
7850
7851VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7852 hdd_adapter_list_node_t* pAdapterNode)
7853{
7854 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307855 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007856 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7857 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307858 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007859 return status;
7860}
7861
7862VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7863 hdd_adapter_list_node_t** ppAdapterNode)
7864{
7865 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307866 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007867 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7868 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307869 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007870 return status;
7871}
7872
7873VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7874 hdd_adapter_list_node_t* pAdapterNode)
7875{
7876 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307877 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007878 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7879 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307880 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 return status;
7882}
7883
7884VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7885 hdd_adapter_list_node_t* pAdapterNode)
7886{
7887 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307888 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007889 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7890 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05307891 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007892 return status;
7893}
7894
7895hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7896 tSirMacAddr macAddr )
7897{
7898 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7899 hdd_adapter_t *pAdapter;
7900 VOS_STATUS status;
7901
7902 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7903
7904 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7905 {
7906 pAdapter = pAdapterNode->pAdapter;
7907
7908 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7909 macAddr, sizeof(tSirMacAddr) ) )
7910 {
7911 return pAdapter;
7912 }
7913 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7914 pAdapterNode = pNext;
7915 }
7916
7917 return NULL;
7918
7919}
7920
7921hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7922{
7923 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7924 hdd_adapter_t *pAdapter;
7925 VOS_STATUS status;
7926
7927 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7928
7929 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7930 {
7931 pAdapter = pAdapterNode->pAdapter;
7932
7933 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7934 IFNAMSIZ ) )
7935 {
7936 return pAdapter;
7937 }
7938 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7939 pAdapterNode = pNext;
7940 }
7941
7942 return NULL;
7943
7944}
7945
7946hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7947{
7948 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7949 hdd_adapter_t *pAdapter;
7950 VOS_STATUS status;
7951
7952 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7953
7954 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7955 {
7956 pAdapter = pAdapterNode->pAdapter;
7957
7958 if( pAdapter && (mode == pAdapter->device_mode) )
7959 {
7960 return pAdapter;
7961 }
7962 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7963 pAdapterNode = pNext;
7964 }
7965
7966 return NULL;
7967
7968}
7969
7970//Remove this function later
7971hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7972{
7973 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7974 hdd_adapter_t *pAdapter;
7975 VOS_STATUS status;
7976
7977 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7978
7979 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7980 {
7981 pAdapter = pAdapterNode->pAdapter;
7982
7983 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7984 {
7985 return pAdapter;
7986 }
7987
7988 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7989 pAdapterNode = pNext;
7990 }
7991
7992 return NULL;
7993
7994}
7995
Jeff Johnson295189b2012-06-20 16:38:30 -07007996/**---------------------------------------------------------------------------
7997
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307998 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007999
8000 This API returns the operating channel of the requested device mode
8001
8002 \param - pHddCtx - Pointer to the HDD context.
8003 - mode - Device mode for which operating channel is required
8004 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
8005 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
8006 \return - channel number. "0" id the requested device is not found OR it is not connected.
8007 --------------------------------------------------------------------------*/
8008v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
8009{
8010 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8011 VOS_STATUS status;
8012 hdd_adapter_t *pAdapter;
8013 v_U8_t operatingChannel = 0;
8014
8015 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8016
8017 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8018 {
8019 pAdapter = pAdapterNode->pAdapter;
8020
8021 if( mode == pAdapter->device_mode )
8022 {
8023 switch(pAdapter->device_mode)
8024 {
8025 case WLAN_HDD_INFRA_STATION:
8026 case WLAN_HDD_P2P_CLIENT:
8027 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
8028 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
8029 break;
8030 case WLAN_HDD_SOFTAP:
8031 case WLAN_HDD_P2P_GO:
8032 /*softap connection info */
8033 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8034 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
8035 break;
8036 default:
8037 break;
8038 }
8039
8040 break; //Found the device of interest. break the loop
8041 }
8042
8043 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8044 pAdapterNode = pNext;
8045 }
8046 return operatingChannel;
8047}
8048
8049#ifdef WLAN_FEATURE_PACKET_FILTERING
8050/**---------------------------------------------------------------------------
8051
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308052 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008053
8054 This used to set the multicast address list.
8055
8056 \param - dev - Pointer to the WLAN device.
8057 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308058 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07008059
8060 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308061static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008062{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308063 hdd_adapter_t *pAdapter;
8064 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308066 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308068
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308069 ENTER();
8070
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308071 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308072 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 {
8074 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308075 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 return;
8077 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308078 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8079 ret = wlan_hdd_validate_context(pHddCtx);
8080 if (0 != ret)
8081 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308082 return;
8083 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008084 if (dev->flags & IFF_ALLMULTI)
8085 {
8086 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008087 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308088 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008089 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308090 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 {
8092 mc_count = netdev_mc_count(dev);
8093 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008094 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8096 {
8097 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008098 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308099 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 return;
8101 }
8102
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308103 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008104
8105 netdev_for_each_mc_addr(ha, dev) {
8106 if (i == mc_count)
8107 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308108 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8109 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008110 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308111 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308112 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008113 i++;
8114 }
8115 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308116
8117 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008118 return;
8119}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308120
8121static void hdd_set_multicast_list(struct net_device *dev)
8122{
8123 vos_ssr_protect(__func__);
8124 __hdd_set_multicast_list(dev);
8125 vos_ssr_unprotect(__func__);
8126}
Jeff Johnson295189b2012-06-20 16:38:30 -07008127#endif
8128
8129/**---------------------------------------------------------------------------
8130
8131 \brief hdd_select_queue() -
8132
8133 This function is registered with the Linux OS for network
8134 core to decide which queue to use first.
8135
8136 \param - dev - Pointer to the WLAN device.
8137 - skb - Pointer to OS packet (sk_buff).
8138 \return - ac, Queue Index/access category corresponding to UP in IP header
8139
8140 --------------------------------------------------------------------------*/
8141v_U16_t hdd_select_queue(struct net_device *dev,
8142 struct sk_buff *skb)
8143{
8144 return hdd_wmm_select_queue(dev, skb);
8145}
8146
8147
8148/**---------------------------------------------------------------------------
8149
8150 \brief hdd_wlan_initial_scan() -
8151
8152 This function triggers the initial scan
8153
8154 \param - pAdapter - Pointer to the HDD adapter.
8155
8156 --------------------------------------------------------------------------*/
8157void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8158{
8159 tCsrScanRequest scanReq;
8160 tCsrChannelInfo channelInfo;
8161 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008162 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008163 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8164
8165 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8166 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8167 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8168
8169 if(sme_Is11dSupported(pHddCtx->hHal))
8170 {
8171 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8172 if ( HAL_STATUS_SUCCESS( halStatus ) )
8173 {
8174 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8175 if( !scanReq.ChannelInfo.ChannelList )
8176 {
8177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8178 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008179 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008180 return;
8181 }
8182 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8183 channelInfo.numOfChannels);
8184 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8185 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008186 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008187 }
8188
8189 scanReq.scanType = eSIR_PASSIVE_SCAN;
8190 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8191 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8192 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8193 }
8194 else
8195 {
8196 scanReq.scanType = eSIR_ACTIVE_SCAN;
8197 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8198 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8199 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8200 }
8201
8202 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8203 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8204 {
8205 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8206 __func__, halStatus );
8207 }
8208
8209 if(sme_Is11dSupported(pHddCtx->hHal))
8210 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8211}
8212
mukul sharmabab477d2015-06-11 17:14:55 +05308213void hdd_purge_cmd_list_all_adapters( hdd_context_t *pHddCtx )
8214{
8215 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8216 VOS_STATUS status;
8217 hdd_adapter_t *pAdapter;
8218
8219 ENTER();
8220
8221 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8222
8223 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8224 {
8225 pAdapter = pAdapterNode->pAdapter;
8226
8227 status = sme_PurgeCmdList(pHddCtx->hHal, pAdapter->sessionId);
8228 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8229 pAdapterNode = pNext;
8230 }
8231
8232 EXIT();
8233}
Jeff Johnson295189b2012-06-20 16:38:30 -07008234/**---------------------------------------------------------------------------
8235
8236 \brief hdd_full_power_callback() - HDD full power callback function
8237
8238 This is the function invoked by SME to inform the result of a full power
8239 request issued by HDD
8240
8241 \param - callbackcontext - Pointer to cookie
8242 \param - status - result of request
8243
8244 \return - None
8245
8246 --------------------------------------------------------------------------*/
8247static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8248{
Jeff Johnson72a40512013-12-19 10:14:15 -08008249 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008250
8251 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308252 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008253
8254 if (NULL == callbackContext)
8255 {
8256 hddLog(VOS_TRACE_LEVEL_ERROR,
8257 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008258 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008259 return;
8260 }
8261
Jeff Johnson72a40512013-12-19 10:14:15 -08008262 /* there is a race condition that exists between this callback
8263 function and the caller since the caller could time out either
8264 before or while this code is executing. we use a spinlock to
8265 serialize these actions */
8266 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008267
8268 if (POWER_CONTEXT_MAGIC != pContext->magic)
8269 {
8270 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008271 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008272 hddLog(VOS_TRACE_LEVEL_WARN,
8273 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008274 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008275 return;
8276 }
8277
Jeff Johnson72a40512013-12-19 10:14:15 -08008278 /* context is valid so caller is still waiting */
8279
8280 /* paranoia: invalidate the magic */
8281 pContext->magic = 0;
8282
8283 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008285
8286 /* serialization is complete */
8287 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008288}
8289
Katya Nigamf0511f62015-05-05 16:40:57 +05308290void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
8291{
8292 pMonCtx->typeSubtypeBitmap = 0;
8293 if( type%10 ) /* Management Packets */
8294 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
8295 type/=10;
8296 if( type%10 ) /* Control Packets */
8297 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
8298 type/=10;
8299 if( type%10 ) /* Data Packets */
8300 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
8301}
8302
8303VOS_STATUS wlan_hdd_mon_poststartmsg( hdd_mon_ctx_t *pMonCtx )
8304{
8305 vos_msg_t monMsg;
8306
8307 monMsg.type = WDA_MON_START_REQ;
8308 monMsg.reserved = 0;
8309 monMsg.bodyptr = (v_U8_t*)pMonCtx;
8310 monMsg.bodyval = 0;
8311
8312 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8313 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8314 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8315 return VOS_STATUS_E_FAILURE;
8316 }
8317
8318 return VOS_STATUS_SUCCESS;
8319}
8320
8321void wlan_hdd_mon_poststopmsg(void)
8322{
8323 vos_msg_t monMsg;
8324
8325 monMsg.type = WDA_MON_STOP_REQ;
8326 monMsg.reserved = 0;
8327 monMsg.bodyptr = NULL;
8328 monMsg.bodyval = 0;
8329
8330 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
8331 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
8332 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
8333 }
8334}
8335
Katya Nigame7b69a82015-04-28 15:24:06 +05308336void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
8337{
8338 VOS_STATUS vosStatus;
8339 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8340 struct wiphy *wiphy = pHddCtx->wiphy;
8341
8342 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
8343 if(pAdapter == NULL || pVosContext == NULL)
8344 {
8345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
8346 return ;
8347 }
Katya Nigamf0511f62015-05-05 16:40:57 +05308348
8349 wlan_hdd_mon_poststopmsg();
Katya Nigame7b69a82015-04-28 15:24:06 +05308350 hdd_UnregisterWext(pAdapter->dev);
8351
8352 vos_mon_stop( pVosContext );
8353
8354 vosStatus = vos_sched_close( pVosContext );
8355 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8356 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8357 "%s: Failed to close VOSS Scheduler",__func__);
8358 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8359 }
8360
8361 vosStatus = vos_nv_close();
8362 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8363 {
8364 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8365 "%s: Failed to close NV", __func__);
8366 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8367 }
8368
8369 vos_close(pVosContext);
8370
8371 #ifdef WLAN_KD_READY_NOTIFIER
8372 nl_srv_exit(pHddCtx->ptt_pid);
8373 #else
8374 nl_srv_exit();
8375 #endif
8376
8377 if (pHddCtx->cfg_ini)
8378 {
8379 kfree(pHddCtx->cfg_ini);
8380 pHddCtx->cfg_ini= NULL;
8381 }
8382 hdd_close_all_adapters( pHddCtx );
8383
8384 wiphy_free(wiphy) ;
8385
8386}
Jeff Johnson295189b2012-06-20 16:38:30 -07008387/**---------------------------------------------------------------------------
8388
8389 \brief hdd_wlan_exit() - HDD WLAN exit function
8390
8391 This is the driver exit point (invoked during rmmod)
8392
8393 \param - pHddCtx - Pointer to the HDD Context
8394
8395 \return - None
8396
8397 --------------------------------------------------------------------------*/
8398void hdd_wlan_exit(hdd_context_t *pHddCtx)
8399{
8400 eHalStatus halStatus;
8401 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8402 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308403 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008404 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008405 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308407 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008408
8409 ENTER();
8410
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308411
Katya Nigame7b69a82015-04-28 15:24:06 +05308412 if (VOS_MONITOR_MODE == hdd_get_conparam())
8413 {
8414 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
8415 wlan_hdd_mon_close(pHddCtx);
8416 return;
8417 }
8418 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08008419 {
8420 // Unloading, restart logic is no more required.
8421 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008422
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308423#ifdef FEATURE_WLAN_TDLS
8424 /* At the time of driver unloading; if tdls connection is present;
8425 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8426 * wlan_hdd_tdls_find_peer always checks for valid context;
8427 * as load/unload in progress there can be a race condition.
8428 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8429 * when tdls state is enabled.
8430 * As soon as driver set load/unload flag; tdls flag also needs
8431 * to be disabled so that hdd_rx_packet_cbk won't call
8432 * wlan_hdd_tdls_find_peer.
8433 */
8434 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8435#endif
8436
c_hpothu5ab05e92014-06-13 17:34:05 +05308437 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8438 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308440 pAdapter = pAdapterNode->pAdapter;
8441 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008442 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308443 /* Disable TX on the interface, after this hard_start_xmit() will
8444 * not be called on that interface
8445 */
8446 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8447 netif_tx_disable(pAdapter->dev);
8448
8449 /* Mark the interface status as "down" for outside world */
8450 netif_carrier_off(pAdapter->dev);
8451
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308452 /* DeInit the adapter. This ensures that all data packets
8453 * are freed.
8454 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308455#ifdef FEATURE_WLAN_TDLS
8456 mutex_lock(&pHddCtx->tdls_lock);
8457#endif
c_hpothu002231a2015-02-05 14:58:51 +05308458 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308459#ifdef FEATURE_WLAN_TDLS
8460 mutex_unlock(&pHddCtx->tdls_lock);
8461#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308462
c_hpothu5ab05e92014-06-13 17:34:05 +05308463 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8464 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8465 {
8466 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8467 hdd_UnregisterWext(pAdapter->dev);
8468 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308469
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308471 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8472 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008473 }
mukul sharmabab477d2015-06-11 17:14:55 +05308474
8475 //Purge all sme cmd's for all interface
8476 hdd_purge_cmd_list_all_adapters(pHddCtx);
8477
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308478 // Cancel any outstanding scan requests. We are about to close all
8479 // of our adapters, but an adapter structure is what SME passes back
8480 // to our callback function. Hence if there are any outstanding scan
8481 // requests then there is a race condition between when the adapter
8482 // is closed and when the callback is invoked.We try to resolve that
8483 // race condition here by canceling any outstanding scans before we
8484 // close the adapters.
8485 // Note that the scans may be cancelled in an asynchronous manner,
8486 // so ideally there needs to be some kind of synchronization. Rather
8487 // than introduce a new synchronization here, we will utilize the
8488 // fact that we are about to Request Full Power, and since that is
8489 // synchronized, the expectation is that by the time Request Full
8490 // Power has completed all scans will be cancelled.
8491 if (pHddCtx->scan_info.mScanPending)
8492 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308493 if(NULL != pAdapter)
8494 {
8495 hddLog(VOS_TRACE_LEVEL_INFO,
8496 FL("abort scan mode: %d sessionId: %d"),
8497 pAdapter->device_mode,
8498 pAdapter->sessionId);
8499 }
8500 hdd_abort_mac_scan(pHddCtx,
8501 pHddCtx->scan_info.sessionId,
8502 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308503 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308505 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008506 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308507 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308508 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8509 {
8510 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8512 "%s: in middle of FTM START", __func__);
8513 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8514 msecs_to_jiffies(20000));
8515 if(!lrc)
8516 {
8517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8518 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8519 }
8520 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008521 wlan_hdd_ftm_close(pHddCtx);
8522 goto free_hdd_ctx;
8523 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308524
Jeff Johnson295189b2012-06-20 16:38:30 -07008525 /* DeRegister with platform driver as client for Suspend/Resume */
8526 vosStatus = hddDeregisterPmOps(pHddCtx);
8527 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8528 {
8529 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8530 VOS_ASSERT(0);
8531 }
8532
8533 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8534 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8535 {
8536 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8537 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008538
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008539 //Stop the traffic monitor timer
8540 if ( VOS_TIMER_STATE_RUNNING ==
8541 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8542 {
8543 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8544 }
8545
8546 // Destroy the traffic monitor timer
8547 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8548 &pHddCtx->tx_rx_trafficTmr)))
8549 {
8550 hddLog(VOS_TRACE_LEVEL_ERROR,
8551 "%s: Cannot deallocate Traffic monitor timer", __func__);
8552 }
8553
Jeff Johnson295189b2012-06-20 16:38:30 -07008554 //Disable IMPS/BMPS as we do not want the device to enter any power
8555 //save mode during shutdown
8556 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8557 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8558 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8559
8560 //Ensure that device is in full power as we will touch H/W during vos_Stop
8561 init_completion(&powerContext.completion);
8562 powerContext.magic = POWER_CONTEXT_MAGIC;
8563
8564 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8565 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8566
8567 if (eHAL_STATUS_SUCCESS != halStatus)
8568 {
8569 if (eHAL_STATUS_PMC_PENDING == halStatus)
8570 {
8571 /* request was sent -- wait for the response */
8572 lrc = wait_for_completion_interruptible_timeout(
8573 &powerContext.completion,
8574 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008575 if (lrc <= 0)
8576 {
8577 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008578 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 }
8580 }
8581 else
8582 {
8583 hddLog(VOS_TRACE_LEVEL_ERROR,
8584 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008585 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008586 /* continue -- need to clean up as much as possible */
8587 }
8588 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308589 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8590 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8591 {
8592 /* This will issue a dump command which will clean up
8593 BTQM queues and unblock MC thread */
8594 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8595 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008596
Jeff Johnson72a40512013-12-19 10:14:15 -08008597 /* either we never sent a request, we sent a request and received a
8598 response or we sent a request and timed out. if we never sent a
8599 request or if we sent a request and got a response, we want to
8600 clear the magic out of paranoia. if we timed out there is a
8601 race condition such that the callback function could be
8602 executing at the same time we are. of primary concern is if the
8603 callback function had already verified the "magic" but had not
8604 yet set the completion variable when a timeout occurred. we
8605 serialize these activities by invalidating the magic while
8606 holding a shared spinlock which will cause us to block if the
8607 callback is currently executing */
8608 spin_lock(&hdd_context_lock);
8609 powerContext.magic = 0;
8610 spin_unlock(&hdd_context_lock);
8611
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +05308612 /* If Device is shutdown, no point for SME to wait for responses
8613 from device. Pre Close SME */
8614 if(wcnss_device_is_shutdown())
8615 {
8616 sme_PreClose(pHddCtx->hHal);
8617 }
Yue Ma0d4891e2013-08-06 17:01:45 -07008618 hdd_debugfs_exit(pHddCtx);
8619
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308620#ifdef WLAN_NS_OFFLOAD
8621 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8622 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8623#endif
8624 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8625 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8626
Jeff Johnson295189b2012-06-20 16:38:30 -07008627 // Unregister the Net Device Notifier
8628 unregister_netdevice_notifier(&hdd_netdev_notifier);
8629
Jeff Johnson295189b2012-06-20 16:38:30 -07008630 hdd_stop_all_adapters( pHddCtx );
8631
Jeff Johnson295189b2012-06-20 16:38:30 -07008632#ifdef WLAN_BTAMP_FEATURE
8633 vosStatus = WLANBAP_Stop(pVosContext);
8634 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8635 {
8636 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8637 "%s: Failed to stop BAP",__func__);
8638 }
8639#endif //WLAN_BTAMP_FEATURE
8640
8641 //Stop all the modules
8642 vosStatus = vos_stop( pVosContext );
8643 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8644 {
8645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8646 "%s: Failed to stop VOSS",__func__);
8647 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8648 }
8649
Jeff Johnson295189b2012-06-20 16:38:30 -07008650 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008651 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008652
8653 //Close the scheduler before calling vos_close to make sure no thread is
8654 // scheduled after the each module close is called i.e after all the data
8655 // structures are freed.
8656 vosStatus = vos_sched_close( pVosContext );
8657 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8658 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8659 "%s: Failed to close VOSS Scheduler",__func__);
8660 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8661 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008662#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8663 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308664 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008665#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008666 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308667 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008668
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308669#ifdef CONFIG_ENABLE_LINUX_REG
8670 vosStatus = vos_nv_close();
8671 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8672 {
8673 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8674 "%s: Failed to close NV", __func__);
8675 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8676 }
8677#endif
8678
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 //Close VOSS
8680 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8681 vos_close(pVosContext);
8682
Jeff Johnson295189b2012-06-20 16:38:30 -07008683 //Close Watchdog
8684 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8685 vos_watchdog_close(pVosContext);
8686
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308687 //Clean up HDD Nlink Service
8688 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308689
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308690#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308691 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308692 {
8693 wlan_logging_sock_deactivate_svc();
8694 }
8695#endif
8696
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308697#ifdef WLAN_KD_READY_NOTIFIER
8698 nl_srv_exit(pHddCtx->ptt_pid);
8699#else
8700 nl_srv_exit();
8701#endif /* WLAN_KD_READY_NOTIFIER */
8702
8703
Jeff Johnson295189b2012-06-20 16:38:30 -07008704 hdd_close_all_adapters( pHddCtx );
8705
Jeff Johnson295189b2012-06-20 16:38:30 -07008706 /* free the power on lock from platform driver */
8707 if (free_riva_power_on_lock("wlan"))
8708 {
8709 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8710 __func__);
8711 }
8712
Jeff Johnson88ba7742013-02-27 14:36:02 -08008713free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308714
8715 //Free up dynamically allocated members inside HDD Adapter
8716 if (pHddCtx->cfg_ini)
8717 {
8718 kfree(pHddCtx->cfg_ini);
8719 pHddCtx->cfg_ini= NULL;
8720 }
8721
Leo Changf04ddad2013-09-18 13:46:38 -07008722 /* FTM mode, WIPHY did not registered
8723 If un-register here, system crash will happen */
8724 if (VOS_FTM_MODE != hdd_get_conparam())
8725 {
8726 wiphy_unregister(wiphy) ;
8727 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008729 if (hdd_is_ssr_required())
8730 {
8731 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008732 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 msleep(5000);
8734 }
8735 hdd_set_ssr_required (VOS_FALSE);
8736}
8737
8738
8739/**---------------------------------------------------------------------------
8740
8741 \brief hdd_update_config_from_nv() - Function to update the contents of
8742 the running configuration with parameters taken from NV storage
8743
8744 \param - pHddCtx - Pointer to the HDD global context
8745
8746 \return - VOS_STATUS_SUCCESS if successful
8747
8748 --------------------------------------------------------------------------*/
8749static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8750{
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 v_BOOL_t itemIsValid = VOS_FALSE;
8752 VOS_STATUS status;
8753 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8754 v_U8_t macLoop;
8755
8756 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8757 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8758 if(status != VOS_STATUS_SUCCESS)
8759 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008760 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008761 return VOS_STATUS_E_FAILURE;
8762 }
8763
8764 if (itemIsValid == VOS_TRUE)
8765 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008766 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008767 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8768 VOS_MAX_CONCURRENCY_PERSONA);
8769 if(status != VOS_STATUS_SUCCESS)
8770 {
8771 /* Get MAC from NV fail, not update CFG info
8772 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008773 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008774 return VOS_STATUS_E_FAILURE;
8775 }
8776
8777 /* If first MAC is not valid, treat all others are not valid
8778 * Then all MACs will be got from ini file */
8779 if(vos_is_macaddr_zero(&macFromNV[0]))
8780 {
8781 /* MAC address in NV file is not configured yet */
8782 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8783 return VOS_STATUS_E_INVAL;
8784 }
8785
8786 /* Get MAC address from NV, update CFG info */
8787 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8788 {
8789 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8790 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308791 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008792 /* This MAC is not valid, skip it
8793 * This MAC will be got from ini file */
8794 }
8795 else
8796 {
8797 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8798 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8799 VOS_MAC_ADDR_SIZE);
8800 }
8801 }
8802 }
8803 else
8804 {
8805 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8806 return VOS_STATUS_E_FAILURE;
8807 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008808
Jeff Johnson295189b2012-06-20 16:38:30 -07008809
8810 return VOS_STATUS_SUCCESS;
8811}
8812
8813/**---------------------------------------------------------------------------
8814
8815 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8816
8817 \param - pAdapter - Pointer to the HDD
8818
8819 \return - None
8820
8821 --------------------------------------------------------------------------*/
8822VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8823{
8824 eHalStatus halStatus;
8825 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308826 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008827
Jeff Johnson295189b2012-06-20 16:38:30 -07008828
8829 // Send ready indication to the HDD. This will kick off the MAC
8830 // into a 'running' state and should kick off an initial scan.
8831 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8832 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8833 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308834 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 "code %08d [x%08x]",__func__, halStatus, halStatus );
8836 return VOS_STATUS_E_FAILURE;
8837 }
8838
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308839 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008840 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8841 // And RIVA will crash
8842 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8843 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308844 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8845 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8846
8847
Jeff Johnson295189b2012-06-20 16:38:30 -07008848 return VOS_STATUS_SUCCESS;
8849}
8850
Jeff Johnson295189b2012-06-20 16:38:30 -07008851/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308852void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008853{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308854
8855 vos_wake_lock_acquire(&wlan_wake_lock, reason);
8856
Jeff Johnson295189b2012-06-20 16:38:30 -07008857}
8858
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308859void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -07008860{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308861
8862 vos_wake_lock_release(&wlan_wake_lock, reason);
8863
Jeff Johnson295189b2012-06-20 16:38:30 -07008864}
8865
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308866void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008867{
Sushant Kaushik83392fa2015-05-05 17:44:40 +05308868
8869 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
8870 reason);
8871
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008872}
8873
Jeff Johnson295189b2012-06-20 16:38:30 -07008874/**---------------------------------------------------------------------------
8875
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008876 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8877 information between Host and Riva
8878
8879 This function gets reported version of FW
8880 It also finds the version of Riva headers used to compile the host
8881 It compares the above two and prints a warning if they are different
8882 It gets the SW and HW version string
8883 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8884 indicating the features they support through a bitmap
8885
8886 \param - pHddCtx - Pointer to HDD context
8887
8888 \return - void
8889
8890 --------------------------------------------------------------------------*/
8891
8892void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8893{
8894
8895 tSirVersionType versionCompiled;
8896 tSirVersionType versionReported;
8897 tSirVersionString versionString;
8898 tANI_U8 fwFeatCapsMsgSupported = 0;
8899 VOS_STATUS vstatus;
8900
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008901 memset(&versionCompiled, 0, sizeof(versionCompiled));
8902 memset(&versionReported, 0, sizeof(versionReported));
8903
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008904 /* retrieve and display WCNSS version information */
8905 do {
8906
8907 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8908 &versionCompiled);
8909 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8910 {
8911 hddLog(VOS_TRACE_LEVEL_FATAL,
8912 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008913 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008914 break;
8915 }
8916
8917 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8918 &versionReported);
8919 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8920 {
8921 hddLog(VOS_TRACE_LEVEL_FATAL,
8922 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008923 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008924 break;
8925 }
8926
8927 if ((versionCompiled.major != versionReported.major) ||
8928 (versionCompiled.minor != versionReported.minor) ||
8929 (versionCompiled.version != versionReported.version) ||
8930 (versionCompiled.revision != versionReported.revision))
8931 {
8932 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8933 "Host expected %u.%u.%u.%u\n",
8934 WLAN_MODULE_NAME,
8935 (int)versionReported.major,
8936 (int)versionReported.minor,
8937 (int)versionReported.version,
8938 (int)versionReported.revision,
8939 (int)versionCompiled.major,
8940 (int)versionCompiled.minor,
8941 (int)versionCompiled.version,
8942 (int)versionCompiled.revision);
8943 }
8944 else
8945 {
8946 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8947 WLAN_MODULE_NAME,
8948 (int)versionReported.major,
8949 (int)versionReported.minor,
8950 (int)versionReported.version,
8951 (int)versionReported.revision);
8952 }
8953
8954 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8955 versionString,
8956 sizeof(versionString));
8957 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8958 {
8959 hddLog(VOS_TRACE_LEVEL_FATAL,
8960 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008961 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008962 break;
8963 }
8964
8965 pr_info("%s: WCNSS software version %s\n",
8966 WLAN_MODULE_NAME, versionString);
8967
8968 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8969 versionString,
8970 sizeof(versionString));
8971 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8972 {
8973 hddLog(VOS_TRACE_LEVEL_FATAL,
8974 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008975 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008976 break;
8977 }
8978
8979 pr_info("%s: WCNSS hardware version %s\n",
8980 WLAN_MODULE_NAME, versionString);
8981
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008982 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8983 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008984 send the message only if it the riva is 1.1
8985 minor numbers for different riva branches:
8986 0 -> (1.0)Mainline Build
8987 1 -> (1.1)Mainline Build
8988 2->(1.04) Stability Build
8989 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008990 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008991 ((versionReported.minor>=1) && (versionReported.version>=1)))
8992 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8993 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008994
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008995 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008996 {
8997#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8998 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8999 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
9000#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07009001 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
9002 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
9003 {
9004 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
9005 }
9006
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009007 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08009008 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009009
9010 } while (0);
9011
9012}
Neelansh Mittaledafed22014-09-04 18:54:39 +05309013void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
9014{
9015 struct sk_buff *skb;
9016 struct nlmsghdr *nlh;
9017 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309018 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05309019
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05309020 if (in_interrupt() || irqs_disabled() || in_atomic())
9021 flags = GFP_ATOMIC;
9022
9023 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05309024
9025 if(skb == NULL) {
9026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9027 "%s: alloc_skb failed", __func__);
9028 return;
9029 }
9030
9031 nlh = (struct nlmsghdr *)skb->data;
9032 nlh->nlmsg_pid = 0; /* from kernel */
9033 nlh->nlmsg_flags = 0;
9034 nlh->nlmsg_seq = 0;
9035 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
9036
9037 ani_hdr = NLMSG_DATA(nlh);
9038 ani_hdr->type = type;
9039
9040 switch(type) {
9041 case WLAN_SVC_SAP_RESTART_IND:
9042 ani_hdr->length = 0;
9043 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
9044 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
9045 break;
9046 default:
9047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9048 "Attempt to send unknown nlink message %d", type);
9049 kfree_skb(skb);
9050 return;
9051 }
9052
9053 nl_srv_bcast(skb);
9054
9055 return;
9056}
9057
9058
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009059
9060/**---------------------------------------------------------------------------
9061
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309062 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
9063
9064 \param - pHddCtx - Pointer to the hdd context
9065
9066 \return - true if hardware supports 5GHz
9067
9068 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309069boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309070{
9071 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
9072 * then hardware support 5Ghz.
9073 */
9074 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
9075 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309077 return true;
9078 }
9079 else
9080 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309082 __func__);
9083 return false;
9084 }
9085}
9086
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309087/**---------------------------------------------------------------------------
9088
9089 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
9090 generate function
9091
9092 This is generate the random mac address for WLAN interface
9093
9094 \param - pHddCtx - Pointer to HDD context
9095 idx - Start interface index to get auto
9096 generated mac addr.
9097 mac_addr - Mac address
9098
9099 \return - 0 for success, < 0 for failure
9100
9101 --------------------------------------------------------------------------*/
9102
9103static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
9104 int idx, v_MACADDR_t mac_addr)
9105{
9106 int i;
9107 unsigned int serialno;
9108 serialno = wcnss_get_serial_number();
9109
9110 if (0 != serialno)
9111 {
9112 /* MAC address has 3 bytes of OUI so we have a maximum of 3
9113 bytes of the serial number that can be used to generate
9114 the other 3 bytes of the MAC address. Mask off all but
9115 the lower 3 bytes (this will also make sure we don't
9116 overflow in the next step) */
9117 serialno &= 0x00FFFFFF;
9118
9119 /* we need a unique address for each session */
9120 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
9121
9122 /* autogen other Mac addresses */
9123 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
9124 {
9125 /* start with the entire default address */
9126 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
9127 /* then replace the lower 3 bytes */
9128 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
9129 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
9130 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
9131
9132 serialno++;
9133 hddLog(VOS_TRACE_LEVEL_ERROR,
9134 "%s: Derived Mac Addr: "
9135 MAC_ADDRESS_STR, __func__,
9136 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
9137 }
9138
9139 }
9140 else
9141 {
9142 hddLog(LOGE, FL("Failed to Get Serial NO"));
9143 return -1;
9144 }
9145 return 0;
9146}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309147
Katya Nigame7b69a82015-04-28 15:24:06 +05309148int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
9149{
9150 VOS_STATUS status;
9151 v_CONTEXT_t pVosContext= NULL;
9152 hdd_adapter_t *pAdapter= NULL;
9153
9154 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9155
9156 if (NULL == pVosContext)
9157 {
9158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9159 "%s: Trying to open VOSS without a PreOpen", __func__);
9160 VOS_ASSERT(0);
9161 return VOS_STATUS_E_FAILURE;
9162 }
9163
9164 status = vos_nv_open();
9165 if (!VOS_IS_STATUS_SUCCESS(status))
9166 {
9167 /* NV module cannot be initialized */
9168 hddLog( VOS_TRACE_LEVEL_FATAL,
9169 "%s: vos_nv_open failed", __func__);
9170 return VOS_STATUS_E_FAILURE;
9171 }
9172
9173 status = vos_init_wiphy_from_nv_bin();
9174 if (!VOS_IS_STATUS_SUCCESS(status))
9175 {
9176 /* NV module cannot be initialized */
9177 hddLog( VOS_TRACE_LEVEL_FATAL,
9178 "%s: vos_init_wiphy failed", __func__);
9179 goto err_vos_nv_close;
9180 }
9181
9182 status = vos_open( &pVosContext, pHddCtx->parent_dev);
9183 if ( !VOS_IS_STATUS_SUCCESS( status ))
9184 {
9185 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
9186 goto err_vos_nv_close;
9187 }
9188
9189 status = vos_mon_start( pVosContext );
9190 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9191 {
9192 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
9193 goto err_vosclose;
9194 }
9195
9196 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9197 WDA_featureCapsExchange(pVosContext);
9198 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9199
9200 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
9201 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9202 if( pAdapter == NULL )
9203 {
9204 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9205 goto err_close_adapter;
9206 }
9207
9208 //Initialize the nlink service
9209 if(nl_srv_init() != 0)
9210 {
9211 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
9212 goto err_close_adapter;
9213 }
9214 return VOS_STATUS_SUCCESS;
9215
9216err_close_adapter:
9217 hdd_close_all_adapters( pHddCtx );
9218 vos_mon_stop( pVosContext );
9219err_vosclose:
9220 status = vos_sched_close( pVosContext );
9221 if (!VOS_IS_STATUS_SUCCESS(status)) {
9222 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9223 "%s: Failed to close VOSS Scheduler", __func__);
9224 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9225 }
9226 vos_close(pVosContext );
9227
9228err_vos_nv_close:
9229 vos_nv_close();
9230
9231return status;
9232}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309233/**---------------------------------------------------------------------------
9234
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309235 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
9236 completed to flush out the scan results
9237
9238 11d scan is done during driver load and is a passive scan on all
9239 channels supported by the device, 11d scans may find some APs on
9240 frequencies which are forbidden to be used in the regulatory domain
9241 the device is operating in. If these APs are notified to the supplicant
9242 it may try to connect to these APs, thus flush out all the scan results
9243 which are present in SME after 11d scan is done.
9244
9245 \return - eHalStatus
9246
9247 --------------------------------------------------------------------------*/
9248static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
9249 tANI_U32 scanId, eCsrScanStatus status)
9250{
9251 ENTER();
9252
9253 sme_ScanFlushResult(halHandle, 0);
9254
9255 EXIT();
9256
9257 return eHAL_STATUS_SUCCESS;
9258}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309259/**---------------------------------------------------------------------------
9260
9261 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
9262 logging is completed successfully.
9263
9264 \return - None
9265
9266 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309267void hdd_init_frame_logging_done(void *fwlogInitCbContext, VOS_STATUS status)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309268{
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309269 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309270
9271 if (NULL == pHddCtx)
9272 {
9273 hddLog(VOS_TRACE_LEVEL_ERROR,
9274 "%s: HDD context is NULL",__func__);
9275 return;
9276 }
9277
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +05309278 if ((VOS_STATUS_SUCCESS == status) &&
9279 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309280 {
9281 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9282 pHddCtx->mgmt_frame_logging = TRUE;
9283 }
9284 else
9285 {
9286 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9287 pHddCtx->mgmt_frame_logging = FALSE;
9288 }
9289
9290 return;
9291}
9292/**---------------------------------------------------------------------------
9293
9294 \brief hdd_init_frame_logging - function to initialize frame logging.
9295 Currently only Mgmt Frames are logged in both TX
9296 and Rx direction and are sent to userspace
9297 application using logger thread when queried.
9298
9299 \return - None
9300
9301 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309302void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309303{
9304 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309305 tpSirFWLoggingInitParam wlanFWLoggingInitParam;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309306
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309307 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
9308 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309309 {
9310 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9311 return;
9312 }
9313
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309314 wlanFWLoggingInitParam = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
9315 if(NULL == wlanFWLoggingInitParam)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309316 {
9317 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9318 return;
9319 }
9320
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309321 vos_mem_set(wlanFWLoggingInitParam, sizeof(tSirFWLoggingInitParam), 0);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309322
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309323 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s Logging",__func__,
9324 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
9325 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
9326 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309327
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309328 if (pHddCtx->cfg_ini->enableFWLogging ||
9329 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309330 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309331 wlanFWLoggingInitParam->enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309332 }
9333
Sushant Kaushik46804902015-07-08 14:46:03 +05309334 if (pHddCtx->cfg_ini->enableMgmtLogging)
9335 {
9336 wlanFWLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9337 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309338 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9339 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309340 wlanFWLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309341 }
9342
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309343 wlanFWLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9344 wlanFWLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9345 wlanFWLoggingInitParam->bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9346 wlanFWLoggingInitParam->continuousFrameLogging =
9347 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309348
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309349 wlanFWLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309350
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309351 wlanFWLoggingInitParam->minLogBufferSize =
9352 pHddCtx->cfg_ini->minLoggingBufferSize;
9353 wlanFWLoggingInitParam->maxLogBufferSize =
9354 pHddCtx->cfg_ini->maxLoggingBufferSize;
9355 wlanFWLoggingInitParam->fwlogInitCallback = hdd_init_frame_logging_done;
9356 wlanFWLoggingInitParam->fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309357
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309358 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309359
9360 if (eHAL_STATUS_SUCCESS != halStatus)
9361 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +05309362 vos_mem_free(wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309363 }
9364
9365 return;
9366}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309367
9368/**---------------------------------------------------------------------------
9369
Jeff Johnson295189b2012-06-20 16:38:30 -07009370 \brief hdd_wlan_startup() - HDD init function
9371
9372 This is the driver startup code executed once a WLAN device has been detected
9373
9374 \param - dev - Pointer to the underlying device
9375
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009376 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009377
9378 --------------------------------------------------------------------------*/
9379
9380int hdd_wlan_startup(struct device *dev )
9381{
9382 VOS_STATUS status;
9383 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009384 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 hdd_context_t *pHddCtx = NULL;
9386 v_CONTEXT_t pVosContext= NULL;
9387#ifdef WLAN_BTAMP_FEATURE
9388 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9389 WLANBAP_ConfigType btAmpConfig;
9390 hdd_config_t *pConfig;
9391#endif
9392 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009393 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309394 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009395
9396 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 /*
9398 * cfg80211: wiphy allocation
9399 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309400 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009401
9402 if(wiphy == NULL)
9403 {
9404 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009405 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009406 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 pHddCtx = wiphy_priv(wiphy);
9408
Jeff Johnson295189b2012-06-20 16:38:30 -07009409 //Initialize the adapter context to zeros.
9410 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9411
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +05309413 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +05309414 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009415
9416 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9417
Siddharth Bhalcd92b782015-06-29 12:25:40 +05309418 /* register for riva power on lock to platform driver
9419 * Locking power early to ensure FW doesn't reset by kernel while
9420 * host driver is busy initializing itself */
9421 if (req_riva_power_on_lock("wlan"))
9422 {
9423 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9424 __func__);
9425 goto err_free_hdd_context;
9426 }
9427
Jeff Johnson295189b2012-06-20 16:38:30 -07009428 /*Get vos context here bcoz vos_open requires it*/
9429 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9430
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009431 if(pVosContext == NULL)
9432 {
9433 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9434 goto err_free_hdd_context;
9435 }
9436
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 //Save the Global VOSS context in adapter context for future.
9438 pHddCtx->pvosContext = pVosContext;
9439
9440 //Save the adapter context in global context for future.
9441 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9442
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 pHddCtx->parent_dev = dev;
9444
9445 init_completion(&pHddCtx->full_pwr_comp_var);
9446 init_completion(&pHddCtx->standby_comp_var);
9447 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009448 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009449 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309450 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309451 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009452
9453#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009454 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009455#else
9456 init_completion(&pHddCtx->driver_crda_req);
9457#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009458
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309459 spin_lock_init(&pHddCtx->schedScan_lock);
9460
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9462
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309463#ifdef FEATURE_WLAN_TDLS
9464 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9465 * invoked by other instances also) to protect the concurrent
9466 * access for the Adapters by TDLS module.
9467 */
9468 mutex_init(&pHddCtx->tdls_lock);
9469#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309470 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309471 mutex_init(&pHddCtx->wmmLock);
9472
Agarwal Ashish1f422872014-07-22 00:11:55 +05309473 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309474
Agarwal Ashish1f422872014-07-22 00:11:55 +05309475 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 // Load all config first as TL config is needed during vos_open
9477 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9478 if(pHddCtx->cfg_ini == NULL)
9479 {
9480 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9481 goto err_free_hdd_context;
9482 }
9483
9484 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9485
9486 // Read and parse the qcom_cfg.ini file
9487 status = hdd_parse_config_ini( pHddCtx );
9488 if ( VOS_STATUS_SUCCESS != status )
9489 {
9490 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9491 __func__, WLAN_INI_FILE);
9492 goto err_config;
9493 }
Arif Hussaind5218912013-12-05 01:10:55 -08009494#ifdef MEMORY_DEBUG
9495 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9496 vos_mem_init();
9497
9498 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9499 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9500#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009501
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309502 /* INI has been read, initialise the configuredMcastBcastFilter with
9503 * INI value as this will serve as the default value
9504 */
9505 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9506 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9507 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309508
9509 if (false == hdd_is_5g_supported(pHddCtx))
9510 {
9511 //5Ghz is not supported.
9512 if (1 != pHddCtx->cfg_ini->nBandCapability)
9513 {
9514 hddLog(VOS_TRACE_LEVEL_INFO,
9515 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9516 pHddCtx->cfg_ini->nBandCapability = 1;
9517 }
9518 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309519
9520 /* If SNR Monitoring is enabled, FW has to parse all beacons
9521 * for calcaluting and storing the average SNR, so set Nth beacon
9522 * filter to 1 to enable FW to parse all the beaocons
9523 */
9524 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9525 {
9526 /* The log level is deliberately set to WARN as overriding
9527 * nthBeaconFilter to 1 will increase power cosumption and this
9528 * might just prove helpful to detect the power issue.
9529 */
9530 hddLog(VOS_TRACE_LEVEL_WARN,
9531 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9532 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9533 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009534 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309535 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009537 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009539 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9540 {
9541 hddLog(VOS_TRACE_LEVEL_FATAL,
9542 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9543 goto err_config;
9544 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009546
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009547 // Update VOS trace levels based upon the cfg.ini
9548 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9549 pHddCtx->cfg_ini->vosTraceEnableBAP);
9550 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9551 pHddCtx->cfg_ini->vosTraceEnableTL);
9552 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9553 pHddCtx->cfg_ini->vosTraceEnableWDI);
9554 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9555 pHddCtx->cfg_ini->vosTraceEnableHDD);
9556 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9557 pHddCtx->cfg_ini->vosTraceEnableSME);
9558 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9559 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309560 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9561 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009562 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9563 pHddCtx->cfg_ini->vosTraceEnableWDA);
9564 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9565 pHddCtx->cfg_ini->vosTraceEnableSYS);
9566 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9567 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009568 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9569 pHddCtx->cfg_ini->vosTraceEnableSAP);
9570 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9571 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009572
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 // Update WDI trace levels based upon the cfg.ini
9574 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9575 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9576 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9577 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9578 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9579 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9580 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9581 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009582
Jeff Johnson88ba7742013-02-27 14:36:02 -08009583 if (VOS_FTM_MODE == hdd_get_conparam())
9584 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9586 {
9587 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9588 goto err_free_hdd_context;
9589 }
9590 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309591 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309592 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009594 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009595
Katya Nigame7b69a82015-04-28 15:24:06 +05309596 if( VOS_MONITOR_MODE == hdd_get_conparam())
9597 {
9598 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
9599 {
9600 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
9601 goto err_free_hdd_context;
9602 }
9603 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
9604 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
9605 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9606 return VOS_STATUS_SUCCESS;
9607 }
9608
Jeff Johnson88ba7742013-02-27 14:36:02 -08009609 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9611 {
9612 status = vos_watchdog_open(pVosContext,
9613 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9614
9615 if(!VOS_IS_STATUS_SUCCESS( status ))
9616 {
9617 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309618 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 }
9620 }
9621
9622 pHddCtx->isLogpInProgress = FALSE;
9623 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9624
Amar Singhala49cbc52013-10-08 18:37:44 -07009625#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009626 /* initialize the NV module. This is required so that
9627 we can initialize the channel information in wiphy
9628 from the NV.bin data. The channel information in
9629 wiphy needs to be initialized before wiphy registration */
9630
9631 status = vos_nv_open();
9632 if (!VOS_IS_STATUS_SUCCESS(status))
9633 {
9634 /* NV module cannot be initialized */
9635 hddLog( VOS_TRACE_LEVEL_FATAL,
9636 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309637 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009638 }
9639
9640 status = vos_init_wiphy_from_nv_bin();
9641 if (!VOS_IS_STATUS_SUCCESS(status))
9642 {
9643 /* NV module cannot be initialized */
9644 hddLog( VOS_TRACE_LEVEL_FATAL,
9645 "%s: vos_init_wiphy failed", __func__);
9646 goto err_vos_nv_close;
9647 }
9648
Amar Singhala49cbc52013-10-08 18:37:44 -07009649#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309650 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309651 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 if ( !VOS_IS_STATUS_SUCCESS( status ))
9653 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009654 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309655 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 }
9657
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9659
9660 if ( NULL == pHddCtx->hHal )
9661 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009662 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 goto err_vosclose;
9664 }
9665
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009666 status = vos_preStart( pHddCtx->pvosContext );
9667 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9668 {
9669 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309670 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009671 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009672
Arif Hussaineaf68602013-12-30 23:10:44 -08009673 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9674 {
9675 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9676 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9677 __func__, enable_dfs_chan_scan);
9678 }
9679 if (0 == enable_11d || 1 == enable_11d)
9680 {
9681 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9682 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9683 __func__, enable_11d);
9684 }
9685
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009686 /* Note that the vos_preStart() sequence triggers the cfg download.
9687 The cfg download must occur before we update the SME config
9688 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009689 status = hdd_set_sme_config( pHddCtx );
9690
9691 if ( VOS_STATUS_SUCCESS != status )
9692 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009693 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309694 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009695 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009696
Jeff Johnson295189b2012-06-20 16:38:30 -07009697 /* In the integrated architecture we update the configuration from
9698 the INI file and from NV before vOSS has been started so that
9699 the final contents are available to send down to the cCPU */
9700
9701 // Apply the cfg.ini to cfg.dat
9702 if (FALSE == hdd_update_config_dat(pHddCtx))
9703 {
9704 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309705 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 }
9707
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309708 // Get mac addr from platform driver
9709 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9710
9711 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309713 /* Store the mac addr for first interface */
9714 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9715
9716 hddLog(VOS_TRACE_LEVEL_ERROR,
9717 "%s: WLAN Mac Addr: "
9718 MAC_ADDRESS_STR, __func__,
9719 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9720
9721 /* Here, passing Arg2 as 1 because we do not want to change the
9722 last 3 bytes (means non OUI bytes) of first interface mac
9723 addr.
9724 */
9725 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9726 {
9727 hddLog(VOS_TRACE_LEVEL_ERROR,
9728 "%s: Failed to generate wlan interface mac addr "
9729 "using MAC from ini file ", __func__);
9730 }
9731 }
9732 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9733 {
9734 // Apply the NV to cfg.dat
9735 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009736#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9737 /* There was not a valid set of MAC Addresses in NV. See if the
9738 default addresses were modified by the cfg.ini settings. If so,
9739 we'll use them, but if not, we'll autogenerate a set of MAC
9740 addresses based upon the device serial number */
9741
9742 static const v_MACADDR_t default_address =
9743 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009744
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309745 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9746 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009747 {
9748 /* cfg.ini has the default address, invoke autogen logic */
9749
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309750 /* Here, passing Arg2 as 0 because we want to change the
9751 last 3 bytes (means non OUI bytes) of all the interfaces
9752 mac addr.
9753 */
9754 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9755 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309757 hddLog(VOS_TRACE_LEVEL_ERROR,
9758 "%s: Failed to generate wlan interface mac addr "
9759 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9760 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 }
9763 else
9764#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9765 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009766 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 "%s: Invalid MAC address in NV, using MAC from ini file "
9768 MAC_ADDRESS_STR, __func__,
9769 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9770 }
9771 }
9772 {
9773 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309774
9775 /* Set the MAC Address Currently this is used by HAL to
9776 * add self sta. Remove this once self sta is added as
9777 * part of session open.
9778 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9780 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9781 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309782
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 if (!HAL_STATUS_SUCCESS( halStatus ))
9784 {
9785 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9786 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309787 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009788 }
9789 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009790
9791 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9792 Note: Firmware image will be read and downloaded inside vos_start API */
9793 status = vos_start( pHddCtx->pvosContext );
9794 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9795 {
9796 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309797 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009798 }
9799
Leo Chang6cec3e22014-01-21 15:33:49 -08009800#ifdef FEATURE_WLAN_CH_AVOID
9801 /* Plug in avoid channel notification callback
9802 * This should happen before ADD_SELF_STA
9803 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309804
9805 /* check the Channel Avoidance is enabled */
9806 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9807 {
9808 sme_AddChAvoidCallback(pHddCtx->hHal,
9809 hdd_hostapd_ch_avoid_cb);
9810 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009811#endif /* FEATURE_WLAN_CH_AVOID */
9812
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009813 /* Exchange capability info between Host and FW and also get versioning info from FW */
9814 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009815
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309816#ifdef CONFIG_ENABLE_LINUX_REG
9817 status = wlan_hdd_init_channels(pHddCtx);
9818 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9819 {
9820 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9821 __func__);
9822 goto err_vosstop;
9823 }
9824#endif
9825
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 status = hdd_post_voss_start_config( pHddCtx );
9827 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9828 {
9829 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9830 __func__);
9831 goto err_vosstop;
9832 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009833
9834#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309835 wlan_hdd_cfg80211_update_reg_info( wiphy );
9836
9837 /* registration of wiphy dev with cfg80211 */
9838 if (0 > wlan_hdd_cfg80211_register(wiphy))
9839 {
9840 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9841 goto err_vosstop;
9842 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009843#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009844
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309845#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309846 /* registration of wiphy dev with cfg80211 */
9847 if (0 > wlan_hdd_cfg80211_register(wiphy))
9848 {
9849 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9850 goto err_vosstop;
9851 }
9852
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309853 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309854 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9855 {
9856 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9857 __func__);
9858 goto err_unregister_wiphy;
9859 }
9860#endif
9861
c_hpothu4a298be2014-12-22 21:12:51 +05309862 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9863
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9865 {
9866 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9867 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9868 }
9869 else
9870 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9872 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9873 if (pAdapter != NULL)
9874 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309875 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309877 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9878 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9879 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009880
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309881 /* Generate the P2P Device Address. This consists of the device's
9882 * primary MAC address with the locally administered bit set.
9883 */
9884 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009885 }
9886 else
9887 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309888 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9889 if (p2p_dev_addr != NULL)
9890 {
9891 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9892 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9893 }
9894 else
9895 {
9896 hddLog(VOS_TRACE_LEVEL_FATAL,
9897 "%s: Failed to allocate mac_address for p2p_device",
9898 __func__);
9899 goto err_close_adapter;
9900 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009902
9903 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9904 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9905 if ( NULL == pP2pAdapter )
9906 {
9907 hddLog(VOS_TRACE_LEVEL_FATAL,
9908 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009909 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009910 goto err_close_adapter;
9911 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009912 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009914
9915 if( pAdapter == NULL )
9916 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9918 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009919 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009920
Arif Hussain66559122013-11-21 10:11:40 -08009921 if (country_code)
9922 {
9923 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009924 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009925 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9926#ifndef CONFIG_ENABLE_LINUX_REG
9927 hdd_checkandupdate_phymode(pAdapter, country_code);
9928#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009929 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9930 (void *)(tSmeChangeCountryCallback)
9931 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009932 country_code,
9933 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309934 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009935 if (eHAL_STATUS_SUCCESS == ret)
9936 {
Arif Hussaincb607082013-12-20 11:57:42 -08009937 ret = wait_for_completion_interruptible_timeout(
9938 &pAdapter->change_country_code,
9939 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9940
9941 if (0 >= ret)
9942 {
9943 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9944 "%s: SME while setting country code timed out", __func__);
9945 }
Arif Hussain66559122013-11-21 10:11:40 -08009946 }
9947 else
9948 {
Arif Hussaincb607082013-12-20 11:57:42 -08009949 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9950 "%s: SME Change Country code from module param fail ret=%d",
9951 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009952 }
9953 }
9954
Jeff Johnson295189b2012-06-20 16:38:30 -07009955#ifdef WLAN_BTAMP_FEATURE
9956 vStatus = WLANBAP_Open(pVosContext);
9957 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9958 {
9959 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9960 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009961 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 }
9963
9964 vStatus = BSL_Init(pVosContext);
9965 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9966 {
9967 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9968 "%s: Failed to Init BSL",__func__);
9969 goto err_bap_close;
9970 }
9971 vStatus = WLANBAP_Start(pVosContext);
9972 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9973 {
9974 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9975 "%s: Failed to start TL",__func__);
9976 goto err_bap_close;
9977 }
9978
9979 pConfig = pHddCtx->cfg_ini;
9980 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9981 status = WLANBAP_SetConfig(&btAmpConfig);
9982
9983#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009984
Mihir Shete9c238772014-10-15 14:35:16 +05309985 /*
9986 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9987 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9988 * which is greater than 0xf. So the below check is safe to make
9989 * sure that there is no entry for UapsdMask in the ini
9990 */
9991 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9992 {
9993 if(IS_DYNAMIC_WMM_PS_ENABLED)
9994 {
9995 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9996 __func__);
9997 pHddCtx->cfg_ini->UapsdMask =
9998 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9999 }
10000 else
10001 {
10002 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
10003 __func__);
10004 pHddCtx->cfg_ini->UapsdMask =
10005 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
10006 }
10007 }
10008
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070010009#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
10010 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
10011 {
10012 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
10013 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
10014 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
10015 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
10016 }
10017#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010018
Agarwal Ashish4b87f922014-06-18 03:03:21 +053010019 wlan_hdd_tdls_init(pHddCtx);
10020
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053010021 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
10022
Jeff Johnson295189b2012-06-20 16:38:30 -070010023 /* Register with platform driver as client for Suspend/Resume */
10024 status = hddRegisterPmOps(pHddCtx);
10025 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10026 {
10027 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
10028#ifdef WLAN_BTAMP_FEATURE
10029 goto err_bap_stop;
10030#else
Jeff Johnsone7245742012-09-05 17:12:55 -070010031 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010032#endif //WLAN_BTAMP_FEATURE
10033 }
10034
Yue Ma0d4891e2013-08-06 17:01:45 -070010035 /* Open debugfs interface */
10036 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
10037 {
10038 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10039 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070010040 }
10041
Jeff Johnson295189b2012-06-20 16:38:30 -070010042 /* Register TM level change handler function to the platform */
10043 status = hddDevTmRegisterNotifyCallback(pHddCtx);
10044 if ( !VOS_IS_STATUS_SUCCESS( status ) )
10045 {
10046 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
10047 goto err_unregister_pmops;
10048 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010049
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 // register net device notifier for device change notification
10051 ret = register_netdevice_notifier(&hdd_netdev_notifier);
10052
10053 if(ret < 0)
10054 {
10055 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010056 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 }
10058
10059 //Initialize the nlink service
10060 if(nl_srv_init() != 0)
10061 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010062 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010063 goto err_reg_netdev;
10064 }
10065
Leo Chang4ce1cc52013-10-21 18:27:15 -070010066#ifdef WLAN_KD_READY_NOTIFIER
10067 pHddCtx->kd_nl_init = 1;
10068#endif /* WLAN_KD_READY_NOTIFIER */
10069
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 //Initialize the BTC service
10071 if(btc_activate_service(pHddCtx) != 0)
10072 {
10073 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
10074 goto err_nl_srv;
10075 }
10076
10077#ifdef PTT_SOCK_SVC_ENABLE
10078 //Initialize the PTT service
10079 if(ptt_sock_activate_svc(pHddCtx) != 0)
10080 {
10081 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
10082 goto err_nl_srv;
10083 }
10084#endif
10085
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010086#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10087 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
10088 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053010089 if(wlan_logging_sock_activate_svc(
10090 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
10091 pHddCtx->cfg_ini->wlanLoggingNumBuf))
10092 {
10093 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
10094 " failed", __func__);
10095 goto err_nl_srv;
10096 }
10097 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
10098 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053010099 if (!pHddCtx->cfg_ini->gEnableDebugLog)
10100 pHddCtx->cfg_ini->gEnableDebugLog =
10101 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010102 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010103
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010104 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
10105 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053010106 pHddCtx->cfg_ini->enableMgmtLogging ||
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010107 pHddCtx->cfg_ini->enableContFWLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010108 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010109 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010110 }
10111 else
10112 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053010113 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010114 }
10115
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010116#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053010117
10118
Sushant Kaushik215778f2015-05-21 14:05:36 +053010119 if (vos_is_multicast_logging())
10120 wlan_logging_set_log_level();
10121
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070010125 /* Action frame registered in one adapter which will
10126 * applicable to all interfaces
10127 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053010128 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010129 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010130
10131 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053010132 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010133
Jeff Johnsone7245742012-09-05 17:12:55 -070010134#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10135 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010136 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070010137 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010138
Jeff Johnsone7245742012-09-05 17:12:55 -070010139#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010140 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010141 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010142 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010143
Jeff Johnsone7245742012-09-05 17:12:55 -070010144
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010145 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
10146 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010147
Katya Nigam5c306ea2014-06-19 15:39:54 +053010148 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010149 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010150 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053010151
10152#ifdef FEATURE_WLAN_SCAN_PNO
10153 /*SME must send channel update configuration to RIVA*/
10154 sme_UpdateChannelConfig(pHddCtx->hHal);
10155#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053010156 /* Send the update default channel list to the FW*/
10157 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053010158
10159 /* Fwr capabilities received, Set the Dot11 mode */
10160 sme_SetDefDot11Mode(pHddCtx->hHal);
10161
Abhishek Singha306a442013-11-07 18:39:01 +053010162#ifndef CONFIG_ENABLE_LINUX_REG
10163 /*updating wiphy so that regulatory user hints can be processed*/
10164 if (wiphy)
10165 {
10166 regulatory_hint(wiphy, "00");
10167 }
10168#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010169 // Initialize the restart logic
10170 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053010171
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010172 //Register the traffic monitor timer now
10173 if ( pHddCtx->cfg_ini->dynSplitscan)
10174 {
10175 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
10176 VOS_TIMER_TYPE_SW,
10177 hdd_tx_rx_pkt_cnt_stat_timer_handler,
10178 (void *)pHddCtx);
10179 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053010180 wlan_hdd_cfg80211_nan_init(pHddCtx);
10181
Dino Mycle6fb96c12014-06-10 11:52:40 +053010182#ifdef WLAN_FEATURE_EXTSCAN
10183 sme_EXTScanRegisterCallback(pHddCtx->hHal,
10184 wlan_hdd_cfg80211_extscan_callback,
10185 pHddCtx);
10186#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010187
10188#ifdef WLAN_NS_OFFLOAD
10189 // Register IPv6 notifier to notify if any change in IP
10190 // So that we can reconfigure the offload parameters
10191 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
10192 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10193 if (ret)
10194 {
10195 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
10196 }
10197 else
10198 {
10199 hddLog(LOGE, FL("Registered IPv6 notifier"));
10200 }
10201#endif
10202
10203 // Register IPv4 notifier to notify if any change in IP
10204 // So that we can reconfigure the offload parameters
10205 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
10206 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10207 if (ret)
10208 {
10209 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
10210 }
10211 else
10212 {
10213 hddLog(LOGE, FL("Registered IPv4 notifier"));
10214 }
10215
Jeff Johnson295189b2012-06-20 16:38:30 -070010216 goto success;
10217
10218err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -070010219#ifdef WLAN_KD_READY_NOTIFIER
10220 nl_srv_exit(pHddCtx->ptt_pid);
10221#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010222 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -070010223#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -070010224err_reg_netdev:
10225 unregister_netdevice_notifier(&hdd_netdev_notifier);
10226
Jeff Johnson295189b2012-06-20 16:38:30 -070010227err_unregister_pmops:
10228 hddDevTmUnregisterNotifyCallback(pHddCtx);
10229 hddDeregisterPmOps(pHddCtx);
10230
Yue Ma0d4891e2013-08-06 17:01:45 -070010231 hdd_debugfs_exit(pHddCtx);
10232
Jeff Johnson295189b2012-06-20 16:38:30 -070010233#ifdef WLAN_BTAMP_FEATURE
10234err_bap_stop:
10235 WLANBAP_Stop(pVosContext);
10236#endif
10237
10238#ifdef WLAN_BTAMP_FEATURE
10239err_bap_close:
10240 WLANBAP_Close(pVosContext);
10241#endif
10242
Jeff Johnson295189b2012-06-20 16:38:30 -070010243err_close_adapter:
10244 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010245#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010246err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053010247#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053010248 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010249err_vosstop:
10250 vos_stop(pVosContext);
10251
Amar Singhala49cbc52013-10-08 18:37:44 -070010252err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070010253 status = vos_sched_close( pVosContext );
10254 if (!VOS_IS_STATUS_SUCCESS(status)) {
10255 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10256 "%s: Failed to close VOSS Scheduler", __func__);
10257 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
10258 }
Amar Singhala49cbc52013-10-08 18:37:44 -070010259 vos_close(pVosContext );
10260
Amar Singhal0a402232013-10-11 20:57:16 -070010261err_vos_nv_close:
10262
c_hpothue6a36282014-03-19 12:27:38 +053010263#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070010264 vos_nv_close();
10265
c_hpothu70f8d812014-03-22 22:59:23 +053010266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010267
10268err_wdclose:
10269 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10270 vos_watchdog_close(pVosContext);
10271
Jeff Johnson295189b2012-06-20 16:38:30 -070010272err_config:
10273 kfree(pHddCtx->cfg_ini);
10274 pHddCtx->cfg_ini= NULL;
10275
10276err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010277 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053010278 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010279 wiphy_free(wiphy) ;
10280 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010281 VOS_BUG(1);
10282
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080010283 if (hdd_is_ssr_required())
10284 {
10285 /* WDI timeout had happened during load, so SSR is needed here */
10286 subsystem_restart("wcnss");
10287 msleep(5000);
10288 }
10289 hdd_set_ssr_required (VOS_FALSE);
10290
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010291 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010292
10293success:
10294 EXIT();
10295 return 0;
10296}
10297
10298/**---------------------------------------------------------------------------
10299
Jeff Johnson32d95a32012-09-10 13:15:23 -070010300 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070010301
Jeff Johnson32d95a32012-09-10 13:15:23 -070010302 This is the driver entry point - called in different timeline depending
10303 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010304
10305 \param - None
10306
10307 \return - 0 for success, non zero for failure
10308
10309 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010310static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010311{
10312 VOS_STATUS status;
10313 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010314 struct device *dev = NULL;
10315 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010316#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10317 int max_retries = 0;
10318#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010319#ifdef HAVE_CBC_DONE
10320 int max_cbc_retries = 0;
10321#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010322
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010323#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10324 wlan_logging_sock_init_svc();
10325#endif
10326
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 ENTER();
10328
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010329 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070010330
10331 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10332 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10333
Jeff Johnson295189b2012-06-20 16:38:30 -070010334#ifdef ANI_BUS_TYPE_PCI
10335
10336 dev = wcnss_wlan_get_device();
10337
10338#endif // ANI_BUS_TYPE_PCI
10339
10340#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010341
10342#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10343 /* wait until WCNSS driver downloads NV */
10344 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10345 msleep(1000);
10346 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010347
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010348 if (max_retries >= 5) {
10349 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010350 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010351#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10352 wlan_logging_sock_deinit_svc();
10353#endif
10354
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010355 return -ENODEV;
10356 }
10357#endif
10358
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010359#ifdef HAVE_CBC_DONE
10360 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10361 msleep(1000);
10362 }
10363 if (max_cbc_retries >= 10) {
10364 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10365 }
10366#endif
10367
Jeff Johnson295189b2012-06-20 16:38:30 -070010368 dev = wcnss_wlan_get_device();
10369#endif // ANI_BUS_TYPE_PLATFORM
10370
10371
10372 do {
10373 if (NULL == dev) {
10374 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10375 ret_status = -1;
10376 break;
10377 }
10378
Jeff Johnson295189b2012-06-20 16:38:30 -070010379#ifdef TIMER_MANAGER
10380 vos_timer_manager_init();
10381#endif
10382
10383 /* Preopen VOSS so that it is ready to start at least SAL */
10384 status = vos_preOpen(&pVosContext);
10385
10386 if (!VOS_IS_STATUS_SUCCESS(status))
10387 {
10388 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10389 ret_status = -1;
10390 break;
10391 }
10392
Sushant Kaushik02beb352015-06-04 15:15:01 +053010393 hddTraceInit();
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010394#ifndef MODULE
10395 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10396 */
10397 hdd_set_conparam((v_UINT_t)con_mode);
10398#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010399
10400 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010401 if (hdd_wlan_startup(dev))
10402 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010404 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010405 vos_preClose( &pVosContext );
10406 ret_status = -1;
10407 break;
10408 }
10409
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 } while (0);
10411
10412 if (0 != ret_status)
10413 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010414#ifdef TIMER_MANAGER
10415 vos_timer_exit();
10416#endif
10417#ifdef MEMORY_DEBUG
10418 vos_mem_exit();
10419#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010420 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010421#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10422 wlan_logging_sock_deinit_svc();
10423#endif
10424
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10426 }
10427 else
10428 {
10429 //Send WLAN UP indication to Nlink Service
10430 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10431
10432 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010433 }
10434
10435 EXIT();
10436
10437 return ret_status;
10438}
10439
Jeff Johnson32d95a32012-09-10 13:15:23 -070010440/**---------------------------------------------------------------------------
10441
10442 \brief hdd_module_init() - Init Function
10443
10444 This is the driver entry point (invoked when module is loaded using insmod)
10445
10446 \param - None
10447
10448 \return - 0 for success, non zero for failure
10449
10450 --------------------------------------------------------------------------*/
10451#ifdef MODULE
10452static int __init hdd_module_init ( void)
10453{
10454 return hdd_driver_init();
10455}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010456#else /* #ifdef MODULE */
10457static int __init hdd_module_init ( void)
10458{
10459 /* Driver initialization is delayed to fwpath_changed_handler */
10460 return 0;
10461}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010462#endif /* #ifdef MODULE */
10463
Jeff Johnson295189b2012-06-20 16:38:30 -070010464
10465/**---------------------------------------------------------------------------
10466
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010467 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010468
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010469 This is the driver exit point (invoked when module is unloaded using rmmod
10470 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010471
10472 \param - None
10473
10474 \return - None
10475
10476 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010477static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010478{
10479 hdd_context_t *pHddCtx = NULL;
10480 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010481 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010482 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010483
10484 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10485
10486 //Get the global vos context
10487 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10488
10489 if(!pVosContext)
10490 {
10491 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10492 goto done;
10493 }
10494
10495 //Get the HDD context.
10496 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10497
10498 if(!pHddCtx)
10499 {
10500 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10501 }
Katya Nigame7b69a82015-04-28 15:24:06 +053010502 else if (VOS_MONITOR_MODE == hdd_get_conparam())
10503 {
10504 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
10505 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10506 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
10507 hdd_wlan_exit(pHddCtx);
10508 vos_preClose( &pVosContext );
10509 goto done;
10510 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010511 else
10512 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010513 /* We wait for active entry threads to exit from driver
10514 * by waiting until rtnl_lock is available.
10515 */
10516 rtnl_lock();
10517 rtnl_unlock();
10518
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010519 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10520 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10521 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10522 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010524 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010525 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10526 msecs_to_jiffies(30000));
10527 if(!rc)
10528 {
10529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10530 "%s:SSR timedout, fatal error", __func__);
10531 VOS_BUG(0);
10532 }
10533 }
10534
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010535 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10536 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010537
c_hpothu8adb97b2014-12-08 19:38:20 +053010538 /* Driver Need to send country code 00 in below condition
10539 * 1) If gCountryCodePriority is set to 1; and last country
10540 * code set is through 11d. This needs to be done in case
10541 * when NV country code is 00.
10542 * This Needs to be done as when kernel store last country
10543 * code and if stored country code is not through 11d,
10544 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10545 * in next load/unload as soon as we get any country through
10546 * 11d. In sme_HandleChangeCountryCodeByUser
10547 * pMsg->countryCode will be last countryCode and
10548 * pMac->scan.countryCode11d will be country through 11d so
10549 * due to mismatch driver will disable 11d.
10550 *
10551 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010552
c_hpothu8adb97b2014-12-08 19:38:20 +053010553 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010554 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010555 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010556 {
10557 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010558 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010559 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10560 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010561
c_hpothu8adb97b2014-12-08 19:38:20 +053010562 //Do all the cleanup before deregistering the driver
10563 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 }
10565
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 vos_preClose( &pVosContext );
10567
10568#ifdef TIMER_MANAGER
10569 vos_timer_exit();
10570#endif
10571#ifdef MEMORY_DEBUG
10572 vos_mem_exit();
10573#endif
10574
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010575#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10576 wlan_logging_sock_deinit_svc();
10577#endif
10578
Jeff Johnson295189b2012-06-20 16:38:30 -070010579done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010580 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010581
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10583}
10584
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010585/**---------------------------------------------------------------------------
10586
10587 \brief hdd_module_exit() - Exit function
10588
10589 This is the driver exit point (invoked when module is unloaded using rmmod)
10590
10591 \param - None
10592
10593 \return - None
10594
10595 --------------------------------------------------------------------------*/
10596static void __exit hdd_module_exit(void)
10597{
10598 hdd_driver_exit();
10599}
10600
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010601#ifdef MODULE
10602static int fwpath_changed_handler(const char *kmessage,
10603 struct kernel_param *kp)
10604{
Jeff Johnson76052702013-04-16 13:55:05 -070010605 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010606}
10607
10608static int con_mode_handler(const char *kmessage,
10609 struct kernel_param *kp)
10610{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010611 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010612}
10613#else /* #ifdef MODULE */
10614/**---------------------------------------------------------------------------
10615
Jeff Johnson76052702013-04-16 13:55:05 -070010616 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010617
Jeff Johnson76052702013-04-16 13:55:05 -070010618 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010619 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010620 - invoked when module parameter fwpath is modified from userspace to signal
10621 initializing the WLAN driver or when con_mode is modified from userspace
10622 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010623
10624 \return - 0 for success, non zero for failure
10625
10626 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010627static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010628{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010629 int ret_status;
10630
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010631 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010632 ret_status = hdd_driver_init();
10633 wlan_hdd_inited = ret_status ? 0 : 1;
10634 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010635 }
10636
10637 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010638
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010639 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010640
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010641 ret_status = hdd_driver_init();
10642 wlan_hdd_inited = ret_status ? 0 : 1;
10643 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010644}
10645
Jeff Johnson295189b2012-06-20 16:38:30 -070010646/**---------------------------------------------------------------------------
10647
Jeff Johnson76052702013-04-16 13:55:05 -070010648 \brief fwpath_changed_handler() - Handler Function
10649
10650 Handle changes to the fwpath parameter
10651
10652 \return - 0 for success, non zero for failure
10653
10654 --------------------------------------------------------------------------*/
10655static int fwpath_changed_handler(const char *kmessage,
10656 struct kernel_param *kp)
10657{
10658 int ret;
10659
10660 ret = param_set_copystring(kmessage, kp);
10661 if (0 == ret)
10662 ret = kickstart_driver();
10663 return ret;
10664}
10665
10666/**---------------------------------------------------------------------------
10667
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010668 \brief con_mode_handler() -
10669
10670 Handler function for module param con_mode when it is changed by userspace
10671 Dynamically linked - do nothing
10672 Statically linked - exit and init driver, as in rmmod and insmod
10673
Jeff Johnson76052702013-04-16 13:55:05 -070010674 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010675
Jeff Johnson76052702013-04-16 13:55:05 -070010676 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010677
10678 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010679static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010680{
Jeff Johnson76052702013-04-16 13:55:05 -070010681 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010682
Jeff Johnson76052702013-04-16 13:55:05 -070010683 ret = param_set_int(kmessage, kp);
10684 if (0 == ret)
10685 ret = kickstart_driver();
10686 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010687}
10688#endif /* #ifdef MODULE */
10689
10690/**---------------------------------------------------------------------------
10691
Jeff Johnson295189b2012-06-20 16:38:30 -070010692 \brief hdd_get_conparam() -
10693
10694 This is the driver exit point (invoked when module is unloaded using rmmod)
10695
10696 \param - None
10697
10698 \return - tVOS_CON_MODE
10699
10700 --------------------------------------------------------------------------*/
10701tVOS_CON_MODE hdd_get_conparam ( void )
10702{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010703#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010704 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010705#else
10706 return (tVOS_CON_MODE)curr_con_mode;
10707#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010708}
10709void hdd_set_conparam ( v_UINT_t newParam )
10710{
10711 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010712#ifndef MODULE
10713 curr_con_mode = con_mode;
10714#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010715}
10716/**---------------------------------------------------------------------------
10717
10718 \brief hdd_softap_sta_deauth() - function
10719
10720 This to take counter measure to handle deauth req from HDD
10721
10722 \param - pAdapter - Pointer to the HDD
10723
10724 \param - enable - boolean value
10725
10726 \return - None
10727
10728 --------------------------------------------------------------------------*/
10729
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010730VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10731 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010732{
Jeff Johnson295189b2012-06-20 16:38:30 -070010733 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010734 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010735
10736 ENTER();
10737
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010738 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10739 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010740
10741 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010742 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010743 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010744
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010745 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010746
10747 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010748 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010749}
10750
10751/**---------------------------------------------------------------------------
10752
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010753 \brief hdd_del_all_sta() - function
10754
10755 This function removes all the stations associated on stopping AP/P2P GO.
10756
10757 \param - pAdapter - Pointer to the HDD
10758
10759 \return - None
10760
10761 --------------------------------------------------------------------------*/
10762
10763int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10764{
10765 v_U16_t i;
10766 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010767 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10768 ptSapContext pSapCtx = NULL;
10769 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10770 if(pSapCtx == NULL){
10771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10772 FL("psapCtx is NULL"));
10773 return 1;
10774 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010775 ENTER();
10776
10777 hddLog(VOS_TRACE_LEVEL_INFO,
10778 "%s: Delete all STAs associated.",__func__);
10779 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10780 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10781 )
10782 {
10783 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10784 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010785 if ((pSapCtx->aStaInfo[i].isUsed) &&
10786 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010787 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010788 struct tagCsrDelStaParams delStaParams;
10789
10790 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010791 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010792 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10793 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010794 &delStaParams);
10795 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010796 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010797 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010798 }
10799 }
10800 }
10801
10802 EXIT();
10803 return 0;
10804}
10805
10806/**---------------------------------------------------------------------------
10807
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 \brief hdd_softap_sta_disassoc() - function
10809
10810 This to take counter measure to handle deauth req from HDD
10811
10812 \param - pAdapter - Pointer to the HDD
10813
10814 \param - enable - boolean value
10815
10816 \return - None
10817
10818 --------------------------------------------------------------------------*/
10819
10820void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10821{
10822 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10823
10824 ENTER();
10825
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010826 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010827
10828 //Ignore request to disassoc bcmc station
10829 if( pDestMacAddress[0] & 0x1 )
10830 return;
10831
10832 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10833}
10834
10835void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10836{
10837 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10838
10839 ENTER();
10840
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010841 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010842
10843 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10844}
10845
Jeff Johnson295189b2012-06-20 16:38:30 -070010846/**---------------------------------------------------------------------------
10847 *
10848 * \brief hdd_get__concurrency_mode() -
10849 *
10850 *
10851 * \param - None
10852 *
10853 * \return - CONCURRENCY MODE
10854 *
10855 * --------------------------------------------------------------------------*/
10856tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10857{
10858 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10859 hdd_context_t *pHddCtx;
10860
10861 if (NULL != pVosContext)
10862 {
10863 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10864 if (NULL != pHddCtx)
10865 {
10866 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10867 }
10868 }
10869
10870 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010871 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010872 return VOS_STA;
10873}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010874v_BOOL_t
10875wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10876{
10877 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010878
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010879 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10880 if (pAdapter == NULL)
10881 {
10882 hddLog(VOS_TRACE_LEVEL_INFO,
10883 FL("GO doesn't exist"));
10884 return TRUE;
10885 }
10886 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10887 {
10888 hddLog(VOS_TRACE_LEVEL_INFO,
10889 FL("GO started"));
10890 return TRUE;
10891 }
10892 else
10893 /* wait till GO changes its interface to p2p device */
10894 hddLog(VOS_TRACE_LEVEL_INFO,
10895 FL("Del_bss called, avoid apps suspend"));
10896 return FALSE;
10897
10898}
Jeff Johnson295189b2012-06-20 16:38:30 -070010899/* Decide whether to allow/not the apps power collapse.
10900 * Allow apps power collapse if we are in connected state.
10901 * if not, allow only if we are in IMPS */
10902v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10903{
10904 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010905 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010906 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010907 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10908 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10909 hdd_adapter_t *pAdapter = NULL;
10910 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010911 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010912
Jeff Johnson295189b2012-06-20 16:38:30 -070010913 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10914 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010915
Yathish9f22e662012-12-10 14:21:35 -080010916 concurrent_state = hdd_get_concurrency_mode();
10917
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010918 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10919 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10920 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010921#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010922
Yathish9f22e662012-12-10 14:21:35 -080010923 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010924 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010925 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10926 return TRUE;
10927#endif
10928
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 /*loop through all adapters. TBD fix for Concurrency */
10930 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10931 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10932 {
10933 pAdapter = pAdapterNode->pAdapter;
10934 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10935 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10936 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010937 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010938 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010939 && pmcState != STOPPED && pmcState != STANDBY &&
10940 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010941 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10942 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010943 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010944 if(pmcState == FULL_POWER &&
10945 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10946 {
10947 /*
10948 * When SCO indication comes from Coex module , host will
10949 * enter in to full power mode, but this should not prevent
10950 * apps processor power collapse.
10951 */
10952 hddLog(LOG1,
10953 FL("Allow apps power collapse"
10954 "even when sco indication is set"));
10955 return TRUE;
10956 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010957 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010958 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10959 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010960 return FALSE;
10961 }
10962 }
10963 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10964 pAdapterNode = pNext;
10965 }
10966 return TRUE;
10967}
10968
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010969/* Decides whether to send suspend notification to Riva
10970 * if any adapter is in BMPS; then it is required */
10971v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10972{
10973 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10974 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10975
10976 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10977 {
10978 return TRUE;
10979 }
10980 return FALSE;
10981}
10982
Jeff Johnson295189b2012-06-20 16:38:30 -070010983void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10984{
10985 switch(mode)
10986 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010987 case VOS_STA_MODE:
10988 case VOS_P2P_CLIENT_MODE:
10989 case VOS_P2P_GO_MODE:
10990 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010991 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010992 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 break;
10994 default:
10995 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010996 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010997 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10998 "Number of open sessions for mode %d = %d"),
10999 pHddCtx->concurrency_mode, mode,
11000 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011001}
11002
11003
11004void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11005{
11006 switch(mode)
11007 {
Chilam Ngc4244af2013-04-01 15:37:32 -070011008 case VOS_STA_MODE:
11009 case VOS_P2P_CLIENT_MODE:
11010 case VOS_P2P_GO_MODE:
11011 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053011012 pHddCtx->no_of_open_sessions[mode]--;
11013 if (!(pHddCtx->no_of_open_sessions[mode]))
11014 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070011015 break;
11016 default:
11017 break;
11018 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053011019 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
11020 "Number of open sessions for mode %d = %d"),
11021 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
11022
11023}
11024/**---------------------------------------------------------------------------
11025 *
11026 * \brief wlan_hdd_incr_active_session()
11027 *
11028 * This function increments the number of active sessions
11029 * maintained per device mode
11030 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
11031 * Incase of SAP/P2P GO upon bss start it is incremented
11032 *
11033 * \param pHddCtx - HDD Context
11034 * \param mode - device mode
11035 *
11036 * \return - None
11037 *
11038 * --------------------------------------------------------------------------*/
11039void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11040{
11041 switch (mode) {
11042 case VOS_STA_MODE:
11043 case VOS_P2P_CLIENT_MODE:
11044 case VOS_P2P_GO_MODE:
11045 case VOS_STA_SAP_MODE:
11046 pHddCtx->no_of_active_sessions[mode]++;
11047 break;
11048 default:
11049 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11050 break;
11051 }
11052 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11053 mode,
11054 pHddCtx->no_of_active_sessions[mode]);
11055}
11056
11057/**---------------------------------------------------------------------------
11058 *
11059 * \brief wlan_hdd_decr_active_session()
11060 *
11061 * This function decrements the number of active sessions
11062 * maintained per device mode
11063 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
11064 * Incase of SAP/P2P GO upon bss stop it is decremented
11065 *
11066 * \param pHddCtx - HDD Context
11067 * \param mode - device mode
11068 *
11069 * \return - None
11070 *
11071 * --------------------------------------------------------------------------*/
11072void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
11073{
11074 switch (mode) {
11075 case VOS_STA_MODE:
11076 case VOS_P2P_CLIENT_MODE:
11077 case VOS_P2P_GO_MODE:
11078 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053011079 if (pHddCtx->no_of_active_sessions[mode] > 0)
11080 pHddCtx->no_of_active_sessions[mode]--;
11081 else
11082 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
11083 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053011084 break;
11085 default:
11086 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
11087 break;
11088 }
11089 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
11090 mode,
11091 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070011092}
11093
Jeff Johnsone7245742012-09-05 17:12:55 -070011094/**---------------------------------------------------------------------------
11095 *
11096 * \brief wlan_hdd_restart_init
11097 *
11098 * This function initalizes restart timer/flag. An internal function.
11099 *
11100 * \param - pHddCtx
11101 *
11102 * \return - None
11103 *
11104 * --------------------------------------------------------------------------*/
11105
11106static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
11107{
11108 /* Initialize */
11109 pHddCtx->hdd_restart_retries = 0;
11110 atomic_set(&pHddCtx->isRestartInProgress, 0);
11111 vos_timer_init(&pHddCtx->hdd_restart_timer,
11112 VOS_TIMER_TYPE_SW,
11113 wlan_hdd_restart_timer_cb,
11114 pHddCtx);
11115}
11116/**---------------------------------------------------------------------------
11117 *
11118 * \brief wlan_hdd_restart_deinit
11119 *
11120 * This function cleans up the resources used. An internal function.
11121 *
11122 * \param - pHddCtx
11123 *
11124 * \return - None
11125 *
11126 * --------------------------------------------------------------------------*/
11127
11128static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
11129{
11130
11131 VOS_STATUS vos_status;
11132 /* Block any further calls */
11133 atomic_set(&pHddCtx->isRestartInProgress, 1);
11134 /* Cleanup */
11135 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
11136 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011137 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011138 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
11139 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011140 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070011141
11142}
11143
11144/**---------------------------------------------------------------------------
11145 *
11146 * \brief wlan_hdd_framework_restart
11147 *
11148 * This function uses a cfg80211 API to start a framework initiated WLAN
11149 * driver module unload/load.
11150 *
11151 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
11152 *
11153 *
11154 * \param - pHddCtx
11155 *
11156 * \return - VOS_STATUS_SUCCESS: Success
11157 * VOS_STATUS_E_EMPTY: Adapter is Empty
11158 * VOS_STATUS_E_NOMEM: No memory
11159
11160 * --------------------------------------------------------------------------*/
11161
11162static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
11163{
11164 VOS_STATUS status = VOS_STATUS_SUCCESS;
11165 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011166 int len = (sizeof (struct ieee80211_mgmt));
11167 struct ieee80211_mgmt *mgmt = NULL;
11168
11169 /* Prepare the DEAUTH managment frame with reason code */
11170 mgmt = kzalloc(len, GFP_KERNEL);
11171 if(mgmt == NULL)
11172 {
11173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11174 "%s: memory allocation failed (%d bytes)", __func__, len);
11175 return VOS_STATUS_E_NOMEM;
11176 }
11177 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070011178
11179 /* Iterate over all adapters/devices */
11180 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011181 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
11182 {
11183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11184 FL("fail to get adapter: %p %d"), pAdapterNode, status);
11185 goto end;
11186 }
11187
Jeff Johnsone7245742012-09-05 17:12:55 -070011188 do
11189 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011190 if(pAdapterNode->pAdapter &&
11191 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070011192 {
11193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11194 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
11195 pAdapterNode->pAdapter->dev->name,
11196 pAdapterNode->pAdapter->device_mode,
11197 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011198 /*
11199 * CFG80211 event to restart the driver
11200 *
11201 * 'cfg80211_send_unprot_deauth' sends a
11202 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
11203 * of SME(Linux Kernel) state machine.
11204 *
11205 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
11206 * the driver.
11207 *
11208 */
11209
11210 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070011211 }
11212 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11213 pAdapterNode = pNext;
11214 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
11215
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053011216 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070011217 /* Free the allocated management frame */
11218 kfree(mgmt);
11219
Jeff Johnsone7245742012-09-05 17:12:55 -070011220 /* Retry until we unload or reach max count */
11221 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
11222 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
11223
11224 return status;
11225
11226}
11227/**---------------------------------------------------------------------------
11228 *
11229 * \brief wlan_hdd_restart_timer_cb
11230 *
11231 * Restart timer callback. An internal function.
11232 *
11233 * \param - User data:
11234 *
11235 * \return - None
11236 *
11237 * --------------------------------------------------------------------------*/
11238
11239void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
11240{
11241 hdd_context_t *pHddCtx = usrDataForCallback;
11242 wlan_hdd_framework_restart(pHddCtx);
11243 return;
11244
11245}
11246
11247
11248/**---------------------------------------------------------------------------
11249 *
11250 * \brief wlan_hdd_restart_driver
11251 *
11252 * This function sends an event to supplicant to restart the WLAN driver.
11253 *
11254 * This function is called from vos_wlanRestart.
11255 *
11256 * \param - pHddCtx
11257 *
11258 * \return - VOS_STATUS_SUCCESS: Success
11259 * VOS_STATUS_E_EMPTY: Adapter is Empty
11260 * VOS_STATUS_E_ALREADY: Request already in progress
11261
11262 * --------------------------------------------------------------------------*/
11263VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
11264{
11265 VOS_STATUS status = VOS_STATUS_SUCCESS;
11266
11267 /* A tight check to make sure reentrancy */
11268 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
11269 {
Mihir Shetefd528652014-06-23 19:07:50 +053011270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070011271 "%s: WLAN restart is already in progress", __func__);
11272
11273 return VOS_STATUS_E_ALREADY;
11274 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070011275 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080011276#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053011277 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070011278#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070011279
Jeff Johnsone7245742012-09-05 17:12:55 -070011280 return status;
11281}
11282
Mihir Shetee1093ba2014-01-21 20:13:32 +053011283/**---------------------------------------------------------------------------
11284 *
11285 * \brief wlan_hdd_init_channels
11286 *
11287 * This function is used to initialize the channel list in CSR
11288 *
11289 * This function is called from hdd_wlan_startup
11290 *
11291 * \param - pHddCtx: HDD context
11292 *
11293 * \return - VOS_STATUS_SUCCESS: Success
11294 * VOS_STATUS_E_FAULT: Failure reported by SME
11295
11296 * --------------------------------------------------------------------------*/
11297static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
11298{
11299 eHalStatus status;
11300
11301 status = sme_InitChannels(pHddCtx->hHal);
11302 if (HAL_STATUS_SUCCESS(status))
11303 {
11304 return VOS_STATUS_SUCCESS;
11305 }
11306 else
11307 {
11308 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11309 __func__, status);
11310 return VOS_STATUS_E_FAULT;
11311 }
11312}
11313
Mihir Shete04206452014-11-20 17:50:58 +053011314#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011315VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011316{
11317 eHalStatus status;
11318
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011319 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011320 if (HAL_STATUS_SUCCESS(status))
11321 {
11322 return VOS_STATUS_SUCCESS;
11323 }
11324 else
11325 {
11326 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11327 __func__, status);
11328 return VOS_STATUS_E_FAULT;
11329 }
11330}
Mihir Shete04206452014-11-20 17:50:58 +053011331#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011332/*
11333 * API to find if there is any STA or P2P-Client is connected
11334 */
11335VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11336{
11337 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11338}
Jeff Johnsone7245742012-09-05 17:12:55 -070011339
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011340
11341/*
11342 * API to find if the firmware will send logs using DXE channel
11343 */
11344v_U8_t hdd_is_fw_logging_enabled(void)
11345{
11346 hdd_context_t *pHddCtx;
11347
11348 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11349 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11350
Sachin Ahuja084313e2015-05-21 17:57:10 +053011351 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011352}
11353
Agarwal Ashish57e84372014-12-05 18:26:53 +053011354/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053011355 * API to find if the firmware will send trace logs using DXE channel
11356 */
11357v_U8_t hdd_is_fw_ev_logging_enabled(void)
11358{
11359 hdd_context_t *pHddCtx;
11360
11361 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11362 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11363
11364 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
11365}
11366/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053011367 * API to find if there is any session connected
11368 */
11369VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11370{
11371 return sme_is_any_session_connected(pHddCtx->hHal);
11372}
11373
11374
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011375int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11376{
11377 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11378 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011379 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011380 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011381
11382 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053011383 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011384 if (pScanInfo->mScanPending)
11385 {
c_hpothua3d45d52015-01-05 14:11:17 +053011386 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11387 eCSR_SCAN_ABORT_DEFAULT);
11388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11389 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011390
c_hpothua3d45d52015-01-05 14:11:17 +053011391 /* If there is active scan command lets wait for the completion else
11392 * there is no need to wait as scan command might be in the SME pending
11393 * command list.
11394 */
11395 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11396 {
c_hpothua3d45d52015-01-05 14:11:17 +053011397 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011398 &pScanInfo->abortscan_event_var,
11399 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011400 if (0 >= status)
11401 {
11402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011403 "%s: Timeout or Interrupt occurred while waiting for abort"
11404 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011405 return -ETIMEDOUT;
11406 }
11407 }
11408 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11409 {
11410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11411 FL("hdd_abort_mac_scan failed"));
11412 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011413 }
11414 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011415 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011416}
11417
c_hpothu225aa7c2014-10-22 17:45:13 +053011418VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11419{
11420 hdd_adapter_t *pAdapter;
11421 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11422 VOS_STATUS vosStatus;
11423
11424 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11425 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11426 {
11427 pAdapter = pAdapterNode->pAdapter;
11428 if (NULL != pAdapter)
11429 {
11430 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11431 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11432 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11433 {
11434 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11435 pAdapter->device_mode);
11436 if (VOS_STATUS_SUCCESS !=
11437 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11438 {
11439 hddLog(LOGE, FL("failed to abort ROC"));
11440 return VOS_STATUS_E_FAILURE;
11441 }
11442 }
11443 }
11444 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11445 pAdapterNode = pNext;
11446 }
11447 return VOS_STATUS_SUCCESS;
11448}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011449
Mihir Shete0be28772015-02-17 18:42:14 +053011450hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11451{
11452 hdd_adapter_t *pAdapter;
11453 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11454 hdd_cfg80211_state_t *cfgState;
11455 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11456 VOS_STATUS vosStatus;
11457
11458 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11459 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11460 {
11461 pAdapter = pAdapterNode->pAdapter;
11462 if (NULL != pAdapter)
11463 {
11464 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11465 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11466 if (pRemainChanCtx)
11467 break;
11468 }
11469 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11470 pAdapterNode = pNext;
11471 }
11472 return pRemainChanCtx;
11473}
11474
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011475/**
11476 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11477 *
11478 * @pHddCtx: HDD context within host driver
11479 * @dfsScanMode: dfsScanMode passed from ioctl
11480 *
11481 */
11482
11483VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11484 tANI_U8 dfsScanMode)
11485{
11486 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11487 hdd_adapter_t *pAdapter;
11488 VOS_STATUS vosStatus;
11489 hdd_station_ctx_t *pHddStaCtx;
11490 eHalStatus status = eHAL_STATUS_SUCCESS;
11491
11492 if(!pHddCtx)
11493 {
11494 hddLog(LOGE, FL("HDD context is Null"));
11495 return eHAL_STATUS_FAILURE;
11496 }
11497
11498 if (pHddCtx->scan_info.mScanPending)
11499 {
11500 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11501 pHddCtx->scan_info.sessionId);
11502 hdd_abort_mac_scan(pHddCtx,
11503 pHddCtx->scan_info.sessionId,
11504 eCSR_SCAN_ABORT_DEFAULT);
11505 }
11506
11507 if (!dfsScanMode)
11508 {
11509 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11510 while ((NULL != pAdapterNode) &&
11511 (VOS_STATUS_SUCCESS == vosStatus))
11512 {
11513 pAdapter = pAdapterNode->pAdapter;
11514
11515 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11516 {
11517 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11518
11519 if(!pHddStaCtx)
11520 {
11521 hddLog(LOGE, FL("HDD STA context is Null"));
11522 return eHAL_STATUS_FAILURE;
11523 }
11524
11525 /* if STA is already connected on DFS channel,
11526 disconnect immediately*/
11527 if (hdd_connIsConnected(pHddStaCtx) &&
11528 (NV_CHANNEL_DFS ==
11529 vos_nv_getChannelEnabledState(
11530 pHddStaCtx->conn_info.operationChannel)))
11531 {
11532 status = sme_RoamDisconnect(pHddCtx->hHal,
11533 pAdapter->sessionId,
11534 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11535 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11536 "sme_RoamDisconnect returned with status: %d"
11537 "for sessionid: %d"), pHddStaCtx->conn_info.
11538 operationChannel, status, pAdapter->sessionId);
11539 }
11540 }
11541
11542 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11543 &pNext);
11544 pAdapterNode = pNext;
11545 }
11546 }
11547
11548 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11549 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11550 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11551
11552 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11553 if (!HAL_STATUS_SUCCESS(status))
11554 {
11555 hddLog(LOGE,
11556 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11557 return status;
11558 }
11559
11560 return status;
11561}
11562
Nirav Shah7e3c8132015-06-22 23:51:42 +053011563static int hdd_log2_ceil(unsigned value)
11564{
11565 /* need to switch to unsigned math so that negative values
11566 * will right-shift towards 0 instead of -1
11567 */
11568 unsigned tmp = value;
11569 int log2 = -1;
11570
11571 if (value == 0)
11572 return 0;
11573
11574 while (tmp) {
11575 log2++;
11576 tmp >>= 1;
11577 }
11578 if (1U << log2 != value)
11579 log2++;
11580
11581 return log2;
11582}
11583
11584/**
11585 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
11586 * @pAdapter: adapter handle
11587 *
11588 * Return: vos status
11589 */
11590VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
11591{
11592 int hash_elem, log2, i;
11593
11594 spin_lock_bh( &pAdapter->sta_hash_lock);
11595 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
11596 spin_unlock_bh( &pAdapter->sta_hash_lock);
11597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11598 "%s: hash already attached for session id %d",
11599 __func__, pAdapter->sessionId);
11600 return VOS_STATUS_SUCCESS;
11601 }
11602 spin_unlock_bh( &pAdapter->sta_hash_lock);
11603
11604 hash_elem = WLAN_MAX_STA_COUNT;
11605 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
11606 log2 = hdd_log2_ceil(hash_elem);
11607 hash_elem = 1 << log2;
11608
11609 pAdapter->sta_id_hash.mask = hash_elem - 1;
11610 pAdapter->sta_id_hash.idx_bits = log2;
11611 pAdapter->sta_id_hash.bins =
11612 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
11613 if (!pAdapter->sta_id_hash.bins) {
11614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11615 "%s: malloc failed for session %d",
11616 __func__, pAdapter->sessionId);
11617 return VOS_STATUS_E_NOMEM;
11618 }
11619
11620 for (i = 0; i < hash_elem; i++)
11621 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
11622
11623 spin_lock_bh( &pAdapter->sta_hash_lock);
11624 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
11625 spin_unlock_bh( &pAdapter->sta_hash_lock);
11626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11627 "%s: Station ID Hash attached for session id %d",
11628 __func__, pAdapter->sessionId);
11629
11630 return VOS_STATUS_SUCCESS;
11631}
11632
11633/**
11634 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
11635 * @pAdapter: adapter handle
11636 *
11637 * Return: vos status
11638 */
11639VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
11640{
11641 int hash_elem, i;
11642 v_SIZE_t size;
11643
11644 spin_lock_bh( &pAdapter->sta_hash_lock);
11645 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11646 spin_unlock_bh( &pAdapter->sta_hash_lock);
11647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11648 "%s: hash not initialized for session id %d",
11649 __func__, pAdapter->sessionId);
11650 return VOS_STATUS_SUCCESS;
11651 }
11652
11653 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
11654 spin_unlock_bh( &pAdapter->sta_hash_lock);
11655
11656 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
11657
11658 /* free all station info*/
11659 for (i = 0; i < hash_elem; i++) {
11660 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
11661 if (size != 0) {
11662 VOS_STATUS status;
11663 hdd_staid_hash_node_t *sta_info_node = NULL;
11664 hdd_staid_hash_node_t *next_node = NULL;
11665 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
11666 (hdd_list_node_t**) &sta_info_node );
11667
11668 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11669 {
11670 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
11671 &sta_info_node->node);
11672 vos_mem_free(sta_info_node);
11673
11674 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
11675 (hdd_list_node_t*)sta_info_node,
11676 (hdd_list_node_t**)&next_node);
11677 sta_info_node = next_node;
11678 }
11679 }
11680 }
11681
11682 vos_mem_free(pAdapter->sta_id_hash.bins);
11683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11684 "%s: Station ID Hash detached for session id %d",
11685 __func__, pAdapter->sessionId);
11686 return VOS_STATUS_SUCCESS;
11687}
11688
11689/**
11690 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
11691 * @pAdapter: adapter handle
11692 * @mac_addr_in: input mac address
11693 *
11694 * Return: index derived from mac address
11695 */
11696int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
11697 v_MACADDR_t *mac_addr_in)
11698{
11699 uint16 index;
11700 struct hdd_align_mac_addr_t * mac_addr =
11701 (struct hdd_align_mac_addr_t *)mac_addr_in;
11702
11703 index = mac_addr->bytes_ab ^
11704 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
11705 index ^= index >> pAdapter->sta_id_hash.idx_bits;
11706 index &= pAdapter->sta_id_hash.mask;
11707 return index;
11708}
11709
11710/**
11711 * hdd_sta_id_hash_add_entry() - add entry in hash
11712 * @pAdapter: adapter handle
11713 * @sta_id: station id
11714 * @mac_addr: mac address
11715 *
11716 * Return: vos status
11717 */
11718VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
11719 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11720{
11721 uint16 index;
11722 hdd_staid_hash_node_t *sta_info_node = NULL;
11723
11724 spin_lock_bh( &pAdapter->sta_hash_lock);
11725 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11726 spin_unlock_bh( &pAdapter->sta_hash_lock);
11727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11728 "%s: hash is not initialized for session id %d",
11729 __func__, pAdapter->sessionId);
11730 return VOS_STATUS_E_FAILURE;
11731 }
11732
11733 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11734 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
11735 if (!sta_info_node) {
11736 spin_unlock_bh( &pAdapter->sta_hash_lock);
11737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11738 "%s: malloc failed", __func__);
11739 return VOS_STATUS_E_NOMEM;
11740 }
11741
11742 sta_info_node->sta_id = sta_id;
11743 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
11744
11745 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
11746 (hdd_list_node_t*) sta_info_node );
11747 spin_unlock_bh( &pAdapter->sta_hash_lock);
11748 return VOS_STATUS_SUCCESS;
11749}
11750
11751/**
11752 * hdd_sta_id_hash_remove_entry() - remove entry from hash
11753 * @pAdapter: adapter handle
11754 * @sta_id: station id
11755 * @mac_addr: mac address
11756 *
11757 * Return: vos status
11758 */
11759VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
11760 v_U8_t sta_id, v_MACADDR_t *mac_addr)
11761{
11762 uint16 index;
11763 VOS_STATUS status;
11764 hdd_staid_hash_node_t *sta_info_node = NULL;
11765 hdd_staid_hash_node_t *next_node = NULL;
11766
11767 spin_lock_bh( &pAdapter->sta_hash_lock);
11768 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11769 spin_unlock_bh( &pAdapter->sta_hash_lock);
11770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11771 "%s: hash is not initialized for session id %d",
11772 __func__, pAdapter->sessionId);
11773 return VOS_STATUS_E_FAILURE;
11774 }
11775
11776 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
11777 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11778 (hdd_list_node_t**) &sta_info_node );
11779
11780 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11781 {
11782 if (sta_info_node->sta_id == sta_id) {
11783 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
11784 &sta_info_node->node);
11785 vos_mem_free(sta_info_node);
11786 break;
11787 }
11788 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11789 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
11790 sta_info_node = next_node;
11791 }
11792 spin_unlock_bh( &pAdapter->sta_hash_lock);
11793 return status;
11794}
11795
11796/**
11797 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
11798 * @pAdapter: adapter handle
11799 * @mac_addr_in: mac address
11800 *
11801 * Return: station id
11802 */
11803int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
11804 v_MACADDR_t *mac_addr_in)
11805{
11806 uint8 is_found = 0;
11807 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
11808 uint16 index;
11809 VOS_STATUS status;
11810 hdd_staid_hash_node_t *sta_info_node = NULL;
11811 hdd_staid_hash_node_t *next_node = NULL;
11812
11813 spin_lock_bh( &pAdapter->sta_hash_lock);
11814 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
11815 spin_unlock_bh( &pAdapter->sta_hash_lock);
11816 hddLog(VOS_TRACE_LEVEL_ERROR,
11817 FL("hash is not initialized for session id %d"),
11818 pAdapter->sessionId);
11819 return HDD_WLAN_INVALID_STA_ID;
11820 }
11821
11822 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
11823 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
11824 (hdd_list_node_t**) &sta_info_node );
11825
11826 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
11827 {
11828 if (vos_mem_compare(&sta_info_node->mac_addr,
11829 mac_addr_in, sizeof(v_MACADDR_t))) {
11830 is_found = 1;
11831 sta_id = sta_info_node->sta_id;
11832 break;
11833 }
11834 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
11835 (hdd_list_node_t*)sta_info_node,
11836 (hdd_list_node_t**)&next_node);
11837 sta_info_node = next_node;
11838 }
11839 spin_unlock_bh( &pAdapter->sta_hash_lock);
11840 return sta_id;
11841}
11842
Jeff Johnson295189b2012-06-20 16:38:30 -070011843//Register the module init/exit functions
11844module_init(hdd_module_init);
11845module_exit(hdd_module_exit);
11846
11847MODULE_LICENSE("Dual BSD/GPL");
11848MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11849MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11850
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011851module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11852 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011853
Jeff Johnson76052702013-04-16 13:55:05 -070011854module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011855 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011856
11857module_param(enable_dfs_chan_scan, int,
11858 S_IRUSR | S_IRGRP | S_IROTH);
11859
11860module_param(enable_11d, int,
11861 S_IRUSR | S_IRGRP | S_IROTH);
11862
11863module_param(country_code, charp,
11864 S_IRUSR | S_IRGRP | S_IROTH);