blob: aaa3581befae13bd9a29dc88e84d0d1ff4f08a49 [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
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800197#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700200/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700201static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700202
203//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700204static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
206static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
207void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800208void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700209
Jeff Johnson295189b2012-06-20 16:38:30 -0700210v_U16_t hdd_select_queue(struct net_device *dev,
211 struct sk_buff *skb);
212
213#ifdef WLAN_FEATURE_PACKET_FILTERING
214static void hdd_set_multicast_list(struct net_device *dev);
215#endif
216
217void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
218
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800219#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800220void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
221static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700222static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
223 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
224 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700225static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
226 tANI_U8 *pTargetApBssid,
227 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800228#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800229#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700230VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800231#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700232
Mihir Shetee1093ba2014-01-21 20:13:32 +0530233static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530234const char * hdd_device_modetoString(v_U8_t device_mode)
235{
236 switch(device_mode)
237 {
238 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
239 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
240 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
241 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
242 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
243 CASE_RETURN_STRING( WLAN_HDD_FTM );
244 CASE_RETURN_STRING( WLAN_HDD_IBSS );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
246 default:
247 return "device_mode Unknown";
248 }
249}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530250
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530251static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700252 unsigned long state,
253 void *ndev)
254{
255 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700256 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700257 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700258#ifdef WLAN_BTAMP_FEATURE
259 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700260#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530261 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262
263 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700264 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700265 (strncmp(dev->name, "p2p", 3)))
266 return NOTIFY_DONE;
267
Jeff Johnson295189b2012-06-20 16:38:30 -0700268 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700269 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700270
Jeff Johnson27cee452013-03-27 11:10:24 -0700271 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800273 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700274 VOS_ASSERT(0);
275 return NOTIFY_DONE;
276 }
277
Jeff Johnson27cee452013-03-27 11:10:24 -0700278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
279 if (NULL == pHddCtx)
280 {
281 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
282 VOS_ASSERT(0);
283 return NOTIFY_DONE;
284 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800285 if (pHddCtx->isLogpInProgress)
286 return NOTIFY_DONE;
287
Jeff Johnson27cee452013-03-27 11:10:24 -0700288
289 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
290 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700291
292 switch (state) {
293 case NETDEV_REGISTER:
294 break;
295
296 case NETDEV_UNREGISTER:
297 break;
298
299 case NETDEV_UP:
300 break;
301
302 case NETDEV_DOWN:
303 break;
304
305 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700306 if(TRUE == pAdapter->isLinkUpSvcNeeded)
307 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 break;
309
310 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530311 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530312 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530313 {
314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
315 "%s: Timeout occurred while waiting for abortscan %ld",
316 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700317 }
318 else
319 {
320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530321 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 }
323#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 status = WLANBAP_StopAmp();
326 if(VOS_STATUS_SUCCESS != status )
327 {
328 pHddCtx->isAmpAllowed = VOS_TRUE;
329 hddLog(VOS_TRACE_LEVEL_FATAL,
330 "%s: Failed to stop AMP", __func__);
331 }
332 else
333 {
334 //a state m/c implementation in PAL is TBD to avoid this delay
335 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700336 if ( pHddCtx->isAmpAllowed )
337 {
338 WLANBAP_DeregisterFromHCI();
339 pHddCtx->isAmpAllowed = VOS_FALSE;
340 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 }
342#endif //WLAN_BTAMP_FEATURE
343 break;
344
345 default:
346 break;
347 }
348
349 return NOTIFY_DONE;
350}
351
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530352static int hdd_netdev_notifier_call(struct notifier_block * nb,
353 unsigned long state,
354 void *ndev)
355{
356 int ret;
357 vos_ssr_protect(__func__);
358 ret = __hdd_netdev_notifier_call( nb, state, ndev);
359 vos_ssr_unprotect(__func__);
360 return ret;
361}
362
Jeff Johnson295189b2012-06-20 16:38:30 -0700363struct notifier_block hdd_netdev_notifier = {
364 .notifier_call = hdd_netdev_notifier_call,
365};
366
367/*---------------------------------------------------------------------------
368 * Function definitions
369 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700370void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
371void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700372//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700373static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700374#ifndef MODULE
375/* current con_mode - used only for statically linked driver
376 * con_mode is changed by userspace to indicate a mode change which will
377 * result in calling the module exit and init functions. The module
378 * exit function will clean up based on the value of con_mode prior to it
379 * being changed by userspace. So curr_con_mode records the current con_mode
380 * for exit when con_mode becomes the next mode for init
381 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700382static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700383#endif
384
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800385/**---------------------------------------------------------------------------
386
387 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
388
389 Called immediately after the cfg.ini is read in order to configure
390 the desired trace levels.
391
392 \param - moduleId - module whose trace level is being configured
393 \param - bitmask - bitmask of log levels to be enabled
394
395 \return - void
396
397 --------------------------------------------------------------------------*/
398static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
399{
400 wpt_tracelevel level;
401
402 /* if the bitmask is the default value, then a bitmask was not
403 specified in cfg.ini, so leave the logging level alone (it
404 will remain at the "compiled in" default value) */
405 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
406 {
407 return;
408 }
409
410 /* a mask was specified. start by disabling all logging */
411 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
412
413 /* now cycle through the bitmask until all "set" bits are serviced */
414 level = VOS_TRACE_LEVEL_FATAL;
415 while (0 != bitmask)
416 {
417 if (bitmask & 1)
418 {
419 vos_trace_setValue(moduleId, level, 1);
420 }
421 level++;
422 bitmask >>= 1;
423 }
424}
425
426
Jeff Johnson295189b2012-06-20 16:38:30 -0700427/**---------------------------------------------------------------------------
428
429 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
430
431 Called immediately after the cfg.ini is read in order to configure
432 the desired trace levels in the WDI.
433
434 \param - moduleId - module whose trace level is being configured
435 \param - bitmask - bitmask of log levels to be enabled
436
437 \return - void
438
439 --------------------------------------------------------------------------*/
440static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
441{
442 wpt_tracelevel level;
443
444 /* if the bitmask is the default value, then a bitmask was not
445 specified in cfg.ini, so leave the logging level alone (it
446 will remain at the "compiled in" default value) */
447 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
448 {
449 return;
450 }
451
452 /* a mask was specified. start by disabling all logging */
453 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
454
455 /* now cycle through the bitmask until all "set" bits are serviced */
456 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
457 while (0 != bitmask)
458 {
459 if (bitmask & 1)
460 {
461 wpalTraceSetLevel(moduleId, level, 1);
462 }
463 level++;
464 bitmask >>= 1;
465 }
466}
Jeff Johnson295189b2012-06-20 16:38:30 -0700467
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530468/*
469 * FUNCTION: wlan_hdd_validate_context
470 * This function is used to check the HDD context
471 */
472int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
473{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530474
475 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
476 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530478 "%s: HDD context is Null", __func__);
479 return -ENODEV;
480 }
481
482 if (pHddCtx->isLogpInProgress)
483 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530485 "%s: LOGP %s. Ignore!!", __func__,
486 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
487 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530488 return -EAGAIN;
489 }
490
Mihir Shete18156292014-03-11 15:38:30 +0530491 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530492 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530494 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
495 return -EAGAIN;
496 }
497 return 0;
498}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700499#ifdef CONFIG_ENABLE_LINUX_REG
500void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
501{
502 hdd_adapter_t *pAdapter = NULL;
503 hdd_station_ctx_t *pHddStaCtx = NULL;
504 eCsrPhyMode phyMode;
505 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530506
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700507 if (NULL == pHddCtx)
508 {
509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
510 "HDD Context is null !!");
511 return ;
512 }
513
514 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
515 if (NULL == pAdapter)
516 {
517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
518 "pAdapter is null !!");
519 return ;
520 }
521
522 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
523 if (NULL == pHddStaCtx)
524 {
525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
526 "pHddStaCtx is null !!");
527 return ;
528 }
529
530 cfg_param = pHddCtx->cfg_ini;
531 if (NULL == cfg_param)
532 {
533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
534 "cfg_params not available !!");
535 return ;
536 }
537
538 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
539
540 if (!pHddCtx->isVHT80Allowed)
541 {
542 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
543 (eCSR_DOT11_MODE_11ac == phyMode) ||
544 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
545 {
546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
547 "Setting phymode to 11n!!");
548 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
549 }
550 }
551 else
552 {
553 /*New country Supports 11ac as well resetting value back from .ini*/
554 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
555 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
556 return ;
557 }
558
559 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
560 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
561 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
562 {
563 VOS_STATUS vosStatus;
564
565 // need to issue a disconnect to CSR.
566 INIT_COMPLETION(pAdapter->disconnect_comp_var);
567 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
568 pAdapter->sessionId,
569 eCSR_DISCONNECT_REASON_UNSPECIFIED );
570
571 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530572 {
573 long ret;
574
575 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700576 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530577 if (0 >= ret)
578 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
579 ret);
580 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700581
582 }
583}
584#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530585void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
586{
587 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
588 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
589 hdd_config_t *cfg_param;
590 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530591 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530592
593 if (NULL == pHddCtx)
594 {
595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
596 "HDD Context is null !!");
597 return ;
598 }
599
600 cfg_param = pHddCtx->cfg_ini;
601
602 if (NULL == cfg_param)
603 {
604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
605 "cfg_params not available !!");
606 return ;
607 }
608
609 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
610
611 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
612 {
613 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
614 (eCSR_DOT11_MODE_11ac == phyMode) ||
615 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
618 "Setting phymode to 11n!!");
619 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
620 }
621 }
622 else
623 {
624 /*New country Supports 11ac as well resetting value back from .ini*/
625 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
626 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
627 return ;
628 }
629
630 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
631 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
632 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
633 {
634 VOS_STATUS vosStatus;
635
636 // need to issue a disconnect to CSR.
637 INIT_COMPLETION(pAdapter->disconnect_comp_var);
638 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
639 pAdapter->sessionId,
640 eCSR_DISCONNECT_REASON_UNSPECIFIED );
641
642 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530643 {
644 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530645 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530646 if (ret <= 0)
647 {
648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
649 "wait on disconnect_comp_var is failed %ld", ret);
650 }
651 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530652
653 }
654}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700655#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530656
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700657void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
658{
659 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
660 hdd_config_t *cfg_param;
661
662 if (NULL == pHddCtx)
663 {
664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
665 "HDD Context is null !!");
666 return ;
667 }
668
669 cfg_param = pHddCtx->cfg_ini;
670
671 if (NULL == cfg_param)
672 {
673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
674 "cfg_params not available !!");
675 return ;
676 }
677
Agarwal Ashish738843c2014-09-25 12:27:56 +0530678 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
679 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700680 {
681 /*New country doesn't support DFS */
682 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
683 }
684 else
685 {
686 /*New country Supports DFS as well resetting value back from .ini*/
687 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
688 }
689
690}
691
Rajeev79dbe4c2013-10-05 11:03:42 +0530692#ifdef FEATURE_WLAN_BATCH_SCAN
693
694/**---------------------------------------------------------------------------
695
696 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
697 input string
698
699 This function extracts assigned integer from string in below format:
700 "STRING=10" : extracts integer 10 from this string
701
702 \param - pInPtr Pointer to input string
703 \param - base Base for string to int conversion(10 for decimal 16 for hex)
704 \param - pOutPtr Pointer to variable in which extracted integer needs to be
705 assigned
706 \param - pLastArg to tell whether it is last arguement in input string or
707 not
708
709 \return - NULL for failure cases
710 pointer to next arguement in input string for success cases
711 --------------------------------------------------------------------------*/
712static tANI_U8 *
713hdd_extract_assigned_int_from_str
714(
715 tANI_U8 *pInPtr,
716 tANI_U8 base,
717 tANI_U32 *pOutPtr,
718 tANI_U8 *pLastArg
719)
720{
721 int tempInt;
722 int v = 0;
723 char buf[32];
724 int val = 0;
725 *pLastArg = FALSE;
726
727 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
728 if (NULL == pInPtr)
729 {
730 return NULL;
731 }
732
733 pInPtr++;
734
735 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
736
737 val = sscanf(pInPtr, "%32s ", buf);
738 if (val < 0 && val > strlen(pInPtr))
739 {
740 return NULL;
741 }
742 pInPtr += val;
743 v = kstrtos32(buf, base, &tempInt);
744 if (v < 0)
745 {
746 return NULL;
747 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800748 if (tempInt < 0)
749 {
750 tempInt = 0;
751 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530752 *pOutPtr = tempInt;
753
754 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
755 if (NULL == pInPtr)
756 {
757 *pLastArg = TRUE;
758 return NULL;
759 }
760 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
761
762 return pInPtr;
763}
764
765/**---------------------------------------------------------------------------
766
767 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
768 input string
769
770 This function extracts assigned character from string in below format:
771 "STRING=A" : extracts char 'A' from this string
772
773 \param - pInPtr Pointer to input string
774 \param - pOutPtr Pointer to variable in which extracted char needs to be
775 assigned
776 \param - pLastArg to tell whether it is last arguement in input string or
777 not
778
779 \return - NULL for failure cases
780 pointer to next arguement in input string for success cases
781 --------------------------------------------------------------------------*/
782static tANI_U8 *
783hdd_extract_assigned_char_from_str
784(
785 tANI_U8 *pInPtr,
786 tANI_U8 *pOutPtr,
787 tANI_U8 *pLastArg
788)
789{
790 *pLastArg = FALSE;
791
792 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
793 if (NULL == pInPtr)
794 {
795 return NULL;
796 }
797
798 pInPtr++;
799
800 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
801
802 *pOutPtr = *pInPtr;
803
804 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
805 if (NULL == pInPtr)
806 {
807 *pLastArg = TRUE;
808 return NULL;
809 }
810 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
811
812 return pInPtr;
813}
814
815
816/**---------------------------------------------------------------------------
817
818 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
819
820 This function parses set batch scan command in below format:
821 WLS_BATCHING_SET <space> followed by below arguements
822 "SCANFREQ=XX" : Optional defaults to 30 sec
823 "MSCAN=XX" : Required number of scans to attempt to batch
824 "BESTN=XX" : Best Network (RSSI) defaults to 16
825 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
826 A. implies only 5 GHz , B. implies only 2.4GHz
827 "RTT=X" : optional defaults to 0
828 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
829 error
830
831 For example input commands:
832 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
833 translated into set batch scan with following parameters:
834 a) Frequence 60 seconds
835 b) Batch 10 scans together
836 c) Best RSSI to be 20
837 d) 5GHz band only
838 e) RTT is equal to 0
839
840 \param - pValue Pointer to input channel list
841 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
842
843 \return - 0 for success non-zero for failure
844
845 --------------------------------------------------------------------------*/
846static int
847hdd_parse_set_batchscan_command
848(
849 tANI_U8 *pValue,
850 tSirSetBatchScanReq *pHddSetBatchScanReq
851)
852{
853 tANI_U8 *inPtr = pValue;
854 tANI_U8 val = 0;
855 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800856 tANI_U32 nScanFreq;
857 tANI_U32 nMscan;
858 tANI_U32 nBestN;
859 tANI_U8 ucRfBand;
860 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800861 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530862
863 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800864 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
865 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
866 nRtt = 0;
867 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530868
869 /*go to space after WLS_BATCHING_SET command*/
870 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
871 /*no argument after the command*/
872 if (NULL == inPtr)
873 {
874 return -EINVAL;
875 }
876
877 /*no space after the command*/
878 else if (SPACE_ASCII_VALUE != *inPtr)
879 {
880 return -EINVAL;
881 }
882
883 /*removing empty spaces*/
884 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
885
886 /*no argument followed by spaces*/
887 if ('\0' == *inPtr)
888 {
889 return -EINVAL;
890 }
891
892 /*check and parse SCANFREQ*/
893 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
894 {
895 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800896 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800897
Rajeev Kumarc933d982013-11-18 20:04:20 -0800898 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800899 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800900 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800901 }
902
Rajeev79dbe4c2013-10-05 11:03:42 +0530903 if ( (NULL == inPtr) || (TRUE == lastArg))
904 {
905 return -EINVAL;
906 }
907 }
908
909 /*check and parse MSCAN*/
910 if ((strncmp(inPtr, "MSCAN", 5) == 0))
911 {
912 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800913 &nMscan, &lastArg);
914
915 if (0 == nMscan)
916 {
917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
918 "invalid MSCAN=%d", nMscan);
919 return -EINVAL;
920 }
921
Rajeev79dbe4c2013-10-05 11:03:42 +0530922 if (TRUE == lastArg)
923 {
924 goto done;
925 }
926 else if (NULL == inPtr)
927 {
928 return -EINVAL;
929 }
930 }
931 else
932 {
933 return -EINVAL;
934 }
935
936 /*check and parse BESTN*/
937 if ((strncmp(inPtr, "BESTN", 5) == 0))
938 {
939 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800940 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800941
Rajeev Kumarc933d982013-11-18 20:04:20 -0800942 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800943 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800944 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800945 }
946
Rajeev79dbe4c2013-10-05 11:03:42 +0530947 if (TRUE == lastArg)
948 {
949 goto done;
950 }
951 else if (NULL == inPtr)
952 {
953 return -EINVAL;
954 }
955 }
956
957 /*check and parse CHANNEL*/
958 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
959 {
960 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800961
Rajeev79dbe4c2013-10-05 11:03:42 +0530962 if (('A' == val) || ('a' == val))
963 {
c_hpothuebf89732014-02-25 13:00:24 +0530964 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530965 }
966 else if (('B' == val) || ('b' == val))
967 {
c_hpothuebf89732014-02-25 13:00:24 +0530968 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530969 }
970 else
971 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800972 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
973 }
974
975 if (TRUE == lastArg)
976 {
977 goto done;
978 }
979 else if (NULL == inPtr)
980 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530981 return -EINVAL;
982 }
983 }
984
985 /*check and parse RTT*/
986 if ((strncmp(inPtr, "RTT", 3) == 0))
987 {
988 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800989 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530990 if (TRUE == lastArg)
991 {
992 goto done;
993 }
994 if (NULL == inPtr)
995 {
996 return -EINVAL;
997 }
998 }
999
1000
1001done:
1002
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001003 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1004 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1005 pHddSetBatchScanReq->bestNetwork = nBestN;
1006 pHddSetBatchScanReq->rfBand = ucRfBand;
1007 pHddSetBatchScanReq->rtt = nRtt;
1008
Rajeev79dbe4c2013-10-05 11:03:42 +05301009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1010 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1011 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1012 pHddSetBatchScanReq->scanFrequency,
1013 pHddSetBatchScanReq->numberOfScansToBatch,
1014 pHddSetBatchScanReq->bestNetwork,
1015 pHddSetBatchScanReq->rfBand,
1016 pHddSetBatchScanReq->rtt);
1017
1018 return 0;
1019}/*End of hdd_parse_set_batchscan_command*/
1020
1021/**---------------------------------------------------------------------------
1022
1023 \brief hdd_set_batch_scan_req_callback () - This function is called after
1024 receiving set batch scan response from FW and it saves set batch scan
1025 response data FW to HDD context and sets the completion event on
1026 which hdd_ioctl is waiting
1027
1028 \param - callbackContext Pointer to HDD adapter
1029 \param - pRsp Pointer to set batch scan response data received from FW
1030
1031 \return - nothing
1032
1033 --------------------------------------------------------------------------*/
1034static void hdd_set_batch_scan_req_callback
1035(
1036 void *callbackContext,
1037 tSirSetBatchScanRsp *pRsp
1038)
1039{
1040 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1041 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1042
1043 /*sanity check*/
1044 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1045 {
1046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1047 "%s: Invalid pAdapter magic", __func__);
1048 VOS_ASSERT(0);
1049 return;
1050 }
1051 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1052
1053 /*save set batch scan response*/
1054 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1055
1056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1057 "Received set batch scan rsp from FW with nScansToBatch=%d",
1058 pHddSetBatchScanRsp->nScansToBatch);
1059
1060 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1061 complete(&pAdapter->hdd_set_batch_scan_req_var);
1062
1063 return;
1064}/*End of hdd_set_batch_scan_req_callback*/
1065
1066
1067/**---------------------------------------------------------------------------
1068
1069 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1070 info in hdd batch scan response queue
1071
1072 \param - pAdapter Pointer to hdd adapter
1073 \param - pAPMetaInfo Pointer to access point meta info
1074 \param - scanId scan ID of batch scan response
1075 \param - isLastAp tells whether AP is last AP in batch scan response or not
1076
1077 \return - nothing
1078
1079 --------------------------------------------------------------------------*/
1080static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1081 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1082{
1083 tHddBatchScanRsp *pHead;
1084 tHddBatchScanRsp *pNode;
1085 tHddBatchScanRsp *pPrev;
1086 tHddBatchScanRsp *pTemp;
1087 tANI_U8 ssidLen;
1088
1089 /*head of hdd batch scan response queue*/
1090 pHead = pAdapter->pBatchScanRsp;
1091
1092 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1093 if (NULL == pNode)
1094 {
1095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1096 "%s: Could not allocate memory", __func__);
1097 VOS_ASSERT(0);
1098 return;
1099 }
1100
1101 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1102 sizeof(pNode->ApInfo.bssid));
1103 ssidLen = strlen(pApMetaInfo->ssid);
1104 if (SIR_MAX_SSID_SIZE < ssidLen)
1105 {
1106 /*invalid scan result*/
1107 vos_mem_free(pNode);
1108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1109 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1110 return;
1111 }
1112 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1113 /*null terminate ssid*/
1114 pNode->ApInfo.ssid[ssidLen] = '\0';
1115 pNode->ApInfo.ch = pApMetaInfo->ch;
1116 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1117 pNode->ApInfo.age = pApMetaInfo->timestamp;
1118 pNode->ApInfo.batchId = scanId;
1119 pNode->ApInfo.isLastAp = isLastAp;
1120
1121 pNode->pNext = NULL;
1122 if (NULL == pHead)
1123 {
1124 pAdapter->pBatchScanRsp = pNode;
1125 }
1126 else
1127 {
1128 pTemp = pHead;
1129 while (NULL != pTemp)
1130 {
1131 pPrev = pTemp;
1132 pTemp = pTemp->pNext;
1133 }
1134 pPrev->pNext = pNode;
1135 }
1136
1137 return;
1138}/*End of hdd_populate_batch_scan_rsp_queue*/
1139
1140/**---------------------------------------------------------------------------
1141
1142 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1143 receiving batch scan response indication from FW. It saves get batch scan
1144 response data in HDD batch scan response queue. This callback sets the
1145 completion event on which hdd_ioctl is waiting only after getting complete
1146 batch scan response data from FW
1147
1148 \param - callbackContext Pointer to HDD adapter
1149 \param - pRsp Pointer to get batch scan response data received from FW
1150
1151 \return - nothing
1152
1153 --------------------------------------------------------------------------*/
1154static void hdd_batch_scan_result_ind_callback
1155(
1156 void *callbackContext,
1157 void *pRsp
1158)
1159{
1160 v_BOOL_t isLastAp;
1161 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001162 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301163 tANI_U32 numberScanList;
1164 tANI_U32 nextScanListOffset;
1165 tANI_U32 nextApMetaInfoOffset;
1166 hdd_adapter_t* pAdapter;
1167 tpSirBatchScanList pScanList;
1168 tpSirBatchScanNetworkInfo pApMetaInfo;
1169 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1170 tSirSetBatchScanReq *pReq;
1171
1172 pAdapter = (hdd_adapter_t *)callbackContext;
1173 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001174 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301175 {
1176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1177 "%s: Invalid pAdapter magic", __func__);
1178 VOS_ASSERT(0);
1179 return;
1180 }
1181
1182 /*initialize locals*/
1183 pReq = &pAdapter->hddSetBatchScanReq;
1184 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1185 isLastAp = FALSE;
1186 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001187 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301188 numberScanList = 0;
1189 nextScanListOffset = 0;
1190 nextApMetaInfoOffset = 0;
1191 pScanList = NULL;
1192 pApMetaInfo = NULL;
1193
1194 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1195 {
1196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1197 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1198 isLastAp = TRUE;
1199 goto done;
1200 }
1201
1202 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1204 "Batch scan rsp: numberScalList %d", numberScanList);
1205
1206 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1207 {
1208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1209 "%s: numberScanList %d", __func__, numberScanList);
1210 isLastAp = TRUE;
1211 goto done;
1212 }
1213
1214 while (numberScanList)
1215 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001216 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301217 nextScanListOffset);
1218 if (NULL == pScanList)
1219 {
1220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1221 "%s: pScanList is %p", __func__, pScanList);
1222 isLastAp = TRUE;
1223 goto done;
1224 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001225 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001227 "Batch scan rsp: numApMetaInfo %d scanId %d",
1228 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301229
1230 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1231 {
1232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1233 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1234 isLastAp = TRUE;
1235 goto done;
1236 }
1237
Rajeev Kumarce651e42013-10-21 18:57:15 -07001238 /*Initialize next AP meta info offset for next scan list*/
1239 nextApMetaInfoOffset = 0;
1240
Rajeev79dbe4c2013-10-05 11:03:42 +05301241 while (numApMetaInfo)
1242 {
1243 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1244 nextApMetaInfoOffset);
1245 if (NULL == pApMetaInfo)
1246 {
1247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1248 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1249 isLastAp = TRUE;
1250 goto done;
1251 }
1252 /*calculate AP age*/
1253 pApMetaInfo->timestamp =
1254 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1255
1256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001257 "%s: bssId "MAC_ADDRESS_STR
1258 " ch %d rssi %d timestamp %d", __func__,
1259 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1260 pApMetaInfo->ch, pApMetaInfo->rssi,
1261 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301262
1263 /*mark last AP in batch scan response*/
1264 if ((TRUE == pBatchScanRsp->isLastResult) &&
1265 (1 == numberScanList) && (1 == numApMetaInfo))
1266 {
1267 isLastAp = TRUE;
1268 }
1269
1270 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1271 /*store batch scan repsonse in hdd queue*/
1272 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1273 pScanList->scanId, isLastAp);
1274 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1275
1276 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1277 numApMetaInfo--;
1278 }
1279
Rajeev Kumarce651e42013-10-21 18:57:15 -07001280 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1281 + (sizeof(tSirBatchScanNetworkInfo)
1282 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301283 numberScanList--;
1284 }
1285
1286done:
1287
1288 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1289 requested from hdd_ioctl*/
1290 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1291 (TRUE == isLastAp))
1292 {
1293 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1294 complete(&pAdapter->hdd_get_batch_scan_req_var);
1295 }
1296
1297 return;
1298}/*End of hdd_batch_scan_result_ind_callback*/
1299
1300/**---------------------------------------------------------------------------
1301
1302 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1303 response as per batch scan FR request format by putting proper markers
1304
1305 \param - pDest pointer to destination buffer
1306 \param - cur_len current length
1307 \param - tot_len total remaining size which can be written to user space
1308 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1309 \param - pAdapter Pointer to HDD adapter
1310
1311 \return - ret no of characters written
1312
1313 --------------------------------------------------------------------------*/
1314static tANI_U32
1315hdd_format_batch_scan_rsp
1316(
1317 tANI_U8 *pDest,
1318 tANI_U32 cur_len,
1319 tANI_U32 tot_len,
1320 tHddBatchScanRsp *pApMetaInfo,
1321 hdd_adapter_t* pAdapter
1322)
1323{
1324 tANI_U32 ret = 0;
1325 tANI_U32 rem_len = 0;
1326 tANI_U8 temp_len = 0;
1327 tANI_U8 temp_total_len = 0;
1328 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1329 tANI_U8 *pTemp = temp;
1330
1331 /*Batch scan reponse needs to be returned to user space in
1332 following format:
1333 "scancount=X\n" where X is the number of scans in current batch
1334 batch
1335 "trunc\n" optional present if current scan truncated
1336 "bssid=XX:XX:XX:XX:XX:XX\n"
1337 "ssid=XXXX\n"
1338 "freq=X\n" frequency in Mhz
1339 "level=XX\n"
1340 "age=X\n" ms
1341 "dist=X\n" cm (-1 if not available)
1342 "errror=X\n" (-1if not available)
1343 "====\n" (end of ap marker)
1344 "####\n" (end of scan marker)
1345 "----\n" (end of results)*/
1346 /*send scan result in above format to user space based on
1347 available length*/
1348 /*The GET response may have more data than the driver can return in its
1349 buffer. In that case the buffer should be filled to the nearest complete
1350 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1351 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1352 The final buffer should end with "----\n"*/
1353
1354 /*sanity*/
1355 if (cur_len > tot_len)
1356 {
1357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1358 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1359 return 0;
1360 }
1361 else
1362 {
1363 rem_len = (tot_len - cur_len);
1364 }
1365
1366 /*end scan marker*/
1367 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1368 {
1369 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1370 pTemp += temp_len;
1371 temp_total_len += temp_len;
1372 }
1373
1374 /*bssid*/
1375 temp_len = snprintf(pTemp, sizeof(temp),
1376 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1377 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1378 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1379 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1380 pTemp += temp_len;
1381 temp_total_len += temp_len;
1382
1383 /*ssid*/
1384 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1385 pApMetaInfo->ApInfo.ssid);
1386 pTemp += temp_len;
1387 temp_total_len += temp_len;
1388
1389 /*freq*/
1390 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001391 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301392 pTemp += temp_len;
1393 temp_total_len += temp_len;
1394
1395 /*level*/
1396 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1397 pApMetaInfo->ApInfo.rssi);
1398 pTemp += temp_len;
1399 temp_total_len += temp_len;
1400
1401 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001402 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301403 pApMetaInfo->ApInfo.age);
1404 pTemp += temp_len;
1405 temp_total_len += temp_len;
1406
1407 /*dist*/
1408 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1409 pTemp += temp_len;
1410 temp_total_len += temp_len;
1411
1412 /*error*/
1413 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1414 pTemp += temp_len;
1415 temp_total_len += temp_len;
1416
1417 /*end AP marker*/
1418 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1419 pTemp += temp_len;
1420 temp_total_len += temp_len;
1421
1422 /*last AP in batch scan response*/
1423 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1424 {
1425 /*end scan marker*/
1426 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1427 pTemp += temp_len;
1428 temp_total_len += temp_len;
1429
1430 /*end batch scan result marker*/
1431 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1432 pTemp += temp_len;
1433 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001434
Rajeev79dbe4c2013-10-05 11:03:42 +05301435 }
1436
1437 if (temp_total_len < rem_len)
1438 {
1439 ret = temp_total_len + 1;
1440 strlcpy(pDest, temp, ret);
1441 pAdapter->isTruncated = FALSE;
1442 }
1443 else
1444 {
1445 pAdapter->isTruncated = TRUE;
1446 if (rem_len >= strlen("%%%%"))
1447 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001448 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301449 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001450 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301451 {
1452 ret = 0;
1453 }
1454 }
1455
1456 return ret;
1457
1458}/*End of hdd_format_batch_scan_rsp*/
1459
1460/**---------------------------------------------------------------------------
1461
1462 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1463 buffer starting with head of hdd batch scan response queue
1464
1465 \param - pAdapter Pointer to HDD adapter
1466 \param - pDest Pointer to user data buffer
1467 \param - cur_len current offset in user buffer
1468 \param - rem_len remaining no of bytes in user buffer
1469
1470 \return - number of bytes written in user buffer
1471
1472 --------------------------------------------------------------------------*/
1473
1474tANI_U32 hdd_populate_user_batch_scan_rsp
1475(
1476 hdd_adapter_t* pAdapter,
1477 tANI_U8 *pDest,
1478 tANI_U32 cur_len,
1479 tANI_U32 rem_len
1480)
1481{
1482 tHddBatchScanRsp *pHead;
1483 tHddBatchScanRsp *pPrev;
1484 tANI_U32 len;
1485
Rajeev79dbe4c2013-10-05 11:03:42 +05301486 pAdapter->isTruncated = FALSE;
1487
1488 /*head of hdd batch scan response queue*/
1489 pHead = pAdapter->pBatchScanRsp;
1490 while (pHead)
1491 {
1492 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1493 pAdapter);
1494 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001495 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301496 cur_len += len;
1497 if(TRUE == pAdapter->isTruncated)
1498 {
1499 /*result is truncated return rest of scan rsp in next req*/
1500 cur_len = rem_len;
1501 break;
1502 }
1503 pPrev = pHead;
1504 pHead = pHead->pNext;
1505 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001506 if (TRUE == pPrev->ApInfo.isLastAp)
1507 {
1508 pAdapter->prev_batch_id = 0;
1509 }
1510 else
1511 {
1512 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1513 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301514 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001515 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301516 }
1517
1518 return cur_len;
1519}/*End of hdd_populate_user_batch_scan_rsp*/
1520
1521/**---------------------------------------------------------------------------
1522
1523 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1524 scan response data from HDD queue to user space
1525 It does following in detail:
1526 a) if HDD has enough data in its queue then it 1st copies data to user
1527 space and then send get batch scan indication message to FW. In this
1528 case it does not wait on any event and batch scan response data will
1529 be populated in HDD response queue in MC thread context after receiving
1530 indication from FW
1531 b) else send get batch scan indication message to FW and wait on an event
1532 which will be set once HDD receives complete batch scan response from
1533 FW and then this function returns batch scan response to user space
1534
1535 \param - pAdapter Pointer to HDD adapter
1536 \param - pPrivData Pointer to priv_data
1537
1538 \return - 0 for success -EFAULT for failure
1539
1540 --------------------------------------------------------------------------*/
1541
1542int hdd_return_batch_scan_rsp_to_user
1543(
1544 hdd_adapter_t* pAdapter,
1545 hdd_priv_data_t *pPrivData,
1546 tANI_U8 *command
1547)
1548{
1549 tANI_U8 *pDest;
1550 tANI_U32 count = 0;
1551 tANI_U32 len = 0;
1552 tANI_U32 cur_len = 0;
1553 tANI_U32 rem_len = 0;
1554 eHalStatus halStatus;
1555 unsigned long rc;
1556 tSirTriggerBatchScanResultInd *pReq;
1557
1558 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1559 pReq->param = 0;/*batch scan client*/
1560 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1561 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1562
1563 cur_len = pPrivData->used_len;
1564 if (pPrivData->total_len > pPrivData->used_len)
1565 {
1566 rem_len = pPrivData->total_len - pPrivData->used_len;
1567 }
1568 else
1569 {
1570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1571 "%s: Invalid user data buffer total_len %d used_len %d",
1572 __func__, pPrivData->total_len, pPrivData->used_len);
1573 return -EFAULT;
1574 }
1575
1576 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1577 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1578 cur_len, rem_len);
1579 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1580
1581 /*enough scan result available in cache to return to user space or
1582 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001583 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301584 {
1585 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1586 halStatus = sme_TriggerBatchScanResultInd(
1587 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1588 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1589 pAdapter);
1590 if ( eHAL_STATUS_SUCCESS == halStatus )
1591 {
1592 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1593 {
1594 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1595 rc = wait_for_completion_timeout(
1596 &pAdapter->hdd_get_batch_scan_req_var,
1597 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1598 if (0 == rc)
1599 {
1600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1601 "%s: Timeout waiting to fetch batch scan rsp from fw",
1602 __func__);
1603 return -EFAULT;
1604 }
1605 }
1606
1607 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001608 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301609 pDest += len;
1610 cur_len += len;
1611
1612 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1613 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1614 cur_len, rem_len);
1615 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1616
1617 count = 0;
1618 len = (len - pPrivData->used_len);
1619 pDest = (command + pPrivData->used_len);
1620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001621 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301622 while(count < len)
1623 {
1624 printk("%c", *(pDest + count));
1625 count++;
1626 }
1627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1628 "%s: copy %d data to user buffer", __func__, len);
1629 if (copy_to_user(pPrivData->buf, pDest, len))
1630 {
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1632 "%s: failed to copy data to user buffer", __func__);
1633 return -EFAULT;
1634 }
1635 }
1636 else
1637 {
1638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1639 "sme_GetBatchScanScan returned failure halStatus %d",
1640 halStatus);
1641 return -EINVAL;
1642 }
1643 }
1644 else
1645 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301646 count = 0;
1647 len = (len - pPrivData->used_len);
1648 pDest = (command + pPrivData->used_len);
1649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001650 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301651 while(count < len)
1652 {
1653 printk("%c", *(pDest + count));
1654 count++;
1655 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1657 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301658 if (copy_to_user(pPrivData->buf, pDest, len))
1659 {
1660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1661 "%s: failed to copy data to user buffer", __func__);
1662 return -EFAULT;
1663 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301664 }
1665
1666 return 0;
1667} /*End of hdd_return_batch_scan_rsp_to_user*/
1668
Rajeev Kumar8b373292014-01-08 20:36:55 -08001669
1670/**---------------------------------------------------------------------------
1671
1672 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1673 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1674 WLS_BATCHING VERSION
1675 WLS_BATCHING SET
1676 WLS_BATCHING GET
1677 WLS_BATCHING STOP
1678
1679 \param - pAdapter Pointer to HDD adapter
1680 \param - pPrivdata Pointer to priv_data
1681 \param - command Pointer to command
1682
1683 \return - 0 for success -EFAULT for failure
1684
1685 --------------------------------------------------------------------------*/
1686
1687int hdd_handle_batch_scan_ioctl
1688(
1689 hdd_adapter_t *pAdapter,
1690 hdd_priv_data_t *pPrivdata,
1691 tANI_U8 *command
1692)
1693{
1694 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001695 hdd_context_t *pHddCtx;
1696
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301697 ENTER();
1698
Yue Mae36e3552014-03-05 17:06:20 -08001699 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1700 ret = wlan_hdd_validate_context(pHddCtx);
1701 if (ret)
1702 {
Yue Mae36e3552014-03-05 17:06:20 -08001703 goto exit;
1704 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001705
1706 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1707 {
1708 char extra[32];
1709 tANI_U8 len = 0;
1710 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1711
1712 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1713 {
1714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1715 "%s: Batch scan feature is not supported by FW", __func__);
1716 ret = -EINVAL;
1717 goto exit;
1718 }
1719
1720 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1721 version);
1722 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1723 {
1724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1725 "%s: failed to copy data to user buffer", __func__);
1726 ret = -EFAULT;
1727 goto exit;
1728 }
1729 ret = HDD_BATCH_SCAN_VERSION;
1730 }
1731 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1732 {
1733 int status;
1734 tANI_U8 *value = (command + 16);
1735 eHalStatus halStatus;
1736 unsigned long rc;
1737 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1738 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1739
1740 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1741 {
1742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1743 "%s: Batch scan feature is not supported by FW", __func__);
1744 ret = -EINVAL;
1745 goto exit;
1746 }
1747
1748 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1749 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1750 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1751 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1752 {
1753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301754 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001755 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301756 hdd_device_modetoString(pAdapter->device_mode),
1757 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001758 ret = -EINVAL;
1759 goto exit;
1760 }
1761
1762 status = hdd_parse_set_batchscan_command(value, pReq);
1763 if (status)
1764 {
1765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1766 "Invalid WLS_BATCHING SET command");
1767 ret = -EINVAL;
1768 goto exit;
1769 }
1770
1771
1772 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1773 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1774 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1775 pAdapter);
1776
1777 if ( eHAL_STATUS_SUCCESS == halStatus )
1778 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301779 char extra[32];
1780 tANI_U8 len = 0;
1781 tANI_U8 mScan = 0;
1782
Rajeev Kumar8b373292014-01-08 20:36:55 -08001783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1784 "sme_SetBatchScanReq returned success halStatus %d",
1785 halStatus);
1786 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1787 {
1788 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1789 rc = wait_for_completion_timeout(
1790 &pAdapter->hdd_set_batch_scan_req_var,
1791 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1792 if (0 == rc)
1793 {
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1795 "%s: Timeout waiting for set batch scan to complete",
1796 __func__);
1797 ret = -EINVAL;
1798 goto exit;
1799 }
1800 }
1801 if ( !pRsp->nScansToBatch )
1802 {
1803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1804 "%s: Received set batch scan failure response from FW",
1805 __func__);
1806 ret = -EINVAL;
1807 goto exit;
1808 }
1809 /*As per the Batch Scan Framework API we should return the MIN of
1810 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301811 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001812
1813 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1814
1815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1816 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301817 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1818 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1819 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1820 {
1821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1822 "%s: failed to copy MSCAN value to user buffer", __func__);
1823 ret = -EFAULT;
1824 goto exit;
1825 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001826 }
1827 else
1828 {
1829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1830 "sme_SetBatchScanReq returned failure halStatus %d",
1831 halStatus);
1832 ret = -EINVAL;
1833 goto exit;
1834 }
1835 }
1836 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1837 {
1838 eHalStatus halStatus;
1839 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1840 pInd->param = 0;
1841
1842 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1843 {
1844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1845 "%s: Batch scan feature is not supported by FW", __func__);
1846 ret = -EINVAL;
1847 goto exit;
1848 }
1849
1850 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1851 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001853 "Batch scan is not yet enabled batch scan state %d",
1854 pAdapter->batchScanState);
1855 ret = -EINVAL;
1856 goto exit;
1857 }
1858
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001859 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1860 hdd_deinit_batch_scan(pAdapter);
1861 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1862
Rajeev Kumar8b373292014-01-08 20:36:55 -08001863 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1864
1865 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1866 pAdapter->sessionId);
1867 if ( eHAL_STATUS_SUCCESS == halStatus )
1868 {
1869 ret = 0;
1870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1871 "sme_StopBatchScanInd returned success halStatus %d",
1872 halStatus);
1873 }
1874 else
1875 {
1876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1877 "sme_StopBatchScanInd returned failure halStatus %d",
1878 halStatus);
1879 ret = -EINVAL;
1880 goto exit;
1881 }
1882 }
1883 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1884 {
1885 tANI_U32 remain_len;
1886
1887 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1888 {
1889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1890 "%s: Batch scan feature is not supported by FW", __func__);
1891 ret = -EINVAL;
1892 goto exit;
1893 }
1894
1895 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1896 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001898 "Batch scan is not yet enabled could not return results"
1899 "Batch Scan state %d",
1900 pAdapter->batchScanState);
1901 ret = -EINVAL;
1902 goto exit;
1903 }
1904
1905 pPrivdata->used_len = 16;
1906 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1907 if (remain_len < pPrivdata->total_len)
1908 {
1909 /*Clear previous batch scan response data if any*/
1910 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1911 }
1912 else
1913 {
1914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1915 "Invalid total length from user space can't fetch batch"
1916 " scan response total_len %d used_len %d remain len %d",
1917 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1918 ret = -EINVAL;
1919 goto exit;
1920 }
1921 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1922 }
1923
1924exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301925 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001926 return ret;
1927}
1928
1929
Rajeev79dbe4c2013-10-05 11:03:42 +05301930#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1931
c_hpothu92367912014-05-01 15:18:17 +05301932static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1933{
c_hpothu39eb1e32014-06-26 16:31:50 +05301934 bcnMissRateContext_t *pCBCtx;
1935
1936 if (NULL == data)
1937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1939 return;
1940 }
c_hpothu92367912014-05-01 15:18:17 +05301941
1942 /* there is a race condition that exists between this callback
1943 function and the caller since the caller could time out either
1944 before or while this code is executing. we use a spinlock to
1945 serialize these actions */
1946 spin_lock(&hdd_context_lock);
1947
c_hpothu39eb1e32014-06-26 16:31:50 +05301948 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301949 gbcnMissRate = -1;
1950
c_hpothu39eb1e32014-06-26 16:31:50 +05301951 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301952 {
1953 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301954 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301955 spin_unlock(&hdd_context_lock);
1956 return ;
1957 }
1958
1959 if (VOS_STATUS_SUCCESS == status)
1960 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301961 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301962 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301963 else
1964 {
1965 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1966 }
1967
c_hpothu92367912014-05-01 15:18:17 +05301968 complete(&(pCBCtx->completion));
1969 spin_unlock(&hdd_context_lock);
1970
1971 return;
1972}
1973
Abhishek Singh08aa7762014-12-16 13:59:03 +05301974void hdd_FWStatisCB( VOS_STATUS status,
1975 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301976{
1977 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301978 hdd_adapter_t *pAdapter;
1979
1980 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1981
Abhishek Singh08aa7762014-12-16 13:59:03 +05301982 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301983 {
1984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1985 return;
1986 }
1987 /* there is a race condition that exists between this callback
1988 function and the caller since the caller could time out either
1989 before or while this code is executing. we use a spinlock to
1990 serialize these actions */
1991 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301992 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301993 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR,
1996 FL("invalid context magic: %08x"), fwStatsCtx->magic);
1997 spin_unlock(&hdd_context_lock);
1998 return;
1999 }
2000 pAdapter = fwStatsCtx->pAdapter;
2001 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2002 {
2003 hddLog(VOS_TRACE_LEVEL_ERROR,
2004 FL("pAdapter returned is NULL or invalid"));
2005 spin_unlock(&hdd_context_lock);
2006 return;
2007 }
2008 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302009 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302010 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302011 switch( fwStatsResult->type )
2012 {
2013 case FW_UBSP_STATS:
2014 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302015 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302016 hddLog(VOS_TRACE_LEVEL_INFO,
2017 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302018 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2019 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302020 }
2021 break;
2022 default:
2023 {
2024 hddLog(VOS_TRACE_LEVEL_ERROR,
2025 FL(" No handling for stats type %d"),fwStatsResult->type);
2026 }
2027 }
2028 }
2029 complete(&(fwStatsCtx->completion));
2030 spin_unlock(&hdd_context_lock);
2031 return;
2032}
2033
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302034static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2035{
2036 int ret = 0;
2037
2038 if (!pCfg || !command || !extra || !len)
2039 {
2040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2041 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2042 ret = -EINVAL;
2043 return ret;
2044 }
2045
2046 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2047 {
2048 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2049 (int)pCfg->nActiveMaxChnTime);
2050 return ret;
2051 }
2052 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2053 {
2054 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2055 (int)pCfg->nActiveMinChnTime);
2056 return ret;
2057 }
2058 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2059 {
2060 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2061 (int)pCfg->nPassiveMaxChnTime);
2062 return ret;
2063 }
2064 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2065 {
2066 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2067 (int)pCfg->nPassiveMinChnTime);
2068 return ret;
2069 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302070 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2071 {
2072 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2073 (int)pCfg->nActiveMaxChnTime);
2074 return ret;
2075 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302076 else
2077 {
2078 ret = -EINVAL;
2079 }
2080
2081 return ret;
2082}
2083
2084static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2085{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302086 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302087 hdd_config_t *pCfg;
2088 tANI_U8 *value = command;
2089 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302090 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302091
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302092 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2093 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302094 {
2095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2096 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2097 ret = -EINVAL;
2098 return ret;
2099 }
2100
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302101 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2102 sme_GetConfigParam(hHal, &smeConfig);
2103
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302104 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2105 {
2106 value = value + 24;
2107 temp = kstrtou32(value, 10, &val);
2108 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2109 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2110 {
2111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2112 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2113 ret = -EFAULT;
2114 return ret;
2115 }
2116 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302117 smeConfig.csrConfig.nActiveMaxChnTime = val;
2118 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302119 }
2120 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2121 {
2122 value = value + 24;
2123 temp = kstrtou32(value, 10, &val);
2124 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2125 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2126 {
2127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2128 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2129 ret = -EFAULT;
2130 return ret;
2131 }
2132 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302133 smeConfig.csrConfig.nActiveMinChnTime = val;
2134 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302135 }
2136 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2137 {
2138 value = value + 25;
2139 temp = kstrtou32(value, 10, &val);
2140 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2141 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2142 {
2143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2144 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2145 ret = -EFAULT;
2146 return ret;
2147 }
2148 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302149 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2150 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302151 }
2152 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2153 {
2154 value = value + 25;
2155 temp = kstrtou32(value, 10, &val);
2156 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2157 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2158 {
2159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2160 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2161 ret = -EFAULT;
2162 return ret;
2163 }
2164 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302165 smeConfig.csrConfig.nPassiveMinChnTime = val;
2166 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302167 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302168 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2169 {
2170 value = value + 13;
2171 temp = kstrtou32(value, 10, &val);
2172 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2173 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2174 {
2175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2176 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2177 ret = -EFAULT;
2178 return ret;
2179 }
2180 pCfg->nActiveMaxChnTime = val;
2181 smeConfig.csrConfig.nActiveMaxChnTime = val;
2182 sme_UpdateConfig(hHal, &smeConfig);
2183 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302184 else
2185 {
2186 ret = -EINVAL;
2187 }
2188
2189 return ret;
2190}
2191
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002192static int hdd_driver_command(hdd_adapter_t *pAdapter,
2193 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002194{
Jeff Johnson295189b2012-06-20 16:38:30 -07002195 hdd_priv_data_t priv_data;
2196 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302197 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2198 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002199 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302200 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302201
2202 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002203 /*
2204 * Note that valid pointers are provided by caller
2205 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002206
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002207 /* copy to local struct to avoid numerous changes to legacy code */
2208 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002209
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002210 if (priv_data.total_len <= 0 ||
2211 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002212 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002213 hddLog(VOS_TRACE_LEVEL_WARN,
2214 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2215 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002216 ret = -EINVAL;
2217 goto exit;
2218 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302219 status = wlan_hdd_validate_context(pHddCtx);
2220 if (0 != status)
2221 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302222 ret = -EINVAL;
2223 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302224 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002225 /* Allocate +1 for '\0' */
2226 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002227 if (!command)
2228 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002229 hddLog(VOS_TRACE_LEVEL_ERROR,
2230 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 ret = -ENOMEM;
2232 goto exit;
2233 }
2234
2235 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2236 {
2237 ret = -EFAULT;
2238 goto exit;
2239 }
2240
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002241 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002242 command[priv_data.total_len] = '\0';
2243
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002244 /* at one time the following block of code was conditional. braces
2245 * have been retained to avoid re-indenting the legacy code
2246 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002247 {
2248 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2249
2250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002251 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002252
2253 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2254 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302255 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2256 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2257 pAdapter->sessionId, (unsigned)
2258 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2259 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2260 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2261 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002262 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2263 sizeof(tSirMacAddr)))
2264 {
2265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002266 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002267 ret = -EFAULT;
2268 }
2269 }
Amar Singhal0974e402013-02-12 14:27:46 -08002270 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002271 {
Amar Singhal0974e402013-02-12 14:27:46 -08002272 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002273
Jeff Johnson295189b2012-06-20 16:38:30 -07002274 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002275
2276 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002277 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002279 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07002280 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002281 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302282 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302283 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002284 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002285 }
Kiet Lamf040f472013-11-20 21:15:23 +05302286 else if(strncmp(command, "SETWMMPS", 8) == 0)
2287 {
2288 tANI_U8 *ptr = command;
2289 ret = hdd_wmmps_helper(pAdapter, ptr);
2290 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302291
2292 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2293 {
2294 tANI_U8 *ptr = command;
2295 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2296 }
2297
Jeff Johnson32d95a32012-09-10 13:15:23 -07002298 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2299 {
2300 char *country_code;
2301
2302 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002303
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002304 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002305 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002306#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302307 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002308#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002309 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2310 (void *)(tSmeChangeCountryCallback)
2311 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302312 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002313 if (eHAL_STATUS_SUCCESS == ret)
2314 {
2315 ret = wait_for_completion_interruptible_timeout(
2316 &pAdapter->change_country_code,
2317 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2318 if (0 >= ret)
2319 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302321 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002322 }
2323 }
2324 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002325 {
2326 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002327 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002328 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002329 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002330
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002331 }
2332 /*
2333 command should be a string having format
2334 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2335 */
Amar Singhal0974e402013-02-12 14:27:46 -08002336 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002337 {
Amar Singhal0974e402013-02-12 14:27:46 -08002338 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002339
2340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002341 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002342
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002343 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002344 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002345 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2346 {
2347 int suspend = 0;
2348 tANI_U8 *ptr = (tANI_U8*)command + 15;
2349
2350 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302351 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2352 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2353 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002354 hdd_set_wlan_suspend_mode(suspend);
2355 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002356#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2357 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2358 {
2359 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002360 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002361 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2362 eHalStatus status = eHAL_STATUS_SUCCESS;
2363
2364 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2365 value = value + 15;
2366
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002367 /* Convert the value from ascii to integer */
2368 ret = kstrtos8(value, 10, &rssi);
2369 if (ret < 0)
2370 {
2371 /* If the input value is greater than max value of datatype, then also
2372 kstrtou8 fails */
2373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2374 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002375 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002376 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2377 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2378 ret = -EINVAL;
2379 goto exit;
2380 }
2381
Srinivas Girigowdade697412013-02-14 16:31:48 -08002382 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002383
Srinivas Girigowdade697412013-02-14 16:31:48 -08002384 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2385 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2386 {
2387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2388 "Neighbor lookup threshold value %d is out of range"
2389 " (Min: %d Max: %d)", lookUpThreshold,
2390 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2391 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2392 ret = -EINVAL;
2393 goto exit;
2394 }
2395
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302396 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2397 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2398 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2400 "%s: Received Command to Set Roam trigger"
2401 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2402
2403 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2404 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2405 if (eHAL_STATUS_SUCCESS != status)
2406 {
2407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2408 "%s: Failed to set roam trigger, try again", __func__);
2409 ret = -EPERM;
2410 goto exit;
2411 }
2412
2413 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302414 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002415 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2416 }
2417 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2418 {
2419 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2420 int rssi = (-1) * lookUpThreshold;
2421 char extra[32];
2422 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302423 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2424 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2425 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002426 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002427 if (copy_to_user(priv_data.buf, &extra, len + 1))
2428 {
2429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2430 "%s: failed to copy data to user buffer", __func__);
2431 ret = -EFAULT;
2432 goto exit;
2433 }
2434 }
2435 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2436 {
2437 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002438 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002439 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002440
Srinivas Girigowdade697412013-02-14 16:31:48 -08002441 /* input refresh period is in terms of seconds */
2442 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2443 value = value + 18;
2444 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002445 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002446 if (ret < 0)
2447 {
2448 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002449 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002451 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002452 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002453 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2454 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002455 ret = -EINVAL;
2456 goto exit;
2457 }
2458
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002459 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2460 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002461 {
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002463 "Roam scan period value %d is out of range"
2464 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002465 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2466 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002467 ret = -EINVAL;
2468 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302469 }
2470 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2471 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2472 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002473 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002474
2475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2476 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002477 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002479 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2480 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002481 }
2482 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2483 {
2484 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2485 char extra[32];
2486 tANI_U8 len = 0;
2487
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302488 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2489 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2490 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002491 len = scnprintf(extra, sizeof(extra), "%s %d",
2492 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002493 /* Returned value is in units of seconds */
2494 if (copy_to_user(priv_data.buf, &extra, len + 1))
2495 {
2496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2497 "%s: failed to copy data to user buffer", __func__);
2498 ret = -EFAULT;
2499 goto exit;
2500 }
2501 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002502 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2503 {
2504 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002505 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002506 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002507
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002508 /* input refresh period is in terms of seconds */
2509 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2510 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002511
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002512 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002513 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002514 if (ret < 0)
2515 {
2516 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002517 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002519 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002520 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002521 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2522 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2523 ret = -EINVAL;
2524 goto exit;
2525 }
2526
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002527 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2528 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2529 {
2530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2531 "Neighbor scan results refresh period value %d is out of range"
2532 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2533 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2534 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2535 ret = -EINVAL;
2536 goto exit;
2537 }
2538 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2539
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2541 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002542 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002543
2544 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2545 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2546 }
2547 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2548 {
2549 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2550 char extra[32];
2551 tANI_U8 len = 0;
2552
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002553 len = scnprintf(extra, sizeof(extra), "%s %d",
2554 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 /* Returned value is in units of seconds */
2556 if (copy_to_user(priv_data.buf, &extra, len + 1))
2557 {
2558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2559 "%s: failed to copy data to user buffer", __func__);
2560 ret = -EFAULT;
2561 goto exit;
2562 }
2563 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002564#ifdef FEATURE_WLAN_LFR
2565 /* SETROAMMODE */
2566 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2567 {
2568 tANI_U8 *value = command;
2569 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2570
2571 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2572 value = value + SIZE_OF_SETROAMMODE + 1;
2573
2574 /* Convert the value from ascii to integer */
2575 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2576 if (ret < 0)
2577 {
2578 /* If the input value is greater than max value of datatype, then also
2579 kstrtou8 fails */
2580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2581 "%s: kstrtou8 failed range [%d - %d]", __func__,
2582 CFG_LFR_FEATURE_ENABLED_MIN,
2583 CFG_LFR_FEATURE_ENABLED_MAX);
2584 ret = -EINVAL;
2585 goto exit;
2586 }
2587 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2588 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2589 {
2590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2591 "Roam Mode value %d is out of range"
2592 " (Min: %d Max: %d)", roamMode,
2593 CFG_LFR_FEATURE_ENABLED_MIN,
2594 CFG_LFR_FEATURE_ENABLED_MAX);
2595 ret = -EINVAL;
2596 goto exit;
2597 }
2598
2599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2600 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2601 /*
2602 * Note that
2603 * SETROAMMODE 0 is to enable LFR while
2604 * SETROAMMODE 1 is to disable LFR, but
2605 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2606 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2607 */
2608 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2609 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2610 else
2611 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2612
2613 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2614 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2615 }
2616 /* GETROAMMODE */
2617 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2618 {
2619 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2620 char extra[32];
2621 tANI_U8 len = 0;
2622
2623 /*
2624 * roamMode value shall be inverted because the sementics is different.
2625 */
2626 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2627 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2628 else
2629 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2630
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002631 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002632 if (copy_to_user(priv_data.buf, &extra, len + 1))
2633 {
2634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2635 "%s: failed to copy data to user buffer", __func__);
2636 ret = -EFAULT;
2637 goto exit;
2638 }
2639 }
2640#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002641#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002642#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002643 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2644 {
2645 tANI_U8 *value = command;
2646 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2647
2648 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2649 value = value + 13;
2650 /* Convert the value from ascii to integer */
2651 ret = kstrtou8(value, 10, &roamRssiDiff);
2652 if (ret < 0)
2653 {
2654 /* If the input value is greater than max value of datatype, then also
2655 kstrtou8 fails */
2656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2657 "%s: kstrtou8 failed range [%d - %d]", __func__,
2658 CFG_ROAM_RSSI_DIFF_MIN,
2659 CFG_ROAM_RSSI_DIFF_MAX);
2660 ret = -EINVAL;
2661 goto exit;
2662 }
2663
2664 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2665 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2666 {
2667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2668 "Roam rssi diff value %d is out of range"
2669 " (Min: %d Max: %d)", roamRssiDiff,
2670 CFG_ROAM_RSSI_DIFF_MIN,
2671 CFG_ROAM_RSSI_DIFF_MAX);
2672 ret = -EINVAL;
2673 goto exit;
2674 }
2675
2676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2677 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2678
2679 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2680 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2681 }
2682 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2683 {
2684 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2685 char extra[32];
2686 tANI_U8 len = 0;
2687
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2689 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2690 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002691 len = scnprintf(extra, sizeof(extra), "%s %d",
2692 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002693 if (copy_to_user(priv_data.buf, &extra, len + 1))
2694 {
2695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2696 "%s: failed to copy data to user buffer", __func__);
2697 ret = -EFAULT;
2698 goto exit;
2699 }
2700 }
2701#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002702#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002703 else if (strncmp(command, "GETBAND", 7) == 0)
2704 {
2705 int band = -1;
2706 char extra[32];
2707 tANI_U8 len = 0;
2708 hdd_getBand_helper(pHddCtx, &band);
2709
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302710 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2711 TRACE_CODE_HDD_GETBAND_IOCTL,
2712 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002713 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002714 if (copy_to_user(priv_data.buf, &extra, len + 1))
2715 {
2716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2717 "%s: failed to copy data to user buffer", __func__);
2718 ret = -EFAULT;
2719 goto exit;
2720 }
2721 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002722 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2723 {
2724 tANI_U8 *value = command;
2725 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2726 tANI_U8 numChannels = 0;
2727 eHalStatus status = eHAL_STATUS_SUCCESS;
2728
2729 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2730 if (eHAL_STATUS_SUCCESS != status)
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: Failed to parse channel list information", __func__);
2734 ret = -EINVAL;
2735 goto exit;
2736 }
2737
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302738 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2739 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2740 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002741 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2742 {
2743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2744 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2745 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2746 ret = -EINVAL;
2747 goto exit;
2748 }
2749 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2750 numChannels);
2751 if (eHAL_STATUS_SUCCESS != status)
2752 {
2753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 "%s: Failed to update channel list information", __func__);
2755 ret = -EINVAL;
2756 goto exit;
2757 }
2758 }
2759 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2760 {
2761 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2762 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002763 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002764 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002765 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002766
2767 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2768 ChannelList, &numChannels ))
2769 {
2770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2771 "%s: failed to get roam scan channel list", __func__);
2772 ret = -EFAULT;
2773 goto exit;
2774 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302775 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2776 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2777 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002778 /* output channel list is of the format
2779 [Number of roam scan channels][Channel1][Channel2]... */
2780 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002781 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002782 for (j = 0; (j < numChannels); j++)
2783 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002784 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2785 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002786 }
2787
2788 if (copy_to_user(priv_data.buf, &extra, len + 1))
2789 {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s: failed to copy data to user buffer", __func__);
2792 ret = -EFAULT;
2793 goto exit;
2794 }
2795 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002796 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2797 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002798 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002799 char extra[32];
2800 tANI_U8 len = 0;
2801
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002802 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002803 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002804 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002805 hdd_is_okc_mode_enabled(pHddCtx) &&
2806 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2807 {
2808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002809 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002810 " hence this operation is not permitted!", __func__);
2811 ret = -EPERM;
2812 goto exit;
2813 }
2814
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002815 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002816 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002817 if (copy_to_user(priv_data.buf, &extra, len + 1))
2818 {
2819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2820 "%s: failed to copy data to user buffer", __func__);
2821 ret = -EFAULT;
2822 goto exit;
2823 }
2824 }
2825 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2826 {
2827 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2828 char extra[32];
2829 tANI_U8 len = 0;
2830
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002831 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002832 then this operation is not permitted (return FAILURE) */
2833 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002834 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002835 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2836 {
2837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002838 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002839 " hence this operation is not permitted!", __func__);
2840 ret = -EPERM;
2841 goto exit;
2842 }
2843
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002844 len = scnprintf(extra, sizeof(extra), "%s %d",
2845 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002846 if (copy_to_user(priv_data.buf, &extra, len + 1))
2847 {
2848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2849 "%s: failed to copy data to user buffer", __func__);
2850 ret = -EFAULT;
2851 goto exit;
2852 }
2853 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002854 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002855 {
2856 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2857 char extra[32];
2858 tANI_U8 len = 0;
2859
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002860 len = scnprintf(extra, sizeof(extra), "%s %d",
2861 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002862 if (copy_to_user(priv_data.buf, &extra, len + 1))
2863 {
2864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2865 "%s: failed to copy data to user buffer", __func__);
2866 ret = -EFAULT;
2867 goto exit;
2868 }
2869 }
2870 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2871 {
2872 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2873 char extra[32];
2874 tANI_U8 len = 0;
2875
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002876 len = scnprintf(extra, sizeof(extra), "%s %d",
2877 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002878 if (copy_to_user(priv_data.buf, &extra, len + 1))
2879 {
2880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2881 "%s: failed to copy data to user buffer", __func__);
2882 ret = -EFAULT;
2883 goto exit;
2884 }
2885 }
2886 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2887 {
2888 tANI_U8 *value = command;
2889 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2890
2891 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2892 value = value + 26;
2893 /* Convert the value from ascii to integer */
2894 ret = kstrtou8(value, 10, &minTime);
2895 if (ret < 0)
2896 {
2897 /* If the input value is greater than max value of datatype, then also
2898 kstrtou8 fails */
2899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2900 "%s: kstrtou8 failed range [%d - %d]", __func__,
2901 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2902 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2903 ret = -EINVAL;
2904 goto exit;
2905 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002906 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2907 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2908 {
2909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2910 "scan min channel time value %d is out of range"
2911 " (Min: %d Max: %d)", minTime,
2912 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2913 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2914 ret = -EINVAL;
2915 goto exit;
2916 }
2917
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302918 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2919 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2920 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2922 "%s: Received Command to change channel min time = %d", __func__, minTime);
2923
2924 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2925 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2926 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002927 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2928 {
2929 tANI_U8 *value = command;
2930 tANI_U8 channel = 0;
2931 tANI_U8 dwellTime = 0;
2932 tANI_U8 bufLen = 0;
2933 tANI_U8 *buf = NULL;
2934 tSirMacAddr targetApBssid;
2935 eHalStatus status = eHAL_STATUS_SUCCESS;
2936 struct ieee80211_channel chan;
2937 tANI_U8 finalLen = 0;
2938 tANI_U8 *finalBuf = NULL;
2939 tANI_U8 temp = 0;
2940 u64 cookie;
2941 hdd_station_ctx_t *pHddStaCtx = NULL;
2942 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2943
2944 /* if not associated, no need to send action frame */
2945 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2946 {
2947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2948 ret = -EINVAL;
2949 goto exit;
2950 }
2951
2952 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2953 &dwellTime, &buf, &bufLen);
2954 if (eHAL_STATUS_SUCCESS != status)
2955 {
2956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2957 "%s: Failed to parse send action frame data", __func__);
2958 ret = -EINVAL;
2959 goto exit;
2960 }
2961
2962 /* if the target bssid is different from currently associated AP,
2963 then no need to send action frame */
2964 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2965 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2966 {
2967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2968 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002969 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002970 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002971 goto exit;
2972 }
2973
2974 /* if the channel number is different from operating channel then
2975 no need to send action frame */
2976 if (channel != pHddStaCtx->conn_info.operationChannel)
2977 {
2978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2979 "%s: channel(%d) is different from operating channel(%d)",
2980 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2981 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002982 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002983 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002984 goto exit;
2985 }
2986 chan.center_freq = sme_ChnToFreq(channel);
2987
2988 finalLen = bufLen + 24;
2989 finalBuf = vos_mem_malloc(finalLen);
2990 if (NULL == finalBuf)
2991 {
2992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2993 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002994 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002995 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002996 goto exit;
2997 }
2998 vos_mem_zero(finalBuf, finalLen);
2999
3000 /* Fill subtype */
3001 temp = SIR_MAC_MGMT_ACTION << 4;
3002 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3003
3004 /* Fill type */
3005 temp = SIR_MAC_MGMT_FRAME;
3006 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3007
3008 /* Fill destination address (bssid of the AP) */
3009 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3010
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003011 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003012 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3013
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003014 /* Fill BSSID (AP mac address) */
3015 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003016
3017 /* Fill received buffer from 24th address */
3018 vos_mem_copy(finalBuf + 24, buf, bufLen);
3019
Jeff Johnson11c33152013-04-16 17:52:40 -07003020 /* done with the parsed buffer */
3021 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003022 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003023
DARAM SUDHA39eede62014-02-12 11:16:40 +05303024 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3026 &(pAdapter->wdev),
3027#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003028 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003029#endif
3030 &chan, 0,
3031#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3032 NL80211_CHAN_HT20, 1,
3033#endif
3034 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003035 1, &cookie );
3036 vos_mem_free(finalBuf);
3037 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003038 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3039 {
3040 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3041 char extra[32];
3042 tANI_U8 len = 0;
3043
3044 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003045 len = scnprintf(extra, sizeof(extra), "%s %d",
3046 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303047 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3048 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3049 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003050 if (copy_to_user(priv_data.buf, &extra, len + 1))
3051 {
3052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3053 "%s: failed to copy data to user buffer", __func__);
3054 ret = -EFAULT;
3055 goto exit;
3056 }
3057 }
3058 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3059 {
3060 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003061 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003062
3063 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3064 value = value + 19;
3065 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003066 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003067 if (ret < 0)
3068 {
3069 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003070 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003072 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003073 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3074 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3075 ret = -EINVAL;
3076 goto exit;
3077 }
3078
3079 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3080 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3081 {
3082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3083 "lfr mode value %d is out of range"
3084 " (Min: %d Max: %d)", maxTime,
3085 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3086 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3087 ret = -EINVAL;
3088 goto exit;
3089 }
3090
3091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3092 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3093
3094 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3095 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3096 }
3097 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3098 {
3099 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3100 char extra[32];
3101 tANI_U8 len = 0;
3102
3103 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003104 len = scnprintf(extra, sizeof(extra), "%s %d",
3105 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003106 if (copy_to_user(priv_data.buf, &extra, len + 1))
3107 {
3108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3109 "%s: failed to copy data to user buffer", __func__);
3110 ret = -EFAULT;
3111 goto exit;
3112 }
3113 }
3114 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3115 {
3116 tANI_U8 *value = command;
3117 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3118
3119 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3120 value = value + 16;
3121 /* Convert the value from ascii to integer */
3122 ret = kstrtou16(value, 10, &val);
3123 if (ret < 0)
3124 {
3125 /* If the input value is greater than max value of datatype, then also
3126 kstrtou16 fails */
3127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3128 "%s: kstrtou16 failed range [%d - %d]", __func__,
3129 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3130 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3131 ret = -EINVAL;
3132 goto exit;
3133 }
3134
3135 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3136 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3137 {
3138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3139 "scan home time value %d is out of range"
3140 " (Min: %d Max: %d)", val,
3141 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3142 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3143 ret = -EINVAL;
3144 goto exit;
3145 }
3146
3147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3148 "%s: Received Command to change scan home time = %d", __func__, val);
3149
3150 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3151 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3152 }
3153 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3154 {
3155 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3156 char extra[32];
3157 tANI_U8 len = 0;
3158
3159 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003160 len = scnprintf(extra, sizeof(extra), "%s %d",
3161 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003162 if (copy_to_user(priv_data.buf, &extra, len + 1))
3163 {
3164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3165 "%s: failed to copy data to user buffer", __func__);
3166 ret = -EFAULT;
3167 goto exit;
3168 }
3169 }
3170 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3171 {
3172 tANI_U8 *value = command;
3173 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3174
3175 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3176 value = value + 17;
3177 /* Convert the value from ascii to integer */
3178 ret = kstrtou8(value, 10, &val);
3179 if (ret < 0)
3180 {
3181 /* If the input value is greater than max value of datatype, then also
3182 kstrtou8 fails */
3183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3184 "%s: kstrtou8 failed range [%d - %d]", __func__,
3185 CFG_ROAM_INTRA_BAND_MIN,
3186 CFG_ROAM_INTRA_BAND_MAX);
3187 ret = -EINVAL;
3188 goto exit;
3189 }
3190
3191 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3192 (val > CFG_ROAM_INTRA_BAND_MAX))
3193 {
3194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3195 "intra band mode value %d is out of range"
3196 " (Min: %d Max: %d)", val,
3197 CFG_ROAM_INTRA_BAND_MIN,
3198 CFG_ROAM_INTRA_BAND_MAX);
3199 ret = -EINVAL;
3200 goto exit;
3201 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3203 "%s: Received Command to change intra band = %d", __func__, val);
3204
3205 pHddCtx->cfg_ini->nRoamIntraBand = val;
3206 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3207 }
3208 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3209 {
3210 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3211 char extra[32];
3212 tANI_U8 len = 0;
3213
3214 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003215 len = scnprintf(extra, sizeof(extra), "%s %d",
3216 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003217 if (copy_to_user(priv_data.buf, &extra, len + 1))
3218 {
3219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3220 "%s: failed to copy data to user buffer", __func__);
3221 ret = -EFAULT;
3222 goto exit;
3223 }
3224 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003225 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3226 {
3227 tANI_U8 *value = command;
3228 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3229
3230 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3231 value = value + 15;
3232 /* Convert the value from ascii to integer */
3233 ret = kstrtou8(value, 10, &nProbes);
3234 if (ret < 0)
3235 {
3236 /* If the input value is greater than max value of datatype, then also
3237 kstrtou8 fails */
3238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3239 "%s: kstrtou8 failed range [%d - %d]", __func__,
3240 CFG_ROAM_SCAN_N_PROBES_MIN,
3241 CFG_ROAM_SCAN_N_PROBES_MAX);
3242 ret = -EINVAL;
3243 goto exit;
3244 }
3245
3246 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3247 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3248 {
3249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3250 "NProbes value %d is out of range"
3251 " (Min: %d Max: %d)", nProbes,
3252 CFG_ROAM_SCAN_N_PROBES_MIN,
3253 CFG_ROAM_SCAN_N_PROBES_MAX);
3254 ret = -EINVAL;
3255 goto exit;
3256 }
3257
3258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3259 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3260
3261 pHddCtx->cfg_ini->nProbes = nProbes;
3262 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3263 }
3264 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3265 {
3266 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3267 char extra[32];
3268 tANI_U8 len = 0;
3269
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003270 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003271 if (copy_to_user(priv_data.buf, &extra, len + 1))
3272 {
3273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3274 "%s: failed to copy data to user buffer", __func__);
3275 ret = -EFAULT;
3276 goto exit;
3277 }
3278 }
3279 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3280 {
3281 tANI_U8 *value = command;
3282 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3283
3284 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3285 /* input value is in units of msec */
3286 value = value + 20;
3287 /* Convert the value from ascii to integer */
3288 ret = kstrtou16(value, 10, &homeAwayTime);
3289 if (ret < 0)
3290 {
3291 /* If the input value is greater than max value of datatype, then also
3292 kstrtou8 fails */
3293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3294 "%s: kstrtou8 failed range [%d - %d]", __func__,
3295 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3296 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3297 ret = -EINVAL;
3298 goto exit;
3299 }
3300
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003301 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3302 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3303 {
3304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3305 "homeAwayTime value %d is out of range"
3306 " (Min: %d Max: %d)", homeAwayTime,
3307 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3308 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3309 ret = -EINVAL;
3310 goto exit;
3311 }
3312
3313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3314 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003315 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3316 {
3317 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3318 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3319 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003320 }
3321 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3322 {
3323 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3324 char extra[32];
3325 tANI_U8 len = 0;
3326
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003327 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003328 if (copy_to_user(priv_data.buf, &extra, len + 1))
3329 {
3330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3331 "%s: failed to copy data to user buffer", __func__);
3332 ret = -EFAULT;
3333 goto exit;
3334 }
3335 }
3336 else if (strncmp(command, "REASSOC", 7) == 0)
3337 {
3338 tANI_U8 *value = command;
3339 tANI_U8 channel = 0;
3340 tSirMacAddr targetApBssid;
3341 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003342#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3343 tCsrHandoffRequest handoffInfo;
3344#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003345 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003346 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3347
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003348 /* if not associated, no need to proceed with reassoc */
3349 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3350 {
3351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3352 ret = -EINVAL;
3353 goto exit;
3354 }
3355
3356 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3357 if (eHAL_STATUS_SUCCESS != status)
3358 {
3359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3360 "%s: Failed to parse reassoc command data", __func__);
3361 ret = -EINVAL;
3362 goto exit;
3363 }
3364
3365 /* if the target bssid is same as currently associated AP,
3366 then no need to proceed with reassoc */
3367 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3368 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3369 {
3370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3371 ret = -EINVAL;
3372 goto exit;
3373 }
3374
3375 /* Check channel number is a valid channel number */
3376 if(VOS_STATUS_SUCCESS !=
3377 wlan_hdd_validate_operation_channel(pAdapter, channel))
3378 {
3379 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003380 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003381 return -EINVAL;
3382 }
3383
3384 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003385#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3386 handoffInfo.channel = channel;
3387 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3388 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3389#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003390 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003391 else if (strncmp(command, "SETWESMODE", 10) == 0)
3392 {
3393 tANI_U8 *value = command;
3394 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3395
3396 /* Move pointer to ahead of SETWESMODE<delimiter> */
3397 value = value + 11;
3398 /* Convert the value from ascii to integer */
3399 ret = kstrtou8(value, 10, &wesMode);
3400 if (ret < 0)
3401 {
3402 /* If the input value is greater than max value of datatype, then also
3403 kstrtou8 fails */
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3405 "%s: kstrtou8 failed range [%d - %d]", __func__,
3406 CFG_ENABLE_WES_MODE_NAME_MIN,
3407 CFG_ENABLE_WES_MODE_NAME_MAX);
3408 ret = -EINVAL;
3409 goto exit;
3410 }
3411
3412 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3413 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3414 {
3415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3416 "WES Mode value %d is out of range"
3417 " (Min: %d Max: %d)", wesMode,
3418 CFG_ENABLE_WES_MODE_NAME_MIN,
3419 CFG_ENABLE_WES_MODE_NAME_MAX);
3420 ret = -EINVAL;
3421 goto exit;
3422 }
3423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3424 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3425
3426 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3427 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3428 }
3429 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3430 {
3431 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3432 char extra[32];
3433 tANI_U8 len = 0;
3434
Arif Hussain826d9412013-11-12 16:44:54 -08003435 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003436 if (copy_to_user(priv_data.buf, &extra, len + 1))
3437 {
3438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3439 "%s: failed to copy data to user buffer", __func__);
3440 ret = -EFAULT;
3441 goto exit;
3442 }
3443 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003444#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003445#ifdef FEATURE_WLAN_LFR
3446 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3447 {
3448 tANI_U8 *value = command;
3449 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3450
3451 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3452 value = value + 12;
3453 /* Convert the value from ascii to integer */
3454 ret = kstrtou8(value, 10, &lfrMode);
3455 if (ret < 0)
3456 {
3457 /* If the input value is greater than max value of datatype, then also
3458 kstrtou8 fails */
3459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3460 "%s: kstrtou8 failed range [%d - %d]", __func__,
3461 CFG_LFR_FEATURE_ENABLED_MIN,
3462 CFG_LFR_FEATURE_ENABLED_MAX);
3463 ret = -EINVAL;
3464 goto exit;
3465 }
3466
3467 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3468 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3469 {
3470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3471 "lfr mode value %d is out of range"
3472 " (Min: %d Max: %d)", lfrMode,
3473 CFG_LFR_FEATURE_ENABLED_MIN,
3474 CFG_LFR_FEATURE_ENABLED_MAX);
3475 ret = -EINVAL;
3476 goto exit;
3477 }
3478
3479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3480 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3481
3482 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3483 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3484 }
3485#endif
3486#ifdef WLAN_FEATURE_VOWIFI_11R
3487 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3488 {
3489 tANI_U8 *value = command;
3490 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3491
3492 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3493 value = value + 18;
3494 /* Convert the value from ascii to integer */
3495 ret = kstrtou8(value, 10, &ft);
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_FAST_TRANSITION_ENABLED_NAME_MIN,
3503 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3504 ret = -EINVAL;
3505 goto exit;
3506 }
3507
3508 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3509 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3510 {
3511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3512 "ft mode value %d is out of range"
3513 " (Min: %d Max: %d)", ft,
3514 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3515 CFG_FAST_TRANSITION_ENABLED_NAME_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 ft mode = %d", __func__, ft);
3522
3523 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3524 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3525 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303526 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
3527 {
3528 tANI_U8 *value = command;
3529 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303530
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05303531 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
3532 value = value + 15;
3533 /* Convert the value from ascii to integer */
3534 ret = kstrtou8(value, 10, &dfsScanMode);
3535 if (ret < 0)
3536 {
3537 /* If the input value is greater than max value of
3538 datatype, then also kstrtou8 fails
3539 */
3540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3541 "%s: kstrtou8 failed range [%d - %d]", __func__,
3542 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3543 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3544 ret = -EINVAL;
3545 goto exit;
3546 }
3547
3548 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
3549 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
3550 {
3551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3552 "dfsScanMode value %d is out of range"
3553 " (Min: %d Max: %d)", dfsScanMode,
3554 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
3555 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
3556 ret = -EINVAL;
3557 goto exit;
3558 }
3559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3560 "%s: Received Command to Set DFS Scan Mode = %d",
3561 __func__, dfsScanMode);
3562
3563 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
3564 }
3565 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
3566 {
3567 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
3568 char extra[32];
3569 tANI_U8 len = 0;
3570
3571 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
3572 if (copy_to_user(priv_data.buf, &extra, len + 1))
3573 {
3574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3575 "%s: failed to copy data to user buffer", __func__);
3576 ret = -EFAULT;
3577 goto exit;
3578 }
3579 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303580 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3581 {
3582 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303583 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303584 tSirMacAddr targetApBssid;
3585 tANI_U8 trigger = 0;
3586 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303587 tHalHandle hHal;
3588 v_U32_t roamId = 0;
3589 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303590 hdd_station_ctx_t *pHddStaCtx = NULL;
3591 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303592 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303593
3594 /* if not associated, no need to proceed with reassoc */
3595 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3596 {
3597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3598 ret = -EINVAL;
3599 goto exit;
3600 }
3601
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303602 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303603 if (eHAL_STATUS_SUCCESS != status)
3604 {
3605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3606 "%s: Failed to parse reassoc command data", __func__);
3607 ret = -EINVAL;
3608 goto exit;
3609 }
3610
3611 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303612 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303613 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3614 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3615 {
3616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3617 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3618 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303619 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3620 &modProfileFields);
3621 sme_RoamReassoc(hHal, pAdapter->sessionId,
3622 NULL, modProfileFields, &roamId, 1);
3623 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303624 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303625
3626 /* Check channel number is a valid channel number */
3627 if(VOS_STATUS_SUCCESS !=
3628 wlan_hdd_validate_operation_channel(pAdapter, channel))
3629 {
3630 hddLog(VOS_TRACE_LEVEL_ERROR,
3631 "%s: Invalid Channel [%d]", __func__, channel);
3632 return -EINVAL;
3633 }
3634
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303635 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303636
3637 /* Proceed with scan/roam */
3638 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3639 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303640 (tSmeFastRoamTrigger)(trigger),
3641 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303642 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003643#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003644#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003645 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3646 {
3647 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003648 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003649
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003650 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003651 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003652 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003653 hdd_is_okc_mode_enabled(pHddCtx) &&
3654 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3655 {
3656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003657 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003658 " hence this operation is not permitted!", __func__);
3659 ret = -EPERM;
3660 goto exit;
3661 }
3662
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003663 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3664 value = value + 11;
3665 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003666 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003667 if (ret < 0)
3668 {
3669 /* If the input value is greater than max value of datatype, then also
3670 kstrtou8 fails */
3671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3672 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003673 CFG_ESE_FEATURE_ENABLED_MIN,
3674 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003675 ret = -EINVAL;
3676 goto exit;
3677 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003678 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3679 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003680 {
3681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003682 "Ese mode value %d is out of range"
3683 " (Min: %d Max: %d)", eseMode,
3684 CFG_ESE_FEATURE_ENABLED_MIN,
3685 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003686 ret = -EINVAL;
3687 goto exit;
3688 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003690 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003691
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003692 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3693 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003694 }
3695#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003696 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3697 {
3698 tANI_U8 *value = command;
3699 tANI_BOOLEAN roamScanControl = 0;
3700
3701 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3702 value = value + 19;
3703 /* Convert the value from ascii to integer */
3704 ret = kstrtou8(value, 10, &roamScanControl);
3705 if (ret < 0)
3706 {
3707 /* If the input value is greater than max value of datatype, then also
3708 kstrtou8 fails */
3709 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3710 "%s: kstrtou8 failed ", __func__);
3711 ret = -EINVAL;
3712 goto exit;
3713 }
3714
3715 if (0 != roamScanControl)
3716 {
3717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3718 "roam scan control invalid value = %d",
3719 roamScanControl);
3720 ret = -EINVAL;
3721 goto exit;
3722 }
3723 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3724 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3725
3726 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3727 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003728#ifdef FEATURE_WLAN_OKC
3729 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3730 {
3731 tANI_U8 *value = command;
3732 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3733
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003734 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003735 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003736 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003737 hdd_is_okc_mode_enabled(pHddCtx) &&
3738 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3739 {
3740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003741 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003742 " hence this operation is not permitted!", __func__);
3743 ret = -EPERM;
3744 goto exit;
3745 }
3746
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003747 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3748 value = value + 11;
3749 /* Convert the value from ascii to integer */
3750 ret = kstrtou8(value, 10, &okcMode);
3751 if (ret < 0)
3752 {
3753 /* If the input value is greater than max value of datatype, then also
3754 kstrtou8 fails */
3755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3756 "%s: kstrtou8 failed range [%d - %d]", __func__,
3757 CFG_OKC_FEATURE_ENABLED_MIN,
3758 CFG_OKC_FEATURE_ENABLED_MAX);
3759 ret = -EINVAL;
3760 goto exit;
3761 }
3762
3763 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3764 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3765 {
3766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3767 "Okc mode value %d is out of range"
3768 " (Min: %d Max: %d)", okcMode,
3769 CFG_OKC_FEATURE_ENABLED_MIN,
3770 CFG_OKC_FEATURE_ENABLED_MAX);
3771 ret = -EINVAL;
3772 goto exit;
3773 }
3774
3775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3776 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3777
3778 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3779 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003780#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003781 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3782 {
3783 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3784 char extra[32];
3785 tANI_U8 len = 0;
3786
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003787 len = scnprintf(extra, sizeof(extra), "%s %d",
3788 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003789 if (copy_to_user(priv_data.buf, &extra, len + 1))
3790 {
3791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3792 "%s: failed to copy data to user buffer", __func__);
3793 ret = -EFAULT;
3794 goto exit;
3795 }
3796 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303797#ifdef WLAN_FEATURE_PACKET_FILTERING
3798 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3799 {
3800 tANI_U8 filterType = 0;
3801 tANI_U8 *value = command;
3802
3803 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3804 value = value + 22;
3805
3806 /* Convert the value from ascii to integer */
3807 ret = kstrtou8(value, 10, &filterType);
3808 if (ret < 0)
3809 {
3810 /* If the input value is greater than max value of datatype,
3811 * then also kstrtou8 fails
3812 */
3813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3814 "%s: kstrtou8 failed range ", __func__);
3815 ret = -EINVAL;
3816 goto exit;
3817 }
3818
3819 if (filterType != 0 && filterType != 1)
3820 {
3821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3822 "%s: Accepted Values are 0 and 1 ", __func__);
3823 ret = -EINVAL;
3824 goto exit;
3825 }
3826 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3827 pAdapter->sessionId);
3828 }
3829#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303830 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3831 {
Kiet Lamad161252014-07-22 11:23:32 -07003832 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303833 int ret;
3834
Kiet Lamad161252014-07-22 11:23:32 -07003835 dhcpPhase = command + 11;
3836 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303837 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003839 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303840
3841 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003842
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303843 ret = wlan_hdd_scan_abort(pAdapter);
3844 if (ret < 0)
3845 {
3846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3847 FL("failed to abort existing scan %d"), ret);
3848 }
3849
Kiet Lamad161252014-07-22 11:23:32 -07003850 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3851 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303852 }
Kiet Lamad161252014-07-22 11:23:32 -07003853 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303854 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003856 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303857
3858 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003859
3860 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3861 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303862 }
3863 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003864 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3865 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3867 FL("making default scan to ACTIVE"));
3868 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003869 }
3870 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3871 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3873 FL("making default scan to PASSIVE"));
3874 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003875 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303876 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3877 {
3878 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3879 char extra[32];
3880 tANI_U8 len = 0;
3881
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303882 memset(extra, 0, sizeof(extra));
3883 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3884 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303885 {
3886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3887 "%s: failed to copy data to user buffer", __func__);
3888 ret = -EFAULT;
3889 goto exit;
3890 }
3891 ret = len;
3892 }
3893 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3894 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303895 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303896 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003897 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3898 {
3899 tANI_U8 filterType = 0;
3900 tANI_U8 *value;
3901 value = command + 9;
3902
3903 /* Convert the value from ascii to integer */
3904 ret = kstrtou8(value, 10, &filterType);
3905 if (ret < 0)
3906 {
3907 /* If the input value is greater than max value of datatype,
3908 * then also kstrtou8 fails
3909 */
3910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3911 "%s: kstrtou8 failed range ", __func__);
3912 ret = -EINVAL;
3913 goto exit;
3914 }
3915 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3916 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3917 {
3918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3919 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3920 " 2-Sink ", __func__);
3921 ret = -EINVAL;
3922 goto exit;
3923 }
3924 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3925 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303926 pScanInfo = &pHddCtx->scan_info;
3927 if (filterType && pScanInfo != NULL &&
3928 pHddCtx->scan_info.mScanPending)
3929 {
3930 /*Miracast Session started. Abort Scan */
3931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3932 "%s, Aborting Scan For Miracast",__func__);
3933 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3934 eCSR_SCAN_ABORT_DEFAULT);
3935 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003936 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303937 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003938 }
Leo Chang614d2072013-08-22 14:59:44 -07003939 else if (strncmp(command, "SETMCRATE", 9) == 0)
3940 {
Leo Chang614d2072013-08-22 14:59:44 -07003941 tANI_U8 *value = command;
3942 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003943 tSirRateUpdateInd *rateUpdate;
3944 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003945
3946 /* Only valid for SAP mode */
3947 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3948 {
3949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3950 "%s: SAP mode is not running", __func__);
3951 ret = -EFAULT;
3952 goto exit;
3953 }
3954
3955 /* Move pointer to ahead of SETMCRATE<delimiter> */
3956 /* input value is in units of hundred kbps */
3957 value = value + 10;
3958 /* Convert the value from ascii to integer, decimal base */
3959 ret = kstrtouint(value, 10, &targetRate);
3960
Leo Chang1f98cbd2013-10-17 15:03:52 -07003961 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3962 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003963 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003964 hddLog(VOS_TRACE_LEVEL_ERROR,
3965 "%s: SETMCRATE indication alloc fail", __func__);
3966 ret = -EFAULT;
3967 goto exit;
3968 }
3969 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3970
3971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3972 "MC Target rate %d", targetRate);
3973 /* Ignore unicast */
3974 rateUpdate->ucastDataRate = -1;
3975 rateUpdate->mcastDataRate24GHz = targetRate;
3976 rateUpdate->mcastDataRate5GHz = targetRate;
3977 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3978 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3979 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3980 if (eHAL_STATUS_SUCCESS != status)
3981 {
3982 hddLog(VOS_TRACE_LEVEL_ERROR,
3983 "%s: SET_MC_RATE failed", __func__);
3984 vos_mem_free(rateUpdate);
3985 ret = -EFAULT;
3986 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003987 }
3988 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303989#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003990 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303991 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003992 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303993 }
3994#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003995#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003996 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3997 {
3998 tANI_U8 *value = command;
3999 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4000 tANI_U8 numChannels = 0;
4001 eHalStatus status = eHAL_STATUS_SUCCESS;
4002
4003 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4004 if (eHAL_STATUS_SUCCESS != status)
4005 {
4006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4007 "%s: Failed to parse channel list information", __func__);
4008 ret = -EINVAL;
4009 goto exit;
4010 }
4011
4012 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4013 {
4014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4015 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4016 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4017 ret = -EINVAL;
4018 goto exit;
4019 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004020 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004021 ChannelList,
4022 numChannels);
4023 if (eHAL_STATUS_SUCCESS != status)
4024 {
4025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4026 "%s: Failed to update channel list information", __func__);
4027 ret = -EINVAL;
4028 goto exit;
4029 }
4030 }
4031 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
4032 {
4033 tANI_U8 *value = command;
4034 char extra[128] = {0};
4035 int len = 0;
4036 tANI_U8 tid = 0;
4037 hdd_station_ctx_t *pHddStaCtx = NULL;
4038 tAniTrafStrmMetrics tsmMetrics;
4039 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4040
4041 /* if not associated, return error */
4042 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4043 {
4044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
4045 ret = -EINVAL;
4046 goto exit;
4047 }
4048
4049 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
4050 value = value + 12;
4051 /* Convert the value from ascii to integer */
4052 ret = kstrtou8(value, 10, &tid);
4053 if (ret < 0)
4054 {
4055 /* If the input value is greater than max value of datatype, then also
4056 kstrtou8 fails */
4057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4058 "%s: kstrtou8 failed range [%d - %d]", __func__,
4059 TID_MIN_VALUE,
4060 TID_MAX_VALUE);
4061 ret = -EINVAL;
4062 goto exit;
4063 }
4064
4065 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4066 {
4067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4068 "tid value %d is out of range"
4069 " (Min: %d Max: %d)", tid,
4070 TID_MIN_VALUE,
4071 TID_MAX_VALUE);
4072 ret = -EINVAL;
4073 goto exit;
4074 }
4075
4076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4077 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4078
4079 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4080 {
4081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4082 "%s: failed to get tsm stats", __func__);
4083 ret = -EFAULT;
4084 goto exit;
4085 }
4086
4087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4088 "UplinkPktQueueDly(%d)\n"
4089 "UplinkPktQueueDlyHist[0](%d)\n"
4090 "UplinkPktQueueDlyHist[1](%d)\n"
4091 "UplinkPktQueueDlyHist[2](%d)\n"
4092 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304093 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004094 "UplinkPktLoss(%d)\n"
4095 "UplinkPktCount(%d)\n"
4096 "RoamingCount(%d)\n"
4097 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4098 tsmMetrics.UplinkPktQueueDlyHist[0],
4099 tsmMetrics.UplinkPktQueueDlyHist[1],
4100 tsmMetrics.UplinkPktQueueDlyHist[2],
4101 tsmMetrics.UplinkPktQueueDlyHist[3],
4102 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4103 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4104
4105 /* Output TSM stats is of the format
4106 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4107 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004108 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004109 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4110 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4111 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4112 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4113 tsmMetrics.RoamingDly);
4114
4115 if (copy_to_user(priv_data.buf, &extra, len + 1))
4116 {
4117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4118 "%s: failed to copy data to user buffer", __func__);
4119 ret = -EFAULT;
4120 goto exit;
4121 }
4122 }
4123 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4124 {
4125 tANI_U8 *value = command;
4126 tANI_U8 *cckmIe = NULL;
4127 tANI_U8 cckmIeLen = 0;
4128 eHalStatus status = eHAL_STATUS_SUCCESS;
4129
4130 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4131 if (eHAL_STATUS_SUCCESS != status)
4132 {
4133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4134 "%s: Failed to parse cckm ie data", __func__);
4135 ret = -EINVAL;
4136 goto exit;
4137 }
4138
4139 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4140 {
4141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4142 "%s: CCKM Ie input length is more than max[%d]", __func__,
4143 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004144 vos_mem_free(cckmIe);
4145 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004146 ret = -EINVAL;
4147 goto exit;
4148 }
4149 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004150 vos_mem_free(cckmIe);
4151 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004152 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004153 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4154 {
4155 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004156 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004157 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004158
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004159 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004160 if (eHAL_STATUS_SUCCESS != status)
4161 {
4162 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004163 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004164 ret = -EINVAL;
4165 goto exit;
4166 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004167 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4168 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4169 hdd_indicateEseBcnReportNoResults (pAdapter,
4170 eseBcnReq.bcnReq[0].measurementToken,
4171 0x02, //BIT(1) set for measurement done
4172 0); // no BSS
4173 goto exit;
4174 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004175
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004176 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4177 if (eHAL_STATUS_SUCCESS != status)
4178 {
4179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4180 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4181 ret = -EINVAL;
4182 goto exit;
4183 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004184 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004185#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304186 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4187 {
4188 eHalStatus status;
4189 char buf[32], len;
4190 long waitRet;
4191 bcnMissRateContext_t getBcnMissRateCtx;
4192
4193 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4194
4195 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4196 {
4197 hddLog(VOS_TRACE_LEVEL_WARN,
4198 FL("GETBCNMISSRATE: STA is not in connected state"));
4199 ret = -1;
4200 goto exit;
4201 }
4202
4203 init_completion(&(getBcnMissRateCtx.completion));
4204 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4205
4206 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4207 pAdapter->sessionId,
4208 (void *)getBcnMissRateCB,
4209 (void *)(&getBcnMissRateCtx));
4210 if( eHAL_STATUS_SUCCESS != status)
4211 {
4212 hddLog(VOS_TRACE_LEVEL_INFO,
4213 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4214 ret = -EINVAL;
4215 goto exit;
4216 }
4217
4218 waitRet = wait_for_completion_interruptible_timeout
4219 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4220 if(waitRet <= 0)
4221 {
4222 hddLog(VOS_TRACE_LEVEL_ERROR,
4223 FL("failed to wait on bcnMissRateComp %d"), ret);
4224
4225 //Make magic number to zero so that callback is not called.
4226 spin_lock(&hdd_context_lock);
4227 getBcnMissRateCtx.magic = 0x0;
4228 spin_unlock(&hdd_context_lock);
4229 ret = -EINVAL;
4230 goto exit;
4231 }
4232
4233 hddLog(VOS_TRACE_LEVEL_INFO,
4234 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4235
4236 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4237 if (copy_to_user(priv_data.buf, &buf, len + 1))
4238 {
4239 hddLog(VOS_TRACE_LEVEL_ERROR,
4240 "%s: failed to copy data to user buffer", __func__);
4241 ret = -EFAULT;
4242 goto exit;
4243 }
4244 ret = len;
4245 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304246#ifdef FEATURE_WLAN_TDLS
4247 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4248 tANI_U8 *value = command;
4249 int set_value;
4250 /* Move pointer to ahead of TDLSOFFCH*/
4251 value += 26;
4252 sscanf(value, "%d", &set_value);
4253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4254 "%s: Tdls offchannel offset:%d",
4255 __func__, set_value);
4256 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4257 if (ret < 0)
4258 {
4259 ret = -EINVAL;
4260 goto exit;
4261 }
4262
4263 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4264 tANI_U8 *value = command;
4265 int set_value;
4266 /* Move pointer to ahead of tdlsoffchnmode*/
4267 value += 18;
4268 sscanf(value, "%d", &set_value);
4269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4270 "%s: Tdls offchannel mode:%d",
4271 __func__, set_value);
4272 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4273 if (ret < 0)
4274 {
4275 ret = -EINVAL;
4276 goto exit;
4277 }
4278 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4279 tANI_U8 *value = command;
4280 int set_value;
4281 /* Move pointer to ahead of TDLSOFFCH*/
4282 value += 14;
4283 sscanf(value, "%d", &set_value);
4284 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4285 "%s: Tdls offchannel num: %d",
4286 __func__, set_value);
4287 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4288 if (ret < 0)
4289 {
4290 ret = -EINVAL;
4291 goto exit;
4292 }
4293 }
4294#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304295 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4296 {
4297 eHalStatus status;
4298 char *buf = NULL;
4299 char len;
4300 long waitRet;
4301 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304302 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304303 tANI_U8 *ptr = command;
4304 int stats = *(ptr + 11) - '0';
4305
4306 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4307 if (!IS_FEATURE_FW_STATS_ENABLE)
4308 {
4309 hddLog(VOS_TRACE_LEVEL_INFO,
4310 FL("Get Firmware stats feature not supported"));
4311 ret = -EINVAL;
4312 goto exit;
4313 }
4314
4315 if (FW_STATS_MAX <= stats || 0 >= stats)
4316 {
4317 hddLog(VOS_TRACE_LEVEL_INFO,
4318 FL(" stats %d not supported"),stats);
4319 ret = -EINVAL;
4320 goto exit;
4321 }
4322
4323 init_completion(&(fwStatsCtx.completion));
4324 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4325 fwStatsCtx.pAdapter = pAdapter;
4326 fwStatsRsp->type = 0;
4327 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304328 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304329 if (eHAL_STATUS_SUCCESS != status)
4330 {
4331 hddLog(VOS_TRACE_LEVEL_ERROR,
4332 FL(" fail to post WDA cmd status = %d"), status);
4333 ret = -EINVAL;
4334 goto exit;
4335 }
4336 waitRet = wait_for_completion_timeout
4337 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4338 if (waitRet <= 0)
4339 {
4340 hddLog(VOS_TRACE_LEVEL_ERROR,
4341 FL("failed to wait on GwtFwstats"));
4342 //Make magic number to zero so that callback is not executed.
4343 spin_lock(&hdd_context_lock);
4344 fwStatsCtx.magic = 0x0;
4345 spin_unlock(&hdd_context_lock);
4346 ret = -EINVAL;
4347 goto exit;
4348 }
4349 if (fwStatsRsp->type)
4350 {
4351 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4352 if (!buf)
4353 {
4354 hddLog(VOS_TRACE_LEVEL_ERROR,
4355 FL(" failed to allocate memory"));
4356 ret = -ENOMEM;
4357 goto exit;
4358 }
4359 switch( fwStatsRsp->type )
4360 {
4361 case FW_UBSP_STATS:
4362 {
4363 len = snprintf(buf, FW_STATE_RSP_LEN,
4364 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304365 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4366 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304367 }
4368 break;
4369 default:
4370 {
4371 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4372 ret = -EFAULT;
4373 kfree(buf);
4374 goto exit;
4375 }
4376 }
4377 if (copy_to_user(priv_data.buf, buf, len + 1))
4378 {
4379 hddLog(VOS_TRACE_LEVEL_ERROR,
4380 FL(" failed to copy data to user buffer"));
4381 ret = -EFAULT;
4382 kfree(buf);
4383 goto exit;
4384 }
4385 ret = len;
4386 kfree(buf);
4387 }
4388 else
4389 {
4390 hddLog(VOS_TRACE_LEVEL_ERROR,
4391 FL("failed to fetch the stats"));
4392 ret = -EFAULT;
4393 goto exit;
4394 }
4395
4396 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004397 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304398 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4399 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4400 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304401 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4402 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004404 }
4405exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304406 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004407 if (command)
4408 {
4409 kfree(command);
4410 }
4411 return ret;
4412}
4413
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004414#ifdef CONFIG_COMPAT
4415static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4416{
4417 struct {
4418 compat_uptr_t buf;
4419 int used_len;
4420 int total_len;
4421 } compat_priv_data;
4422 hdd_priv_data_t priv_data;
4423 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004424
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004425 /*
4426 * Note that pAdapter and ifr have already been verified by caller,
4427 * and HDD context has also been validated
4428 */
4429 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4430 sizeof(compat_priv_data))) {
4431 ret = -EFAULT;
4432 goto exit;
4433 }
4434 priv_data.buf = compat_ptr(compat_priv_data.buf);
4435 priv_data.used_len = compat_priv_data.used_len;
4436 priv_data.total_len = compat_priv_data.total_len;
4437 ret = hdd_driver_command(pAdapter, &priv_data);
4438 exit:
4439 return ret;
4440}
4441#else /* CONFIG_COMPAT */
4442static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4443{
4444 /* will never be invoked */
4445 return 0;
4446}
4447#endif /* CONFIG_COMPAT */
4448
4449static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4450{
4451 hdd_priv_data_t priv_data;
4452 int ret = 0;
4453
4454 /*
4455 * Note that pAdapter and ifr have already been verified by caller,
4456 * and HDD context has also been validated
4457 */
4458 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4459 ret = -EFAULT;
4460 } else {
4461 ret = hdd_driver_command(pAdapter, &priv_data);
4462 }
4463 return ret;
4464}
4465
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304466int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004467{
4468 hdd_adapter_t *pAdapter;
4469 hdd_context_t *pHddCtx;
4470 int ret;
4471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304472 ENTER();
4473
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004474 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4475 if (NULL == pAdapter) {
4476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4477 "%s: HDD adapter context is Null", __func__);
4478 ret = -ENODEV;
4479 goto exit;
4480 }
4481 if (dev != pAdapter->dev) {
4482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4483 "%s: HDD adapter/dev inconsistency", __func__);
4484 ret = -ENODEV;
4485 goto exit;
4486 }
4487
4488 if ((!ifr) || (!ifr->ifr_data)) {
4489 ret = -EINVAL;
4490 goto exit;
4491 }
4492
4493 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4494 ret = wlan_hdd_validate_context(pHddCtx);
4495 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004496 ret = -EBUSY;
4497 goto exit;
4498 }
4499
4500 switch (cmd) {
4501 case (SIOCDEVPRIVATE + 1):
4502 if (is_compat_task())
4503 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4504 else
4505 ret = hdd_driver_ioctl(pAdapter, ifr);
4506 break;
4507 default:
4508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4509 __func__, cmd);
4510 ret = -EINVAL;
4511 break;
4512 }
4513 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304514 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004515 return ret;
4516}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004517
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304518int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4519{
4520 int ret;
4521
4522 vos_ssr_protect(__func__);
4523 ret = __hdd_ioctl(dev, ifr, cmd);
4524 vos_ssr_unprotect(__func__);
4525
4526 return ret;
4527}
4528
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004529#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004530/**---------------------------------------------------------------------------
4531
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004532 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004533
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004534 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004535 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4536 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4537 <space>Scan Mode N<space>Meas Duration N
4538 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4539 then take N.
4540 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4541 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4542 This function does not take care of removing duplicate channels from the list
4543
4544 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004545 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004546
4547 \return - 0 for success non-zero for failure
4548
4549 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004550static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4551 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004552{
4553 tANI_U8 *inPtr = pValue;
4554 int tempInt = 0;
4555 int j = 0, i = 0, v = 0;
4556 char buf[32];
4557
4558 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4559 /*no argument after the command*/
4560 if (NULL == inPtr)
4561 {
4562 return -EINVAL;
4563 }
4564 /*no space after the command*/
4565 else if (SPACE_ASCII_VALUE != *inPtr)
4566 {
4567 return -EINVAL;
4568 }
4569
4570 /*removing empty spaces*/
4571 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4572
4573 /*no argument followed by spaces*/
4574 if ('\0' == *inPtr) return -EINVAL;
4575
4576 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004577 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004578 if (1 != v) return -EINVAL;
4579
4580 v = kstrtos32(buf, 10, &tempInt);
4581 if ( v < 0) return -EINVAL;
4582
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004583 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004584
4585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004586 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004587
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004588 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004589 {
4590 for (i = 0; i < 4; i++)
4591 {
4592 /*inPtr pointing to the beginning of first space after number of ie fields*/
4593 inPtr = strpbrk( inPtr, " " );
4594 /*no ie data after the number of ie fields argument*/
4595 if (NULL == inPtr) return -EINVAL;
4596
4597 /*removing empty space*/
4598 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4599
4600 /*no ie data after the number of ie fields argument and spaces*/
4601 if ( '\0' == *inPtr ) return -EINVAL;
4602
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004603 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004604 if (1 != v) return -EINVAL;
4605
4606 v = kstrtos32(buf, 10, &tempInt);
4607 if (v < 0) return -EINVAL;
4608
4609 switch (i)
4610 {
4611 case 0: /* Measurement token */
4612 if (tempInt <= 0)
4613 {
4614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4615 "Invalid Measurement Token(%d)", tempInt);
4616 return -EINVAL;
4617 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004618 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004619 break;
4620
4621 case 1: /* Channel number */
4622 if ((tempInt <= 0) ||
4623 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4624 {
4625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4626 "Invalid Channel Number(%d)", tempInt);
4627 return -EINVAL;
4628 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004629 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004630 break;
4631
4632 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004633 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004634 {
4635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4636 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4637 return -EINVAL;
4638 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004639 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004640 break;
4641
4642 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004643 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4644 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004645 {
4646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4647 "Invalid Measurement Duration(%d)", tempInt);
4648 return -EINVAL;
4649 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004650 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004651 break;
4652 }
4653 }
4654 }
4655
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004656 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004657 {
4658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304659 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004660 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004661 pEseBcnReq->bcnReq[j].measurementToken,
4662 pEseBcnReq->bcnReq[j].channel,
4663 pEseBcnReq->bcnReq[j].scanMode,
4664 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004665 }
4666
4667 return VOS_STATUS_SUCCESS;
4668}
4669
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004670static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4671{
4672 struct statsContext *pStatsContext = NULL;
4673 hdd_adapter_t *pAdapter = NULL;
4674
4675 if (NULL == pContext)
4676 {
4677 hddLog(VOS_TRACE_LEVEL_ERROR,
4678 "%s: Bad param, pContext [%p]",
4679 __func__, pContext);
4680 return;
4681 }
4682
Jeff Johnson72a40512013-12-19 10:14:15 -08004683 /* there is a race condition that exists between this callback
4684 function and the caller since the caller could time out either
4685 before or while this code is executing. we use a spinlock to
4686 serialize these actions */
4687 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004688
4689 pStatsContext = pContext;
4690 pAdapter = pStatsContext->pAdapter;
4691 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4692 {
4693 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004694 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004695 hddLog(VOS_TRACE_LEVEL_WARN,
4696 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4697 __func__, pAdapter, pStatsContext->magic);
4698 return;
4699 }
4700
Jeff Johnson72a40512013-12-19 10:14:15 -08004701 /* context is valid so caller is still waiting */
4702
4703 /* paranoia: invalidate the magic */
4704 pStatsContext->magic = 0;
4705
4706 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004707 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4708 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4709 tsmMetrics.UplinkPktQueueDlyHist,
4710 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4711 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4712 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4713 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4714 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4715 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4716 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4717
Jeff Johnson72a40512013-12-19 10:14:15 -08004718 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004719 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004720
4721 /* serialization is complete */
4722 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004723}
4724
4725
4726
4727static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4728 tAniTrafStrmMetrics* pTsmMetrics)
4729{
4730 hdd_station_ctx_t *pHddStaCtx = NULL;
4731 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004732 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004733 long lrc;
4734 struct statsContext context;
4735 hdd_context_t *pHddCtx = NULL;
4736
4737 if (NULL == pAdapter)
4738 {
4739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4740 return VOS_STATUS_E_FAULT;
4741 }
4742
4743 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4744 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4745
4746 /* we are connected prepare our callback context */
4747 init_completion(&context.completion);
4748 context.pAdapter = pAdapter;
4749 context.magic = STATS_CONTEXT_MAGIC;
4750
4751 /* query tsm stats */
4752 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4753 pHddStaCtx->conn_info.staId[ 0 ],
4754 pHddStaCtx->conn_info.bssId,
4755 &context, pHddCtx->pvosContext, tid);
4756
4757 if (eHAL_STATUS_SUCCESS != hstatus)
4758 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004759 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4760 __func__);
4761 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004762 }
4763 else
4764 {
4765 /* request was sent -- wait for the response */
4766 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4767 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004768 if (lrc <= 0)
4769 {
4770 hddLog(VOS_TRACE_LEVEL_ERROR,
4771 "%s: SME %s while retrieving statistics",
4772 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004773 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004774 }
4775 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004776
Jeff Johnson72a40512013-12-19 10:14:15 -08004777 /* either we never sent a request, we sent a request and received a
4778 response or we sent a request and timed out. if we never sent a
4779 request or if we sent a request and got a response, we want to
4780 clear the magic out of paranoia. if we timed out there is a
4781 race condition such that the callback function could be
4782 executing at the same time we are. of primary concern is if the
4783 callback function had already verified the "magic" but had not
4784 yet set the completion variable when a timeout occurred. we
4785 serialize these activities by invalidating the magic while
4786 holding a shared spinlock which will cause us to block if the
4787 callback is currently executing */
4788 spin_lock(&hdd_context_lock);
4789 context.magic = 0;
4790 spin_unlock(&hdd_context_lock);
4791
4792 if (VOS_STATUS_SUCCESS == vstatus)
4793 {
4794 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4795 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4796 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4797 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4798 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4799 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4800 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4801 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4802 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4803 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4804 }
4805 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004806}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004807#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004808
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004809#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004810void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4811{
4812 eCsrBand band = -1;
4813 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4814 switch (band)
4815 {
4816 case eCSR_BAND_ALL:
4817 *pBand = WLAN_HDD_UI_BAND_AUTO;
4818 break;
4819
4820 case eCSR_BAND_24:
4821 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4822 break;
4823
4824 case eCSR_BAND_5G:
4825 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4826 break;
4827
4828 default:
4829 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4830 *pBand = -1;
4831 break;
4832 }
4833}
4834
4835/**---------------------------------------------------------------------------
4836
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004837 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4838
4839 This function parses the send action frame data passed in the format
4840 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4841
Srinivas Girigowda56076852013-08-20 14:00:50 -07004842 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004843 \param - pTargetApBssid Pointer to target Ap bssid
4844 \param - pChannel Pointer to the Target AP channel
4845 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4846 \param - pBuf Pointer to data
4847 \param - pBufLen Pointer to data length
4848
4849 \return - 0 for success non-zero for failure
4850
4851 --------------------------------------------------------------------------*/
4852VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4853 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4854{
4855 tANI_U8 *inPtr = pValue;
4856 tANI_U8 *dataEnd;
4857 int tempInt;
4858 int j = 0;
4859 int i = 0;
4860 int v = 0;
4861 tANI_U8 tempBuf[32];
4862 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004863 /* 12 hexa decimal digits, 5 ':' and '\0' */
4864 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004865
4866 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4867 /*no argument after the command*/
4868 if (NULL == inPtr)
4869 {
4870 return -EINVAL;
4871 }
4872
4873 /*no space after the command*/
4874 else if (SPACE_ASCII_VALUE != *inPtr)
4875 {
4876 return -EINVAL;
4877 }
4878
4879 /*removing empty spaces*/
4880 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4881
4882 /*no argument followed by spaces*/
4883 if ('\0' == *inPtr)
4884 {
4885 return -EINVAL;
4886 }
4887
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004888 v = sscanf(inPtr, "%17s", macAddress);
4889 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004890 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4892 "Invalid MAC address or All hex inputs are not read (%d)", v);
4893 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004894 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004895
4896 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4897 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4898 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4899 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4900 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4901 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004902
4903 /* point to the next argument */
4904 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4905 /*no argument after the command*/
4906 if (NULL == inPtr) return -EINVAL;
4907
4908 /*removing empty spaces*/
4909 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4910
4911 /*no argument followed by spaces*/
4912 if ('\0' == *inPtr)
4913 {
4914 return -EINVAL;
4915 }
4916
4917 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004918 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004919 if (1 != v) return -EINVAL;
4920
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004921 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304922 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304923 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004924
4925 *pChannel = tempInt;
4926
4927 /* point to the next argument */
4928 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4929 /*no argument after the command*/
4930 if (NULL == inPtr) return -EINVAL;
4931 /*removing empty spaces*/
4932 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4933
4934 /*no argument followed by spaces*/
4935 if ('\0' == *inPtr)
4936 {
4937 return -EINVAL;
4938 }
4939
4940 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004941 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004942 if (1 != v) return -EINVAL;
4943
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004944 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004945 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004946
4947 *pDwellTime = tempInt;
4948
4949 /* point to the next argument */
4950 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4951 /*no argument after the command*/
4952 if (NULL == inPtr) return -EINVAL;
4953 /*removing empty spaces*/
4954 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4955
4956 /*no argument followed by spaces*/
4957 if ('\0' == *inPtr)
4958 {
4959 return -EINVAL;
4960 }
4961
4962 /* find the length of data */
4963 dataEnd = inPtr;
4964 while(('\0' != *dataEnd) )
4965 {
4966 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004967 }
Kiet Lambe150c22013-11-21 16:30:32 +05304968 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004969 if ( *pBufLen <= 0) return -EINVAL;
4970
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004971 /* Allocate the number of bytes based on the number of input characters
4972 whether it is even or odd.
4973 if the number of input characters are even, then we need N/2 byte.
4974 if the number of input characters are odd, then we need do (N+1)/2 to
4975 compensate rounding off.
4976 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4977 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4978 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004979 if (NULL == *pBuf)
4980 {
4981 hddLog(VOS_TRACE_LEVEL_FATAL,
4982 "%s: vos_mem_alloc failed ", __func__);
4983 return -EINVAL;
4984 }
4985
4986 /* the buffer received from the upper layer is character buffer,
4987 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4988 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4989 and f0 in 3rd location */
4990 for (i = 0, j = 0; j < *pBufLen; j += 2)
4991 {
Kiet Lambe150c22013-11-21 16:30:32 +05304992 if( j+1 == *pBufLen)
4993 {
4994 tempByte = hdd_parse_hex(inPtr[j]);
4995 }
4996 else
4997 {
4998 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4999 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005000 (*pBuf)[i++] = tempByte;
5001 }
5002 *pBufLen = i;
5003 return VOS_STATUS_SUCCESS;
5004}
5005
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005006/**---------------------------------------------------------------------------
5007
Srinivas Girigowdade697412013-02-14 16:31:48 -08005008 \brief hdd_parse_channellist() - HDD Parse channel list
5009
5010 This function parses the channel list passed in the format
5011 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005012 if the Number of channels (N) does not match with the actual number of channels passed
5013 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
5014 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
5015 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
5016 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08005017
5018 \param - pValue Pointer to input channel list
5019 \param - ChannelList Pointer to local output array to record channel list
5020 \param - pNumChannels Pointer to number of roam scan channels
5021
5022 \return - 0 for success non-zero for failure
5023
5024 --------------------------------------------------------------------------*/
5025VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
5026{
5027 tANI_U8 *inPtr = pValue;
5028 int tempInt;
5029 int j = 0;
5030 int v = 0;
5031 char buf[32];
5032
5033 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5034 /*no argument after the command*/
5035 if (NULL == inPtr)
5036 {
5037 return -EINVAL;
5038 }
5039
5040 /*no space after the command*/
5041 else if (SPACE_ASCII_VALUE != *inPtr)
5042 {
5043 return -EINVAL;
5044 }
5045
5046 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005047 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005048
5049 /*no argument followed by spaces*/
5050 if ('\0' == *inPtr)
5051 {
5052 return -EINVAL;
5053 }
5054
5055 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005056 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005057 if (1 != v) return -EINVAL;
5058
Srinivas Girigowdade697412013-02-14 16:31:48 -08005059 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005060 if ((v < 0) ||
5061 (tempInt <= 0) ||
5062 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5063 {
5064 return -EINVAL;
5065 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005066
5067 *pNumChannels = tempInt;
5068
5069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5070 "Number of channels are: %d", *pNumChannels);
5071
5072 for (j = 0; j < (*pNumChannels); j++)
5073 {
5074 /*inPtr pointing to the beginning of first space after number of channels*/
5075 inPtr = strpbrk( inPtr, " " );
5076 /*no channel list after the number of channels argument*/
5077 if (NULL == inPtr)
5078 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005079 if (0 != j)
5080 {
5081 *pNumChannels = j;
5082 return VOS_STATUS_SUCCESS;
5083 }
5084 else
5085 {
5086 return -EINVAL;
5087 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005088 }
5089
5090 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005091 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005092
5093 /*no channel list after the number of channels argument and spaces*/
5094 if ( '\0' == *inPtr )
5095 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005096 if (0 != j)
5097 {
5098 *pNumChannels = j;
5099 return VOS_STATUS_SUCCESS;
5100 }
5101 else
5102 {
5103 return -EINVAL;
5104 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005105 }
5106
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005107 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005108 if (1 != v) return -EINVAL;
5109
Srinivas Girigowdade697412013-02-14 16:31:48 -08005110 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005111 if ((v < 0) ||
5112 (tempInt <= 0) ||
5113 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5114 {
5115 return -EINVAL;
5116 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005117 pChannelList[j] = tempInt;
5118
5119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5120 "Channel %d added to preferred channel list",
5121 pChannelList[j] );
5122 }
5123
Srinivas Girigowdade697412013-02-14 16:31:48 -08005124 return VOS_STATUS_SUCCESS;
5125}
5126
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005127
5128/**---------------------------------------------------------------------------
5129
5130 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5131
5132 This function parses the reasoc command data passed in the format
5133 REASSOC<space><bssid><space><channel>
5134
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005135 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005136 \param - pTargetApBssid Pointer to target Ap bssid
5137 \param - pChannel Pointer to the Target AP channel
5138
5139 \return - 0 for success non-zero for failure
5140
5141 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005142VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5143 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005144{
5145 tANI_U8 *inPtr = pValue;
5146 int tempInt;
5147 int v = 0;
5148 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005149 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005150 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005151
5152 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5153 /*no argument after the command*/
5154 if (NULL == inPtr)
5155 {
5156 return -EINVAL;
5157 }
5158
5159 /*no space after the command*/
5160 else if (SPACE_ASCII_VALUE != *inPtr)
5161 {
5162 return -EINVAL;
5163 }
5164
5165 /*removing empty spaces*/
5166 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5167
5168 /*no argument followed by spaces*/
5169 if ('\0' == *inPtr)
5170 {
5171 return -EINVAL;
5172 }
5173
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005174 v = sscanf(inPtr, "%17s", macAddress);
5175 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005176 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5178 "Invalid MAC address or All hex inputs are not read (%d)", v);
5179 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005180 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005181
5182 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5183 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5184 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5185 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5186 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5187 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005188
5189 /* point to the next argument */
5190 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5191 /*no argument after the command*/
5192 if (NULL == inPtr) return -EINVAL;
5193
5194 /*removing empty spaces*/
5195 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5196
5197 /*no argument followed by spaces*/
5198 if ('\0' == *inPtr)
5199 {
5200 return -EINVAL;
5201 }
5202
5203 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005204 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005205 if (1 != v) return -EINVAL;
5206
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005207 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005208 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305209 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005210 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5211 {
5212 return -EINVAL;
5213 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005214
5215 *pChannel = tempInt;
5216 return VOS_STATUS_SUCCESS;
5217}
5218
5219#endif
5220
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005221#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005222/**---------------------------------------------------------------------------
5223
5224 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5225
5226 This function parses the SETCCKM IE command
5227 SETCCKMIE<space><ie data>
5228
5229 \param - pValue Pointer to input data
5230 \param - pCckmIe Pointer to output cckm Ie
5231 \param - pCckmIeLen Pointer to output cckm ie length
5232
5233 \return - 0 for success non-zero for failure
5234
5235 --------------------------------------------------------------------------*/
5236VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5237 tANI_U8 *pCckmIeLen)
5238{
5239 tANI_U8 *inPtr = pValue;
5240 tANI_U8 *dataEnd;
5241 int j = 0;
5242 int i = 0;
5243 tANI_U8 tempByte = 0;
5244
5245 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5246 /*no argument after the command*/
5247 if (NULL == inPtr)
5248 {
5249 return -EINVAL;
5250 }
5251
5252 /*no space after the command*/
5253 else if (SPACE_ASCII_VALUE != *inPtr)
5254 {
5255 return -EINVAL;
5256 }
5257
5258 /*removing empty spaces*/
5259 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5260
5261 /*no argument followed by spaces*/
5262 if ('\0' == *inPtr)
5263 {
5264 return -EINVAL;
5265 }
5266
5267 /* find the length of data */
5268 dataEnd = inPtr;
5269 while(('\0' != *dataEnd) )
5270 {
5271 dataEnd++;
5272 ++(*pCckmIeLen);
5273 }
5274 if ( *pCckmIeLen <= 0) return -EINVAL;
5275
5276 /* Allocate the number of bytes based on the number of input characters
5277 whether it is even or odd.
5278 if the number of input characters are even, then we need N/2 byte.
5279 if the number of input characters are odd, then we need do (N+1)/2 to
5280 compensate rounding off.
5281 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5282 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5283 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5284 if (NULL == *pCckmIe)
5285 {
5286 hddLog(VOS_TRACE_LEVEL_FATAL,
5287 "%s: vos_mem_alloc failed ", __func__);
5288 return -EINVAL;
5289 }
5290 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5291 /* the buffer received from the upper layer is character buffer,
5292 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5293 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5294 and f0 in 3rd location */
5295 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5296 {
5297 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5298 (*pCckmIe)[i++] = tempByte;
5299 }
5300 *pCckmIeLen = i;
5301
5302 return VOS_STATUS_SUCCESS;
5303}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005304#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005305
Jeff Johnson295189b2012-06-20 16:38:30 -07005306/**---------------------------------------------------------------------------
5307
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005308 \brief hdd_is_valid_mac_address() - Validate MAC address
5309
5310 This function validates whether the given MAC address is valid or not
5311 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5312 where X is the hexa decimal digit character and separated by ':'
5313 This algorithm works even if MAC address is not separated by ':'
5314
5315 This code checks given input string mac contains exactly 12 hexadecimal digits.
5316 and a separator colon : appears in the input string only after
5317 an even number of hex digits.
5318
5319 \param - pMacAddr pointer to the input MAC address
5320 \return - 1 for valid and 0 for invalid
5321
5322 --------------------------------------------------------------------------*/
5323
5324v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5325{
5326 int xdigit = 0;
5327 int separator = 0;
5328 while (*pMacAddr)
5329 {
5330 if (isxdigit(*pMacAddr))
5331 {
5332 xdigit++;
5333 }
5334 else if (':' == *pMacAddr)
5335 {
5336 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5337 break;
5338
5339 ++separator;
5340 }
5341 else
5342 {
5343 separator = -1;
5344 /* Invalid MAC found */
5345 return 0;
5346 }
5347 ++pMacAddr;
5348 }
5349 return (xdigit == 12 && (separator == 5 || separator == 0));
5350}
5351
5352/**---------------------------------------------------------------------------
5353
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305354 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005355
5356 \param - dev Pointer to net_device structure
5357
5358 \return - 0 for success non-zero for failure
5359
5360 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305361int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005362{
5363 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5364 hdd_context_t *pHddCtx;
5365 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5366 VOS_STATUS status;
5367 v_BOOL_t in_standby = TRUE;
5368
5369 if (NULL == pAdapter)
5370 {
5371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305372 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005373 return -ENODEV;
5374 }
5375
5376 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305377 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5378 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005379 if (NULL == pHddCtx)
5380 {
5381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005382 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005383 return -ENODEV;
5384 }
5385
5386 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5387 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5388 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005389 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5390 {
5391 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305392 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005393 in_standby = FALSE;
5394 break;
5395 }
5396 else
5397 {
5398 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5399 pAdapterNode = pNext;
5400 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005401 }
5402
5403 if (TRUE == in_standby)
5404 {
5405 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5406 {
5407 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5408 "wlan out of power save", __func__);
5409 return -EINVAL;
5410 }
5411 }
5412
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005413 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005414 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5415 {
5416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005417 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005418 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305419 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005420 netif_tx_start_all_queues(dev);
5421 }
5422
5423 return 0;
5424}
5425
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305426/**---------------------------------------------------------------------------
5427
5428 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5429
5430 This is called in response to ifconfig up
5431
5432 \param - dev Pointer to net_device structure
5433
5434 \return - 0 for success non-zero for failure
5435
5436 --------------------------------------------------------------------------*/
5437int hdd_open(struct net_device *dev)
5438{
5439 int ret;
5440
5441 vos_ssr_protect(__func__);
5442 ret = __hdd_open(dev);
5443 vos_ssr_unprotect(__func__);
5444
5445 return ret;
5446}
5447
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305448int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005449{
5450 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5451
5452 if(pAdapter == NULL) {
5453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005454 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005455 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005456 }
5457
5458 netif_start_queue(dev);
5459
5460 return 0;
5461}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305462
5463int hdd_mon_open (struct net_device *dev)
5464{
5465 int ret;
5466
5467 vos_ssr_protect(__func__);
5468 ret = __hdd_mon_open(dev);
5469 vos_ssr_unprotect(__func__);
5470
5471 return ret;
5472}
5473
Jeff Johnson295189b2012-06-20 16:38:30 -07005474/**---------------------------------------------------------------------------
5475
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305476 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005477
5478 \param - dev Pointer to net_device structure
5479
5480 \return - 0 for success non-zero for failure
5481
5482 --------------------------------------------------------------------------*/
5483
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305484int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005485{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305486 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5488 hdd_context_t *pHddCtx;
5489 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5490 VOS_STATUS status;
5491 v_BOOL_t enter_standby = TRUE;
5492
5493 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 if (NULL == pAdapter)
5495 {
5496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305497 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 return -ENODEV;
5499 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305500 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305501 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305502
5503 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5504 ret = wlan_hdd_validate_context(pHddCtx);
5505 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305507 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 }
5509
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305510 /* Nothing to be done if the interface is not opened */
5511 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5512 {
5513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5514 "%s: NETDEV Interface is not OPENED", __func__);
5515 return -ENODEV;
5516 }
5517
5518 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005519 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005520 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305521
5522 /* Disable TX on the interface, after this hard_start_xmit() will not
5523 * be called on that interface
5524 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305525 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005526 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305527
5528 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005529 netif_carrier_off(pAdapter->dev);
5530
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305531 /* The interface is marked as down for outside world (aka kernel)
5532 * But the driver is pretty much alive inside. The driver needs to
5533 * tear down the existing connection on the netdev (session)
5534 * cleanup the data pipes and wait until the control plane is stabilized
5535 * for this interface. The call also needs to wait until the above
5536 * mentioned actions are completed before returning to the caller.
5537 * Notice that the hdd_stop_adapter is requested not to close the session
5538 * That is intentional to be able to scan if it is a STA/P2P interface
5539 */
5540 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305541#ifdef FEATURE_WLAN_TDLS
5542 mutex_lock(&pHddCtx->tdls_lock);
5543#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305544 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305545 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305546#ifdef FEATURE_WLAN_TDLS
5547 mutex_unlock(&pHddCtx->tdls_lock);
5548#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005549 /* SoftAP ifaces should never go in power save mode
5550 making sure same here. */
5551 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5552 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005553 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 )
5555 {
5556 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5558 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005559 EXIT();
5560 return 0;
5561 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305562 /* Find if any iface is up. If any iface is up then can't put device to
5563 * sleep/power save mode
5564 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5566 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5567 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005568 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5569 {
5570 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305571 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005572 enter_standby = FALSE;
5573 break;
5574 }
5575 else
5576 {
5577 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5578 pAdapterNode = pNext;
5579 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005580 }
5581
5582 if (TRUE == enter_standby)
5583 {
5584 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5585 "entering standby", __func__);
5586 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5587 {
5588 /*log and return success*/
5589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5590 "wlan in power save", __func__);
5591 }
5592 }
5593
5594 EXIT();
5595 return 0;
5596}
5597
5598/**---------------------------------------------------------------------------
5599
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305600 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005601
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305602 This is called in response to ifconfig down
5603
5604 \param - dev Pointer to net_device structure
5605
5606 \return - 0 for success non-zero for failure
5607-----------------------------------------------------------------------------*/
5608int hdd_stop (struct net_device *dev)
5609{
5610 int ret;
5611
5612 vos_ssr_protect(__func__);
5613 ret = __hdd_stop(dev);
5614 vos_ssr_unprotect(__func__);
5615
5616 return ret;
5617}
5618
5619/**---------------------------------------------------------------------------
5620
5621 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005622
5623 \param - dev Pointer to net_device structure
5624
5625 \return - void
5626
5627 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305628static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005629{
5630 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305631 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 ENTER();
5633
5634 do
5635 {
5636 if (NULL == pAdapter)
5637 {
5638 hddLog(VOS_TRACE_LEVEL_FATAL,
5639 "%s: NULL pAdapter", __func__);
5640 break;
5641 }
5642
5643 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5644 {
5645 hddLog(VOS_TRACE_LEVEL_FATAL,
5646 "%s: Invalid magic", __func__);
5647 break;
5648 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305649 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5650 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005651 {
5652 hddLog(VOS_TRACE_LEVEL_FATAL,
5653 "%s: NULL pHddCtx", __func__);
5654 break;
5655 }
5656
5657 if (dev != pAdapter->dev)
5658 {
5659 hddLog(VOS_TRACE_LEVEL_FATAL,
5660 "%s: Invalid device reference", __func__);
5661 /* we haven't validated all cases so let this go for now */
5662 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305663#ifdef FEATURE_WLAN_TDLS
5664 mutex_lock(&pHddCtx->tdls_lock);
5665#endif
c_hpothu002231a2015-02-05 14:58:51 +05305666 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305667#ifdef FEATURE_WLAN_TDLS
5668 mutex_unlock(&pHddCtx->tdls_lock);
5669#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005670
5671 /* after uninit our adapter structure will no longer be valid */
5672 pAdapter->dev = NULL;
5673 pAdapter->magic = 0;
5674 } while (0);
5675
5676 EXIT();
5677}
5678
5679/**---------------------------------------------------------------------------
5680
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305681 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5682
5683 This is called during the netdev unregister to uninitialize all data
5684associated with the device
5685
5686 \param - dev Pointer to net_device structure
5687
5688 \return - void
5689
5690 --------------------------------------------------------------------------*/
5691static void hdd_uninit (struct net_device *dev)
5692{
5693 vos_ssr_protect(__func__);
5694 __hdd_uninit(dev);
5695 vos_ssr_unprotect(__func__);
5696}
5697
5698/**---------------------------------------------------------------------------
5699
Jeff Johnson295189b2012-06-20 16:38:30 -07005700 \brief hdd_release_firmware() -
5701
5702 This function calls the release firmware API to free the firmware buffer.
5703
5704 \param - pFileName Pointer to the File Name.
5705 pCtx - Pointer to the adapter .
5706
5707
5708 \return - 0 for success, non zero for failure
5709
5710 --------------------------------------------------------------------------*/
5711
5712VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5713{
5714 VOS_STATUS status = VOS_STATUS_SUCCESS;
5715 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5716 ENTER();
5717
5718
5719 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5720
5721 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5722
5723 if(pHddCtx->fw) {
5724 release_firmware(pHddCtx->fw);
5725 pHddCtx->fw = NULL;
5726 }
5727 else
5728 status = VOS_STATUS_E_FAILURE;
5729 }
5730 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5731 if(pHddCtx->nv) {
5732 release_firmware(pHddCtx->nv);
5733 pHddCtx->nv = NULL;
5734 }
5735 else
5736 status = VOS_STATUS_E_FAILURE;
5737
5738 }
5739
5740 EXIT();
5741 return status;
5742}
5743
5744/**---------------------------------------------------------------------------
5745
5746 \brief hdd_request_firmware() -
5747
5748 This function reads the firmware file using the request firmware
5749 API and returns the the firmware data and the firmware file size.
5750
5751 \param - pfileName - Pointer to the file name.
5752 - pCtx - Pointer to the adapter .
5753 - ppfw_data - Pointer to the pointer of the firmware data.
5754 - pSize - Pointer to the file size.
5755
5756 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5757
5758 --------------------------------------------------------------------------*/
5759
5760
5761VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5762{
5763 int status;
5764 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5765 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5766 ENTER();
5767
5768 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5769
5770 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5771
5772 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5773 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5774 __func__, pfileName);
5775 retval = VOS_STATUS_E_FAILURE;
5776 }
5777
5778 else {
5779 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5780 *pSize = pHddCtx->fw->size;
5781 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5782 __func__, *pSize);
5783 }
5784 }
5785 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5786
5787 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5788
5789 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5790 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5791 __func__, pfileName);
5792 retval = VOS_STATUS_E_FAILURE;
5793 }
5794
5795 else {
5796 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5797 *pSize = pHddCtx->nv->size;
5798 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5799 __func__, *pSize);
5800 }
5801 }
5802
5803 EXIT();
5804 return retval;
5805}
5806/**---------------------------------------------------------------------------
5807 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5808
5809 This is the function invoked by SME to inform the result of a full power
5810 request issued by HDD
5811
5812 \param - callbackcontext - Pointer to cookie
5813 status - result of request
5814
5815 \return - None
5816
5817--------------------------------------------------------------------------*/
5818void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5819{
5820 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5821
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005822 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 if(&pHddCtx->full_pwr_comp_var)
5824 {
5825 complete(&pHddCtx->full_pwr_comp_var);
5826 }
5827}
5828
5829/**---------------------------------------------------------------------------
5830
5831 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5832
5833 This is the function invoked by SME to inform the result of BMPS
5834 request issued by HDD
5835
5836 \param - callbackcontext - Pointer to cookie
5837 status - result of request
5838
5839 \return - None
5840
5841--------------------------------------------------------------------------*/
5842void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5843{
5844
5845 struct completion *completion_var = (struct completion*) callbackContext;
5846
Arif Hussain6d2a3322013-11-17 19:50:10 -08005847 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005848 if(completion_var != NULL)
5849 {
5850 complete(completion_var);
5851 }
5852}
5853
5854/**---------------------------------------------------------------------------
5855
5856 \brief hdd_get_cfg_file_size() -
5857
5858 This function reads the configuration file using the request firmware
5859 API and returns the configuration file size.
5860
5861 \param - pCtx - Pointer to the adapter .
5862 - pFileName - Pointer to the file name.
5863 - pBufSize - Pointer to the buffer size.
5864
5865 \return - 0 for success, non zero for failure
5866
5867 --------------------------------------------------------------------------*/
5868
5869VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5870{
5871 int status;
5872 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5873
5874 ENTER();
5875
5876 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5877
5878 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5879 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5880 status = VOS_STATUS_E_FAILURE;
5881 }
5882 else {
5883 *pBufSize = pHddCtx->fw->size;
5884 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5885 release_firmware(pHddCtx->fw);
5886 pHddCtx->fw = NULL;
5887 }
5888
5889 EXIT();
5890 return VOS_STATUS_SUCCESS;
5891}
5892
5893/**---------------------------------------------------------------------------
5894
5895 \brief hdd_read_cfg_file() -
5896
5897 This function reads the configuration file using the request firmware
5898 API and returns the cfg data and the buffer size of the configuration file.
5899
5900 \param - pCtx - Pointer to the adapter .
5901 - pFileName - Pointer to the file name.
5902 - pBuffer - Pointer to the data buffer.
5903 - pBufSize - Pointer to the buffer size.
5904
5905 \return - 0 for success, non zero for failure
5906
5907 --------------------------------------------------------------------------*/
5908
5909VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5910 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5911{
5912 int status;
5913 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5914
5915 ENTER();
5916
5917 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5918
5919 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5920 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5921 return VOS_STATUS_E_FAILURE;
5922 }
5923 else {
5924 if(*pBufSize != pHddCtx->fw->size) {
5925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5926 "file size", __func__);
5927 release_firmware(pHddCtx->fw);
5928 pHddCtx->fw = NULL;
5929 return VOS_STATUS_E_FAILURE;
5930 }
5931 else {
5932 if(pBuffer) {
5933 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5934 }
5935 release_firmware(pHddCtx->fw);
5936 pHddCtx->fw = NULL;
5937 }
5938 }
5939
5940 EXIT();
5941
5942 return VOS_STATUS_SUCCESS;
5943}
5944
5945/**---------------------------------------------------------------------------
5946
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305947 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005948
5949 This function sets the user specified mac address using
5950 the command ifconfig wlanX hw ether <mac adress>.
5951
5952 \param - dev - Pointer to the net device.
5953 - addr - Pointer to the sockaddr.
5954 \return - 0 for success, non zero for failure
5955
5956 --------------------------------------------------------------------------*/
5957
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305958static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005959{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305960 hdd_adapter_t *pAdapter;
5961 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 struct sockaddr *psta_mac_addr = addr;
5963 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305964 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005965
5966 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305967 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5968 if (NULL == pAdapter)
5969 {
5970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5971 "%s: Adapter is NULL",__func__);
5972 return -EINVAL;
5973 }
5974 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5975 ret = wlan_hdd_validate_context(pHddCtx);
5976 if (0 != ret)
5977 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305978 return ret;
5979 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005980
5981 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5983
5984 EXIT();
5985 return halStatus;
5986}
5987
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305988/**---------------------------------------------------------------------------
5989
5990 \brief hdd_set_mac_address() -
5991
5992 Wrapper function to protect __hdd_set_mac_address() function from ssr
5993
5994 \param - dev - Pointer to the net device.
5995 - addr - Pointer to the sockaddr.
5996 \return - 0 for success, non zero for failure
5997
5998 --------------------------------------------------------------------------*/
5999static int hdd_set_mac_address(struct net_device *dev, void *addr)
6000{
6001 int ret;
6002
6003 vos_ssr_protect(__func__);
6004 ret = __hdd_set_mac_address(dev, addr);
6005 vos_ssr_unprotect(__func__);
6006
6007 return ret;
6008}
6009
Jeff Johnson295189b2012-06-20 16:38:30 -07006010tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
6011{
6012 int i;
6013 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6014 {
Abhishek Singheb183782014-02-06 13:37:21 +05306015 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 break;
6017 }
6018
6019 if( VOS_MAX_CONCURRENCY_PERSONA == i)
6020 return NULL;
6021
6022 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
6023 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
6024}
6025
6026void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
6027{
6028 int i;
6029 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
6030 {
6031 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
6032 {
6033 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
6034 break;
6035 }
6036 }
6037 return;
6038}
6039
6040#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6041 static struct net_device_ops wlan_drv_ops = {
6042 .ndo_open = hdd_open,
6043 .ndo_stop = hdd_stop,
6044 .ndo_uninit = hdd_uninit,
6045 .ndo_start_xmit = hdd_hard_start_xmit,
6046 .ndo_tx_timeout = hdd_tx_timeout,
6047 .ndo_get_stats = hdd_stats,
6048 .ndo_do_ioctl = hdd_ioctl,
6049 .ndo_set_mac_address = hdd_set_mac_address,
6050 .ndo_select_queue = hdd_select_queue,
6051#ifdef WLAN_FEATURE_PACKET_FILTERING
6052#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6053 .ndo_set_rx_mode = hdd_set_multicast_list,
6054#else
6055 .ndo_set_multicast_list = hdd_set_multicast_list,
6056#endif //LINUX_VERSION_CODE
6057#endif
6058 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006059 static struct net_device_ops wlan_mon_drv_ops = {
6060 .ndo_open = hdd_mon_open,
6061 .ndo_stop = hdd_stop,
6062 .ndo_uninit = hdd_uninit,
6063 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6064 .ndo_tx_timeout = hdd_tx_timeout,
6065 .ndo_get_stats = hdd_stats,
6066 .ndo_do_ioctl = hdd_ioctl,
6067 .ndo_set_mac_address = hdd_set_mac_address,
6068 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306069
Jeff Johnson295189b2012-06-20 16:38:30 -07006070#endif
6071
6072void hdd_set_station_ops( struct net_device *pWlanDev )
6073{
6074#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006075 pWlanDev->netdev_ops = &wlan_drv_ops;
6076#else
6077 pWlanDev->open = hdd_open;
6078 pWlanDev->stop = hdd_stop;
6079 pWlanDev->uninit = hdd_uninit;
6080 pWlanDev->hard_start_xmit = NULL;
6081 pWlanDev->tx_timeout = hdd_tx_timeout;
6082 pWlanDev->get_stats = hdd_stats;
6083 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006084 pWlanDev->set_mac_address = hdd_set_mac_address;
6085#endif
6086}
6087
Katya Nigam1fd24402015-02-16 14:52:19 +05306088void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6089{
6090 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6091 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6092 #else
6093 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6094 #endif
6095}
6096
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006097static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006098{
6099 struct net_device *pWlanDev = NULL;
6100 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006101 /*
6102 * cfg80211 initialization and registration....
6103 */
6104 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6105
Jeff Johnson295189b2012-06-20 16:38:30 -07006106 if(pWlanDev != NULL)
6107 {
6108
6109 //Save the pointer to the net_device in the HDD adapter
6110 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6111
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6113
6114 pAdapter->dev = pWlanDev;
6115 pAdapter->pHddCtx = pHddCtx;
6116 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306117 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006118
6119 init_completion(&pAdapter->session_open_comp_var);
6120 init_completion(&pAdapter->session_close_comp_var);
6121 init_completion(&pAdapter->disconnect_comp_var);
6122 init_completion(&pAdapter->linkup_event_var);
6123 init_completion(&pAdapter->cancel_rem_on_chan_var);
6124 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306125 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006126#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6127 init_completion(&pAdapter->offchannel_tx_event);
6128#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006129 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006130#ifdef FEATURE_WLAN_TDLS
6131 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006132 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006133 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306134 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006135#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006136 init_completion(&pHddCtx->mc_sus_event_var);
6137 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306138 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006139 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006140 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006141
Rajeev79dbe4c2013-10-05 11:03:42 +05306142#ifdef FEATURE_WLAN_BATCH_SCAN
6143 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6144 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6145 pAdapter->pBatchScanRsp = NULL;
6146 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006147 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006148 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306149 mutex_init(&pAdapter->hdd_batch_scan_lock);
6150#endif
6151
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 pAdapter->isLinkUpSvcNeeded = FALSE;
6153 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6154 //Init the net_device structure
6155 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6156
6157 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6158 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6159 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6160 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6161
6162 hdd_set_station_ops( pAdapter->dev );
6163
6164 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006165 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6166 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6167 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006168 /* set pWlanDev's parent to underlying device */
6169 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006170
6171 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006172 }
6173
6174 return pAdapter;
6175}
6176
6177VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6178{
6179 struct net_device *pWlanDev = pAdapter->dev;
6180 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6181 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6182 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6183
6184 if( rtnl_lock_held )
6185 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006186 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006187 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6188 {
6189 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6190 return VOS_STATUS_E_FAILURE;
6191 }
6192 }
6193 if (register_netdevice(pWlanDev))
6194 {
6195 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6196 return VOS_STATUS_E_FAILURE;
6197 }
6198 }
6199 else
6200 {
6201 if(register_netdev(pWlanDev))
6202 {
6203 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6204 return VOS_STATUS_E_FAILURE;
6205 }
6206 }
6207 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6208
6209 return VOS_STATUS_SUCCESS;
6210}
6211
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006212static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006213{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006214 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006215
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006216 if (NULL == pAdapter)
6217 {
6218 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6219 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006220 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006221
6222 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6223 {
6224 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6225 return eHAL_STATUS_NOT_INITIALIZED;
6226 }
6227
6228 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6229
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006230#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006231 /* need to make sure all of our scheduled work has completed.
6232 * This callback is called from MC thread context, so it is safe to
6233 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006234 *
6235 * Even though this is called from MC thread context, if there is a faulty
6236 * work item in the system, that can hang this call forever. So flushing
6237 * this global work queue is not safe; and now we make sure that
6238 * individual work queues are stopped correctly. But the cancel work queue
6239 * is a GPL only API, so the proprietary version of the driver would still
6240 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006241 */
6242 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006243#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006244
6245 /* We can be blocked while waiting for scheduled work to be
6246 * flushed, and the adapter structure can potentially be freed, in
6247 * which case the magic will have been reset. So make sure the
6248 * magic is still good, and hence the adapter structure is still
6249 * valid, before signaling completion */
6250 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6251 {
6252 complete(&pAdapter->session_close_comp_var);
6253 }
6254
Jeff Johnson295189b2012-06-20 16:38:30 -07006255 return eHAL_STATUS_SUCCESS;
6256}
6257
6258VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6259{
6260 struct net_device *pWlanDev = pAdapter->dev;
6261 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6262 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6263 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6264 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306265 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006266
6267 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006268 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006269 //Open a SME session for future operation
6270 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006271 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006272 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6273 {
6274 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006275 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006276 halStatus, halStatus );
6277 status = VOS_STATUS_E_FAILURE;
6278 goto error_sme_open;
6279 }
6280
6281 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306282 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 &pAdapter->session_open_comp_var,
6284 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306285 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 {
6287 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306288 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006289 status = VOS_STATUS_E_FAILURE;
6290 goto error_sme_open;
6291 }
6292
6293 // Register wireless extensions
6294 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6295 {
6296 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006297 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 halStatus, halStatus );
6299 status = VOS_STATUS_E_FAILURE;
6300 goto error_register_wext;
6301 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306302
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306304 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6305 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6306 #else
6307 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6308 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006309
6310 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306311 hddLog(VOS_TRACE_LEVEL_INFO,
6312 "%s: Set HDD connState to eConnectionState_NotConnected",
6313 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006314 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6315
6316 //Set the default operation channel
6317 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6318
6319 /* Make the default Auth Type as OPEN*/
6320 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6321
6322 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6323 {
6324 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006325 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006326 status, status );
6327 goto error_init_txrx;
6328 }
6329
6330 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6331
6332 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6333 {
6334 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006335 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 status, status );
6337 goto error_wmm_init;
6338 }
6339
6340 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6341
6342 return VOS_STATUS_SUCCESS;
6343
6344error_wmm_init:
6345 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6346 hdd_deinit_tx_rx(pAdapter);
6347error_init_txrx:
6348 hdd_UnregisterWext(pWlanDev);
6349error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006350 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 {
6352 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006353 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006355 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306357 unsigned long rc;
6358
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306360 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006362 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306363 if (rc <= 0)
6364 hddLog(VOS_TRACE_LEVEL_ERROR,
6365 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 }
6367}
6368error_sme_open:
6369 return status;
6370}
6371
Jeff Johnson295189b2012-06-20 16:38:30 -07006372void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6373{
6374 hdd_cfg80211_state_t *cfgState;
6375
6376 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6377
6378 if( NULL != cfgState->buf )
6379 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306380 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6382 rc = wait_for_completion_interruptible_timeout(
6383 &pAdapter->tx_action_cnf_event,
6384 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306385 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306388 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6389 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 }
6391 }
6392 return;
6393}
Jeff Johnson295189b2012-06-20 16:38:30 -07006394
c_hpothu002231a2015-02-05 14:58:51 +05306395void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006396{
6397 ENTER();
6398 switch ( pAdapter->device_mode )
6399 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306400 case WLAN_HDD_IBSS:
6401 {
6402 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6403 {
6404 hdd_ibss_deinit_tx_rx( pAdapter );
6405 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6406 }
6407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 case WLAN_HDD_INFRA_STATION:
6409 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006410 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 {
6412 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6413 {
6414 hdd_deinit_tx_rx( pAdapter );
6415 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6416 }
6417
6418 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6419 {
6420 hdd_wmm_adapter_close( pAdapter );
6421 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6422 }
6423
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 break;
6426 }
6427
6428 case WLAN_HDD_SOFTAP:
6429 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306431
6432 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6433 {
6434 hdd_wmm_adapter_close( pAdapter );
6435 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6436 }
6437
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006439
c_hpothu002231a2015-02-05 14:58:51 +05306440 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 break;
6444 }
6445
6446 case WLAN_HDD_MONITOR:
6447 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006449 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6450 {
6451 hdd_deinit_tx_rx( pAdapter );
6452 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6453 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006454 if(NULL != pAdapterforTx)
6455 {
6456 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006458 break;
6459 }
6460
6461
6462 default:
6463 break;
6464 }
6465
6466 EXIT();
6467}
6468
6469void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6470{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006471 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306472
6473 ENTER();
6474 if (NULL == pAdapter)
6475 {
6476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6477 "%s: HDD adapter is Null", __func__);
6478 return;
6479 }
6480
6481 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006482
Rajeev79dbe4c2013-10-05 11:03:42 +05306483#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306484 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6485 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006486 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306487 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6488 )
6489 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006490 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306491 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006492 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6493 {
6494 hdd_deinit_batch_scan(pAdapter);
6495 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306496 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006497 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306498#endif
6499
Jeff Johnson295189b2012-06-20 16:38:30 -07006500 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6501 if( rtnl_held )
6502 {
6503 unregister_netdevice(pWlanDev);
6504 }
6505 else
6506 {
6507 unregister_netdev(pWlanDev);
6508 }
6509 // note that the pAdapter is no longer valid at this point
6510 // since the memory has been reclaimed
6511 }
6512
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306513 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006514}
6515
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006516void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6517{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306518 VOS_STATUS status;
6519 hdd_adapter_t *pAdapter = NULL;
6520 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006521
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306522 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006523
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306524 /*loop through all adapters.*/
6525 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006526 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306527 pAdapter = pAdapterNode->pAdapter;
6528 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6529 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006530
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306531 { // we skip this registration for modes other than STA and P2P client modes.
6532 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6533 pAdapterNode = pNext;
6534 continue;
6535 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006536
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306537 //Apply Dynamic DTIM For P2P
6538 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6539 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6540 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6541 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6542 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6543 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6544 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6545 (eConnectionState_Associated ==
6546 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6547 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6548 {
6549 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006550
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306551 powerRequest.uIgnoreDTIM = 1;
6552 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6553
6554 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6555 {
6556 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6557 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6558 }
6559 else
6560 {
6561 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6562 }
6563
6564 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6565 * specified during Enter/Exit BMPS when LCD off*/
6566 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6567 NULL, eANI_BOOLEAN_FALSE);
6568 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6569 NULL, eANI_BOOLEAN_FALSE);
6570
6571 /* switch to the DTIM specified in cfg.ini */
6572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6573 "Switch to DTIM %d", powerRequest.uListenInterval);
6574 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6575 break;
6576
6577 }
6578
6579 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6580 pAdapterNode = pNext;
6581 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006582}
6583
6584void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6585{
6586 /*Switch back to DTIM 1*/
6587 tSirSetPowerParamsReq powerRequest = { 0 };
6588
6589 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6590 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006591 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006592
6593 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6594 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6595 NULL, eANI_BOOLEAN_FALSE);
6596 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6597 NULL, eANI_BOOLEAN_FALSE);
6598
6599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6600 "Switch to DTIM%d",powerRequest.uListenInterval);
6601 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6602
6603}
6604
Jeff Johnson295189b2012-06-20 16:38:30 -07006605VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6606{
6607 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306608 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6609 {
6610 hddLog( LOGE, FL("Wlan Unload in progress"));
6611 return VOS_STATUS_E_PERM;
6612 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006613 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6614 {
6615 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6616 }
6617
6618 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6619 {
6620 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6621 }
6622
6623 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6624 {
6625 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6626 }
6627
6628 return status;
6629}
6630
6631VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6632{
6633 hdd_adapter_t *pAdapter = NULL;
6634 eHalStatus halStatus;
6635 VOS_STATUS status = VOS_STATUS_E_INVAL;
6636 v_BOOL_t disableBmps = FALSE;
6637 v_BOOL_t disableImps = FALSE;
6638
6639 switch(session_type)
6640 {
6641 case WLAN_HDD_INFRA_STATION:
6642 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006643 case WLAN_HDD_P2P_CLIENT:
6644 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 //Exit BMPS -> Is Sta/P2P Client is already connected
6646 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6647 if((NULL != pAdapter)&&
6648 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6649 {
6650 disableBmps = TRUE;
6651 }
6652
6653 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6654 if((NULL != pAdapter)&&
6655 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6656 {
6657 disableBmps = TRUE;
6658 }
6659
6660 //Exit both Bmps and Imps incase of Go/SAP Mode
6661 if((WLAN_HDD_SOFTAP == session_type) ||
6662 (WLAN_HDD_P2P_GO == session_type))
6663 {
6664 disableBmps = TRUE;
6665 disableImps = TRUE;
6666 }
6667
6668 if(TRUE == disableImps)
6669 {
6670 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6671 {
6672 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6673 }
6674 }
6675
6676 if(TRUE == disableBmps)
6677 {
6678 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6679 {
6680 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6681
6682 if(eHAL_STATUS_SUCCESS != halStatus)
6683 {
6684 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006685 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006686 VOS_ASSERT(0);
6687 return status;
6688 }
6689 }
6690
6691 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6692 {
6693 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6694
6695 if(eHAL_STATUS_SUCCESS != halStatus)
6696 {
6697 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006698 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 VOS_ASSERT(0);
6700 return status;
6701 }
6702 }
6703 }
6704
6705 if((TRUE == disableBmps) ||
6706 (TRUE == disableImps))
6707 {
6708 /* Now, get the chip into Full Power now */
6709 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6710 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6711 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6712
6713 if(halStatus != eHAL_STATUS_SUCCESS)
6714 {
6715 if(halStatus == eHAL_STATUS_PMC_PENDING)
6716 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306717 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006718 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306719 ret = wait_for_completion_interruptible_timeout(
6720 &pHddCtx->full_pwr_comp_var,
6721 msecs_to_jiffies(1000));
6722 if (ret <= 0)
6723 {
6724 hddLog(VOS_TRACE_LEVEL_ERROR,
6725 "%s: wait on full_pwr_comp_var failed %ld",
6726 __func__, ret);
6727 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006728 }
6729 else
6730 {
6731 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006732 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006733 VOS_ASSERT(0);
6734 return status;
6735 }
6736 }
6737
6738 status = VOS_STATUS_SUCCESS;
6739 }
6740
6741 break;
6742 }
6743 return status;
6744}
6745
6746hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006747 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006748 tANI_U8 rtnl_held )
6749{
6750 hdd_adapter_t *pAdapter = NULL;
6751 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6752 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6753 VOS_STATUS exitbmpsStatus;
6754
Arif Hussain6d2a3322013-11-17 19:50:10 -08006755 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006756
Nirav Shah436658f2014-02-28 17:05:45 +05306757 if(macAddr == NULL)
6758 {
6759 /* Not received valid macAddr */
6760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6761 "%s:Unable to add virtual intf: Not able to get"
6762 "valid mac address",__func__);
6763 return NULL;
6764 }
6765
Jeff Johnson295189b2012-06-20 16:38:30 -07006766 //Disable BMPS incase of Concurrency
6767 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6768
6769 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6770 {
6771 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306772 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 VOS_ASSERT(0);
6774 return NULL;
6775 }
6776
6777 switch(session_type)
6778 {
6779 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006780 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006781 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 {
6783 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6784
6785 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306786 {
6787 hddLog(VOS_TRACE_LEVEL_FATAL,
6788 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306790 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006791
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306792#ifdef FEATURE_WLAN_TDLS
6793 /* A Mutex Lock is introduced while changing/initializing the mode to
6794 * protect the concurrent access for the Adapters by TDLS module.
6795 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306796 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306797#endif
6798
Jeff Johnsone7245742012-09-05 17:12:55 -07006799 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6800 NL80211_IFTYPE_P2P_CLIENT:
6801 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006802
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306804#ifdef FEATURE_WLAN_TDLS
6805 mutex_unlock(&pHddCtx->tdls_lock);
6806#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306807
6808 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006809 if( VOS_STATUS_SUCCESS != status )
6810 goto err_free_netdev;
6811
6812 status = hdd_register_interface( pAdapter, rtnl_held );
6813 if( VOS_STATUS_SUCCESS != status )
6814 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306815#ifdef FEATURE_WLAN_TDLS
6816 mutex_lock(&pHddCtx->tdls_lock);
6817#endif
c_hpothu002231a2015-02-05 14:58:51 +05306818 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306819#ifdef FEATURE_WLAN_TDLS
6820 mutex_unlock(&pHddCtx->tdls_lock);
6821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 goto err_free_netdev;
6823 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306824
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306825 // Workqueue which gets scheduled in IPv4 notification callback.
6826 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6827
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306828#ifdef WLAN_NS_OFFLOAD
6829 // Workqueue which gets scheduled in IPv6 notification callback.
6830 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6831#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006832 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306833 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006834 netif_tx_disable(pAdapter->dev);
6835 //netif_tx_disable(pWlanDev);
6836 netif_carrier_off(pAdapter->dev);
6837
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306838 if (WLAN_HDD_P2P_CLIENT == session_type ||
6839 WLAN_HDD_P2P_DEVICE == session_type)
6840 {
6841 /* Initialize the work queue to defer the
6842 * back to back RoC request */
6843 INIT_DELAYED_WORK(&pAdapter->roc_work,
6844 hdd_p2p_roc_work_queue);
6845 }
6846
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 break;
6848 }
6849
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 case WLAN_HDD_SOFTAP:
6852 {
6853 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6854 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306855 {
6856 hddLog(VOS_TRACE_LEVEL_FATAL,
6857 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006858 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306859 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006860
Jeff Johnson295189b2012-06-20 16:38:30 -07006861 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6862 NL80211_IFTYPE_AP:
6863 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 pAdapter->device_mode = session_type;
6865
6866 status = hdd_init_ap_mode(pAdapter);
6867 if( VOS_STATUS_SUCCESS != status )
6868 goto err_free_netdev;
6869
6870 status = hdd_register_hostapd( pAdapter, rtnl_held );
6871 if( VOS_STATUS_SUCCESS != status )
6872 {
c_hpothu002231a2015-02-05 14:58:51 +05306873 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 goto err_free_netdev;
6875 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306876 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006877 netif_tx_disable(pAdapter->dev);
6878 netif_carrier_off(pAdapter->dev);
6879
6880 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306881
6882 if (WLAN_HDD_P2P_GO == session_type)
6883 {
6884 /* Initialize the work queue to
6885 * defer the back to back RoC request */
6886 INIT_DELAYED_WORK(&pAdapter->roc_work,
6887 hdd_p2p_roc_work_queue);
6888 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006889 break;
6890 }
6891 case WLAN_HDD_MONITOR:
6892 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6894 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306895 {
6896 hddLog(VOS_TRACE_LEVEL_FATAL,
6897 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306899 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006900
6901 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6902 pAdapter->device_mode = session_type;
6903 status = hdd_register_interface( pAdapter, rtnl_held );
6904#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6905 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6906#else
6907 pAdapter->dev->open = hdd_mon_open;
6908 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6909#endif
6910 hdd_init_tx_rx( pAdapter );
6911 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6912 //Set adapter to be used for data tx. It will use either GO or softap.
6913 pAdapter->sessionCtx.monitor.pAdapterForTx =
6914 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6916 {
6917 pAdapter->sessionCtx.monitor.pAdapterForTx =
6918 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6919 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 /* This workqueue will be used to transmit management packet over
6921 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006922 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6923 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6924 return NULL;
6925 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006926
Jeff Johnson295189b2012-06-20 16:38:30 -07006927 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6928 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 }
6930 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006931 case WLAN_HDD_FTM:
6932 {
6933 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6934
6935 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306936 {
6937 hddLog(VOS_TRACE_LEVEL_FATAL,
6938 FL("failed to allocate adapter for session %d"), session_type);
6939 return NULL;
6940 }
6941
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6943 * message while loading driver in FTM mode. */
6944 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6945 pAdapter->device_mode = session_type;
6946 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306947
6948 hdd_init_tx_rx( pAdapter );
6949
6950 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306951 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306952 netif_tx_disable(pAdapter->dev);
6953 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 }
6955 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 default:
6957 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306958 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6959 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006960 VOS_ASSERT(0);
6961 return NULL;
6962 }
6963 }
6964
Jeff Johnson295189b2012-06-20 16:38:30 -07006965 if( VOS_STATUS_SUCCESS == status )
6966 {
6967 //Add it to the hdd's session list.
6968 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6969 if( NULL == pHddAdapterNode )
6970 {
6971 status = VOS_STATUS_E_NOMEM;
6972 }
6973 else
6974 {
6975 pHddAdapterNode->pAdapter = pAdapter;
6976 status = hdd_add_adapter_back ( pHddCtx,
6977 pHddAdapterNode );
6978 }
6979 }
6980
6981 if( VOS_STATUS_SUCCESS != status )
6982 {
6983 if( NULL != pAdapter )
6984 {
6985 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6986 pAdapter = NULL;
6987 }
6988 if( NULL != pHddAdapterNode )
6989 {
6990 vos_mem_free( pHddAdapterNode );
6991 }
6992
6993 goto resume_bmps;
6994 }
6995
6996 if(VOS_STATUS_SUCCESS == status)
6997 {
6998 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6999
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07007000 //Initialize the WoWL service
7001 if(!hdd_init_wowl(pAdapter))
7002 {
7003 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
7004 goto err_free_netdev;
7005 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007007 return pAdapter;
7008
7009err_free_netdev:
7010 free_netdev(pAdapter->dev);
7011 wlan_hdd_release_intf_addr( pHddCtx,
7012 pAdapter->macAddressCurrent.bytes );
7013
7014resume_bmps:
7015 //If bmps disabled enable it
7016 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
7017 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307018 if (pHddCtx->hdd_wlan_suspended)
7019 {
7020 hdd_set_pwrparams(pHddCtx);
7021 }
7022 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 }
7024 return NULL;
7025}
7026
7027VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7028 tANI_U8 rtnl_held )
7029{
7030 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
7031 VOS_STATUS status;
7032
7033 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
7034 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307035 {
7036 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
7037 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007040
7041 while ( pCurrent->pAdapter != pAdapter )
7042 {
7043 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
7044 if( VOS_STATUS_SUCCESS != status )
7045 break;
7046
7047 pCurrent = pNext;
7048 }
7049 pAdapterNode = pCurrent;
7050 if( VOS_STATUS_SUCCESS == status )
7051 {
7052 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7053 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307054
7055#ifdef FEATURE_WLAN_TDLS
7056
7057 /* A Mutex Lock is introduced while changing/initializing the mode to
7058 * protect the concurrent access for the Adapters by TDLS module.
7059 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307060 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307061#endif
7062
Jeff Johnson295189b2012-06-20 16:38:30 -07007063 hdd_remove_adapter( pHddCtx, pAdapterNode );
7064 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007065 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007066
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307067#ifdef FEATURE_WLAN_TDLS
7068 mutex_unlock(&pHddCtx->tdls_lock);
7069#endif
7070
Jeff Johnson295189b2012-06-20 16:38:30 -07007071
7072 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307073 if ((!vos_concurrent_open_sessions_running()) &&
7074 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7075 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307077 if (pHddCtx->hdd_wlan_suspended)
7078 {
7079 hdd_set_pwrparams(pHddCtx);
7080 }
7081 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007082 }
7083
7084 return VOS_STATUS_SUCCESS;
7085 }
7086
7087 return VOS_STATUS_E_FAILURE;
7088}
7089
7090VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7091{
7092 hdd_adapter_list_node_t *pHddAdapterNode;
7093 VOS_STATUS status;
7094
7095 ENTER();
7096
7097 do
7098 {
7099 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7100 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7101 {
7102 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7103 vos_mem_free( pHddAdapterNode );
7104 }
7105 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7106
7107 EXIT();
7108
7109 return VOS_STATUS_SUCCESS;
7110}
7111
7112void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7113{
7114 v_U8_t addIE[1] = {0};
7115
7116 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7117 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7118 eANI_BOOLEAN_FALSE) )
7119 {
7120 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007121 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007122 }
7123
7124 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7125 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7126 eANI_BOOLEAN_FALSE) )
7127 {
7128 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007129 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 }
7131
7132 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7133 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7134 eANI_BOOLEAN_FALSE) )
7135 {
7136 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007137 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007138 }
7139}
7140
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307141VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7142 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007143{
7144 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7145 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307146 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307148 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307149 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007150
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307151 if (pHddCtx->isLogpInProgress) {
7152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7153 "%s:LOGP in Progress. Ignore!!!",__func__);
7154 return VOS_STATUS_E_FAILURE;
7155 }
7156
Jeff Johnson295189b2012-06-20 16:38:30 -07007157 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307158
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307159 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 switch(pAdapter->device_mode)
7161 {
7162 case WLAN_HDD_INFRA_STATION:
7163 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007164 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307165 {
7166 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7167 if( hdd_connIsConnected(pstation) ||
7168 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007169 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307170#ifdef FEATURE_WLAN_TDLS
7171 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307172 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307173 mutex_unlock(&pHddCtx->tdls_lock);
7174#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007175 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7176 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7177 pAdapter->sessionId,
7178 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7179 else
7180 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7181 pAdapter->sessionId,
7182 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7183 //success implies disconnect command got queued up successfully
7184 if(halStatus == eHAL_STATUS_SUCCESS)
7185 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307186 ret = wait_for_completion_interruptible_timeout(
7187 &pAdapter->disconnect_comp_var,
7188 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7189 if (ret <= 0)
7190 {
7191 hddLog(VOS_TRACE_LEVEL_ERROR,
7192 "%s: wait on disconnect_comp_var failed %ld",
7193 __func__, ret);
7194 }
7195 }
7196 else
7197 {
7198 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7199 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 }
7201 memset(&wrqu, '\0', sizeof(wrqu));
7202 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7203 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7204 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7205 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307206 else if(pstation->conn_info.connState ==
7207 eConnectionState_Disconnecting)
7208 {
7209 ret = wait_for_completion_interruptible_timeout(
7210 &pAdapter->disconnect_comp_var,
7211 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7212 if (ret <= 0)
7213 {
7214 hddLog(VOS_TRACE_LEVEL_ERROR,
7215 FL("wait on disconnect_comp_var failed %ld"), ret);
7216 }
7217 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307218 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307220 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307221 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307223 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7224 {
7225 while (pAdapter->is_roc_inprogress)
7226 {
7227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7228 "%s: ROC in progress for session %d!!!",
7229 __func__, pAdapter->sessionId);
7230 // waiting for ROC to expire
7231 msleep(500);
7232 /* In GO present case , if retry exceeds 3,
7233 it means something went wrong. */
7234 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7235 {
7236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7237 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307238 if (eHAL_STATUS_SUCCESS !=
7239 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7240 pAdapter->sessionId ))
7241 {
7242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7243 FL("Failed to Cancel Remain on Channel"));
7244 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307245 wait_for_completion_interruptible_timeout(
7246 &pAdapter->cancel_rem_on_chan_var,
7247 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7248 break;
7249 }
7250 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307251#ifdef WLAN_OPEN_SOURCE
7252 cancel_delayed_work_sync(&pAdapter->roc_work);
7253#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307254 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307255#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307256#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307257 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7258#endif
7259#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307260
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307261#ifdef WLAN_OPEN_SOURCE
7262 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7263#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307264
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307265 /* It is possible that the caller of this function does not
7266 * wish to close the session
7267 */
7268 if (VOS_TRUE == bCloseSession &&
7269 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007270 {
7271 INIT_COMPLETION(pAdapter->session_close_comp_var);
7272 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307273 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7274 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307276 unsigned long ret;
7277
Jeff Johnson295189b2012-06-20 16:38:30 -07007278 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307279 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307280 &pAdapter->session_close_comp_var,
7281 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307282 if ( 0 >= ret)
7283 {
7284 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307285 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307286 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007287 }
7288 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307289 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007290 break;
7291
7292 case WLAN_HDD_SOFTAP:
7293 case WLAN_HDD_P2P_GO:
7294 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307295 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7296 while (pAdapter->is_roc_inprogress) {
7297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7298 "%s: ROC in progress for session %d!!!",
7299 __func__, pAdapter->sessionId);
7300 msleep(500);
7301 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7303 "%s: ROC completion is not received.!!!", __func__);
7304 WLANSAP_CancelRemainOnChannel(
7305 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7306 wait_for_completion_interruptible_timeout(
7307 &pAdapter->cancel_rem_on_chan_var,
7308 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7309 break;
7310 }
7311 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307312
7313#ifdef WLAN_OPEN_SOURCE
7314 cancel_delayed_work_sync(&pAdapter->roc_work);
7315#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307316 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007317 mutex_lock(&pHddCtx->sap_lock);
7318 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7319 {
7320 VOS_STATUS status;
7321 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7322
7323 //Stop Bss.
7324 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7325 if (VOS_IS_STATUS_SUCCESS(status))
7326 {
7327 hdd_hostapd_state_t *pHostapdState =
7328 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7329
7330 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7331
7332 if (!VOS_IS_STATUS_SUCCESS(status))
7333 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307334 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7335 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 }
7337 }
7338 else
7339 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007340 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007341 }
7342 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307343 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007344
7345 if (eHAL_STATUS_FAILURE ==
7346 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7347 0, NULL, eANI_BOOLEAN_FALSE))
7348 {
7349 hddLog(LOGE,
7350 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007351 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007352 }
7353
7354 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7355 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7356 eANI_BOOLEAN_FALSE) )
7357 {
7358 hddLog(LOGE,
7359 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7360 }
7361
7362 // Reset WNI_CFG_PROBE_RSP Flags
7363 wlan_hdd_reset_prob_rspies(pAdapter);
7364 kfree(pAdapter->sessionCtx.ap.beacon);
7365 pAdapter->sessionCtx.ap.beacon = NULL;
7366 }
7367 mutex_unlock(&pHddCtx->sap_lock);
7368 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007369
Jeff Johnson295189b2012-06-20 16:38:30 -07007370 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007371#ifdef WLAN_OPEN_SOURCE
7372 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7373#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007375
Jeff Johnson295189b2012-06-20 16:38:30 -07007376 default:
7377 break;
7378 }
7379
7380 EXIT();
7381 return VOS_STATUS_SUCCESS;
7382}
7383
7384VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7385{
7386 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7387 VOS_STATUS status;
7388 hdd_adapter_t *pAdapter;
7389
7390 ENTER();
7391
7392 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7393
7394 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7395 {
7396 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007397
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307398 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007399
7400 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7401 pAdapterNode = pNext;
7402 }
7403
7404 EXIT();
7405
7406 return VOS_STATUS_SUCCESS;
7407}
7408
Rajeev Kumarf999e582014-01-09 17:33:29 -08007409
7410#ifdef FEATURE_WLAN_BATCH_SCAN
7411/**---------------------------------------------------------------------------
7412
7413 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7414 structures
7415
7416 \param - pAdapter Pointer to HDD adapter
7417
7418 \return - None
7419
7420 --------------------------------------------------------------------------*/
7421void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7422{
7423 tHddBatchScanRsp *pNode;
7424 tHddBatchScanRsp *pPrev;
7425
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307426 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007427 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307428 hddLog(VOS_TRACE_LEVEL_ERROR,
7429 "%s: Adapter context is Null", __func__);
7430 return;
7431 }
7432
7433 pNode = pAdapter->pBatchScanRsp;
7434 while (pNode)
7435 {
7436 pPrev = pNode;
7437 pNode = pNode->pNext;
7438 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007439 }
7440
7441 pAdapter->pBatchScanRsp = NULL;
7442 pAdapter->numScanList = 0;
7443 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7444 pAdapter->prev_batch_id = 0;
7445
7446 return;
7447}
7448#endif
7449
7450
Jeff Johnson295189b2012-06-20 16:38:30 -07007451VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7452{
7453 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7454 VOS_STATUS status;
7455 hdd_adapter_t *pAdapter;
7456
7457 ENTER();
7458
7459 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7460
7461 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7462 {
7463 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307464 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007465 netif_tx_disable(pAdapter->dev);
7466 netif_carrier_off(pAdapter->dev);
7467
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007468 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7469
Jeff Johnson295189b2012-06-20 16:38:30 -07007470 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307471
Katya Nigam1fd24402015-02-16 14:52:19 +05307472 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7473 hdd_ibss_deinit_tx_rx(pAdapter);
7474
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307475 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7476
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307477 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7478 {
7479 hdd_wmm_adapter_close( pAdapter );
7480 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7481 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007482
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307483 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7484 {
7485 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7486 }
7487
Rajeev Kumarf999e582014-01-09 17:33:29 -08007488#ifdef FEATURE_WLAN_BATCH_SCAN
7489 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7490 {
7491 hdd_deinit_batch_scan(pAdapter);
7492 }
7493#endif
7494
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307495#ifdef FEATURE_WLAN_TDLS
7496 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307497 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307498 mutex_unlock(&pHddCtx->tdls_lock);
7499#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7501 pAdapterNode = pNext;
7502 }
7503
7504 EXIT();
7505
7506 return VOS_STATUS_SUCCESS;
7507}
7508
7509VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7510{
7511 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7512 VOS_STATUS status;
7513 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307514 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007515
7516 ENTER();
7517
7518 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7519
7520 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7521 {
7522 pAdapter = pAdapterNode->pAdapter;
7523
Kumar Anand82c009f2014-05-29 00:29:42 -07007524 hdd_wmm_init( pAdapter );
7525
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 switch(pAdapter->device_mode)
7527 {
7528 case WLAN_HDD_INFRA_STATION:
7529 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007530 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307531
7532 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7533
Jeff Johnson295189b2012-06-20 16:38:30 -07007534 hdd_init_station_mode(pAdapter);
7535 /* Open the gates for HDD to receive Wext commands */
7536 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007537 pHddCtx->scan_info.mScanPending = FALSE;
7538 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007539
7540 //Trigger the initial scan
7541 hdd_wlan_initial_scan(pAdapter);
7542
7543 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307544 if (eConnectionState_Associated == connState ||
7545 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007546 {
7547 union iwreq_data wrqu;
7548 memset(&wrqu, '\0', sizeof(wrqu));
7549 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7550 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7551 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007552 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007553
Jeff Johnson295189b2012-06-20 16:38:30 -07007554 /* indicate disconnected event to nl80211 */
7555 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7556 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307558 else if (eConnectionState_Connecting == connState)
7559 {
7560 /*
7561 * Indicate connect failure to supplicant if we were in the
7562 * process of connecting
7563 */
7564 cfg80211_connect_result(pAdapter->dev, NULL,
7565 NULL, 0, NULL, 0,
7566 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7567 GFP_KERNEL);
7568 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007569 break;
7570
7571 case WLAN_HDD_SOFTAP:
7572 /* softAP can handle SSR */
7573 break;
7574
7575 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007577 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007578 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007579 break;
7580
7581 case WLAN_HDD_MONITOR:
7582 /* monitor interface start */
7583 break;
7584 default:
7585 break;
7586 }
7587
7588 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7589 pAdapterNode = pNext;
7590 }
7591
7592 EXIT();
7593
7594 return VOS_STATUS_SUCCESS;
7595}
7596
7597VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7598{
7599 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7600 hdd_adapter_t *pAdapter;
7601 VOS_STATUS status;
7602 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307603 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007604
7605 ENTER();
7606
7607 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7608
7609 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7610 {
7611 pAdapter = pAdapterNode->pAdapter;
7612
7613 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7614 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7615 {
7616 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7617 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7618
Abhishek Singhf4669da2014-05-26 15:07:49 +05307619 hddLog(VOS_TRACE_LEVEL_INFO,
7620 "%s: Set HDD connState to eConnectionState_NotConnected",
7621 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7623 init_completion(&pAdapter->disconnect_comp_var);
7624 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7625 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7626
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307627 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007628 &pAdapter->disconnect_comp_var,
7629 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307630 if (0 >= ret)
7631 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7632 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007633
7634 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7635 pHddCtx->isAmpAllowed = VOS_FALSE;
7636 sme_RoamConnect(pHddCtx->hHal,
7637 pAdapter->sessionId, &(pWextState->roamProfile),
7638 &roamId);
7639 }
7640
7641 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7642 pAdapterNode = pNext;
7643 }
7644
7645 EXIT();
7646
7647 return VOS_STATUS_SUCCESS;
7648}
7649
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007650void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7651{
7652 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7653 VOS_STATUS status;
7654 hdd_adapter_t *pAdapter;
7655 hdd_station_ctx_t *pHddStaCtx;
7656 hdd_ap_ctx_t *pHddApCtx;
7657 hdd_hostapd_state_t * pHostapdState;
7658 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7659 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7660 const char *p2pMode = "DEV";
7661 const char *ccMode = "Standalone";
7662 int n;
7663
7664 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7665 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7666 {
7667 pAdapter = pAdapterNode->pAdapter;
7668 switch (pAdapter->device_mode) {
7669 case WLAN_HDD_INFRA_STATION:
7670 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7671 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7672 staChannel = pHddStaCtx->conn_info.operationChannel;
7673 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7674 }
7675 break;
7676 case WLAN_HDD_P2P_CLIENT:
7677 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7678 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7679 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7680 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7681 p2pMode = "CLI";
7682 }
7683 break;
7684 case WLAN_HDD_P2P_GO:
7685 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7686 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7687 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7688 p2pChannel = pHddApCtx->operatingChannel;
7689 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7690 }
7691 p2pMode = "GO";
7692 break;
7693 case WLAN_HDD_SOFTAP:
7694 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7695 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7696 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7697 apChannel = pHddApCtx->operatingChannel;
7698 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7699 }
7700 break;
7701 default:
7702 break;
7703 }
7704 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7705 pAdapterNode = pNext;
7706 }
7707 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7708 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7709 }
7710 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7711 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7712 if (p2pChannel > 0) {
7713 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7714 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7715 }
7716 if (apChannel > 0) {
7717 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7718 apChannel, MAC_ADDR_ARRAY(apBssid));
7719 }
7720
7721 if (p2pChannel > 0 && apChannel > 0) {
7722 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7723 }
7724}
7725
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007726bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007727{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007728 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007729}
7730
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007731/* Once SSR is disabled then it cannot be set. */
7732void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007733{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007734 if (HDD_SSR_DISABLED == isSsrRequired)
7735 return;
7736
Jeff Johnson295189b2012-06-20 16:38:30 -07007737 isSsrRequired = value;
7738}
7739
7740VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7741 hdd_adapter_list_node_t** ppAdapterNode)
7742{
7743 VOS_STATUS status;
7744 spin_lock(&pHddCtx->hddAdapters.lock);
7745 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7746 (hdd_list_node_t**) ppAdapterNode );
7747 spin_unlock(&pHddCtx->hddAdapters.lock);
7748 return status;
7749}
7750
7751VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7752 hdd_adapter_list_node_t* pAdapterNode,
7753 hdd_adapter_list_node_t** pNextAdapterNode)
7754{
7755 VOS_STATUS status;
7756 spin_lock(&pHddCtx->hddAdapters.lock);
7757 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7758 (hdd_list_node_t*) pAdapterNode,
7759 (hdd_list_node_t**)pNextAdapterNode );
7760
7761 spin_unlock(&pHddCtx->hddAdapters.lock);
7762 return status;
7763}
7764
7765VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7766 hdd_adapter_list_node_t* pAdapterNode)
7767{
7768 VOS_STATUS status;
7769 spin_lock(&pHddCtx->hddAdapters.lock);
7770 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7771 &pAdapterNode->node );
7772 spin_unlock(&pHddCtx->hddAdapters.lock);
7773 return status;
7774}
7775
7776VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7777 hdd_adapter_list_node_t** ppAdapterNode)
7778{
7779 VOS_STATUS status;
7780 spin_lock(&pHddCtx->hddAdapters.lock);
7781 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7782 (hdd_list_node_t**) ppAdapterNode );
7783 spin_unlock(&pHddCtx->hddAdapters.lock);
7784 return status;
7785}
7786
7787VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7788 hdd_adapter_list_node_t* pAdapterNode)
7789{
7790 VOS_STATUS status;
7791 spin_lock(&pHddCtx->hddAdapters.lock);
7792 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7793 (hdd_list_node_t*) pAdapterNode );
7794 spin_unlock(&pHddCtx->hddAdapters.lock);
7795 return status;
7796}
7797
7798VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7799 hdd_adapter_list_node_t* pAdapterNode)
7800{
7801 VOS_STATUS status;
7802 spin_lock(&pHddCtx->hddAdapters.lock);
7803 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7804 (hdd_list_node_t*) pAdapterNode );
7805 spin_unlock(&pHddCtx->hddAdapters.lock);
7806 return status;
7807}
7808
7809hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7810 tSirMacAddr macAddr )
7811{
7812 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7813 hdd_adapter_t *pAdapter;
7814 VOS_STATUS status;
7815
7816 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7817
7818 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7819 {
7820 pAdapter = pAdapterNode->pAdapter;
7821
7822 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7823 macAddr, sizeof(tSirMacAddr) ) )
7824 {
7825 return pAdapter;
7826 }
7827 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7828 pAdapterNode = pNext;
7829 }
7830
7831 return NULL;
7832
7833}
7834
7835hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7836{
7837 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7838 hdd_adapter_t *pAdapter;
7839 VOS_STATUS status;
7840
7841 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7842
7843 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7844 {
7845 pAdapter = pAdapterNode->pAdapter;
7846
7847 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7848 IFNAMSIZ ) )
7849 {
7850 return pAdapter;
7851 }
7852 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7853 pAdapterNode = pNext;
7854 }
7855
7856 return NULL;
7857
7858}
7859
7860hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7861{
7862 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7863 hdd_adapter_t *pAdapter;
7864 VOS_STATUS status;
7865
7866 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7867
7868 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7869 {
7870 pAdapter = pAdapterNode->pAdapter;
7871
7872 if( pAdapter && (mode == pAdapter->device_mode) )
7873 {
7874 return pAdapter;
7875 }
7876 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7877 pAdapterNode = pNext;
7878 }
7879
7880 return NULL;
7881
7882}
7883
7884//Remove this function later
7885hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7886{
7887 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7888 hdd_adapter_t *pAdapter;
7889 VOS_STATUS status;
7890
7891 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7892
7893 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7894 {
7895 pAdapter = pAdapterNode->pAdapter;
7896
7897 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7898 {
7899 return pAdapter;
7900 }
7901
7902 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7903 pAdapterNode = pNext;
7904 }
7905
7906 return NULL;
7907
7908}
7909
Jeff Johnson295189b2012-06-20 16:38:30 -07007910/**---------------------------------------------------------------------------
7911
7912 \brief hdd_set_monitor_tx_adapter() -
7913
7914 This API initializes the adapter to be used while transmitting on monitor
7915 adapter.
7916
7917 \param - pHddCtx - Pointer to the HDD context.
7918 pAdapter - Adapter that will used for TX. This can be NULL.
7919 \return - None.
7920 --------------------------------------------------------------------------*/
7921void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7922{
7923 hdd_adapter_t *pMonAdapter;
7924
7925 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7926
7927 if( NULL != pMonAdapter )
7928 {
7929 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7930 }
7931}
Jeff Johnson295189b2012-06-20 16:38:30 -07007932/**---------------------------------------------------------------------------
7933
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307934 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007935
7936 This API returns the operating channel of the requested device mode
7937
7938 \param - pHddCtx - Pointer to the HDD context.
7939 - mode - Device mode for which operating channel is required
7940 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7941 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7942 \return - channel number. "0" id the requested device is not found OR it is not connected.
7943 --------------------------------------------------------------------------*/
7944v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7945{
7946 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7947 VOS_STATUS status;
7948 hdd_adapter_t *pAdapter;
7949 v_U8_t operatingChannel = 0;
7950
7951 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7952
7953 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7954 {
7955 pAdapter = pAdapterNode->pAdapter;
7956
7957 if( mode == pAdapter->device_mode )
7958 {
7959 switch(pAdapter->device_mode)
7960 {
7961 case WLAN_HDD_INFRA_STATION:
7962 case WLAN_HDD_P2P_CLIENT:
7963 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7964 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7965 break;
7966 case WLAN_HDD_SOFTAP:
7967 case WLAN_HDD_P2P_GO:
7968 /*softap connection info */
7969 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7970 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7971 break;
7972 default:
7973 break;
7974 }
7975
7976 break; //Found the device of interest. break the loop
7977 }
7978
7979 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7980 pAdapterNode = pNext;
7981 }
7982 return operatingChannel;
7983}
7984
7985#ifdef WLAN_FEATURE_PACKET_FILTERING
7986/**---------------------------------------------------------------------------
7987
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307988 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007989
7990 This used to set the multicast address list.
7991
7992 \param - dev - Pointer to the WLAN device.
7993 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307994 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07007995
7996 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307997static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007998{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307999 hdd_adapter_t *pAdapter;
8000 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308002 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008003 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308004
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308005 ENTER();
8006
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308007 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308008 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008009 {
8010 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308011 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008012 return;
8013 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308014 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8015 ret = wlan_hdd_validate_context(pHddCtx);
8016 if (0 != ret)
8017 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308018 return;
8019 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008020 if (dev->flags & IFF_ALLMULTI)
8021 {
8022 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008023 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308024 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008025 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308026 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008027 {
8028 mc_count = netdev_mc_count(dev);
8029 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008030 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07008031 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
8032 {
8033 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008034 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308035 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008036 return;
8037 }
8038
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308039 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07008040
8041 netdev_for_each_mc_addr(ha, dev) {
8042 if (i == mc_count)
8043 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308044 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
8045 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008046 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308047 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05308048 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 i++;
8050 }
8051 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308052
8053 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 return;
8055}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308056
8057static void hdd_set_multicast_list(struct net_device *dev)
8058{
8059 vos_ssr_protect(__func__);
8060 __hdd_set_multicast_list(dev);
8061 vos_ssr_unprotect(__func__);
8062}
Jeff Johnson295189b2012-06-20 16:38:30 -07008063#endif
8064
8065/**---------------------------------------------------------------------------
8066
8067 \brief hdd_select_queue() -
8068
8069 This function is registered with the Linux OS for network
8070 core to decide which queue to use first.
8071
8072 \param - dev - Pointer to the WLAN device.
8073 - skb - Pointer to OS packet (sk_buff).
8074 \return - ac, Queue Index/access category corresponding to UP in IP header
8075
8076 --------------------------------------------------------------------------*/
8077v_U16_t hdd_select_queue(struct net_device *dev,
8078 struct sk_buff *skb)
8079{
8080 return hdd_wmm_select_queue(dev, skb);
8081}
8082
8083
8084/**---------------------------------------------------------------------------
8085
8086 \brief hdd_wlan_initial_scan() -
8087
8088 This function triggers the initial scan
8089
8090 \param - pAdapter - Pointer to the HDD adapter.
8091
8092 --------------------------------------------------------------------------*/
8093void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8094{
8095 tCsrScanRequest scanReq;
8096 tCsrChannelInfo channelInfo;
8097 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008098 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8100
8101 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8102 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8103 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8104
8105 if(sme_Is11dSupported(pHddCtx->hHal))
8106 {
8107 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8108 if ( HAL_STATUS_SUCCESS( halStatus ) )
8109 {
8110 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8111 if( !scanReq.ChannelInfo.ChannelList )
8112 {
8113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8114 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008115 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 return;
8117 }
8118 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8119 channelInfo.numOfChannels);
8120 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8121 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008122 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 }
8124
8125 scanReq.scanType = eSIR_PASSIVE_SCAN;
8126 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8127 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8128 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8129 }
8130 else
8131 {
8132 scanReq.scanType = eSIR_ACTIVE_SCAN;
8133 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8134 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8135 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8136 }
8137
8138 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8139 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8140 {
8141 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8142 __func__, halStatus );
8143 }
8144
8145 if(sme_Is11dSupported(pHddCtx->hHal))
8146 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8147}
8148
Jeff Johnson295189b2012-06-20 16:38:30 -07008149/**---------------------------------------------------------------------------
8150
8151 \brief hdd_full_power_callback() - HDD full power callback function
8152
8153 This is the function invoked by SME to inform the result of a full power
8154 request issued by HDD
8155
8156 \param - callbackcontext - Pointer to cookie
8157 \param - status - result of request
8158
8159 \return - None
8160
8161 --------------------------------------------------------------------------*/
8162static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8163{
Jeff Johnson72a40512013-12-19 10:14:15 -08008164 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008165
8166 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308167 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008168
8169 if (NULL == callbackContext)
8170 {
8171 hddLog(VOS_TRACE_LEVEL_ERROR,
8172 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008173 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008174 return;
8175 }
8176
Jeff Johnson72a40512013-12-19 10:14:15 -08008177 /* there is a race condition that exists between this callback
8178 function and the caller since the caller could time out either
8179 before or while this code is executing. we use a spinlock to
8180 serialize these actions */
8181 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008182
8183 if (POWER_CONTEXT_MAGIC != pContext->magic)
8184 {
8185 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008186 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008187 hddLog(VOS_TRACE_LEVEL_WARN,
8188 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008189 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 return;
8191 }
8192
Jeff Johnson72a40512013-12-19 10:14:15 -08008193 /* context is valid so caller is still waiting */
8194
8195 /* paranoia: invalidate the magic */
8196 pContext->magic = 0;
8197
8198 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008199 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008200
8201 /* serialization is complete */
8202 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008203}
8204
8205/**---------------------------------------------------------------------------
8206
8207 \brief hdd_wlan_exit() - HDD WLAN exit function
8208
8209 This is the driver exit point (invoked during rmmod)
8210
8211 \param - pHddCtx - Pointer to the HDD Context
8212
8213 \return - None
8214
8215 --------------------------------------------------------------------------*/
8216void hdd_wlan_exit(hdd_context_t *pHddCtx)
8217{
8218 eHalStatus halStatus;
8219 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8220 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308221 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008222 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008223 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308225 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008226
8227 ENTER();
8228
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308229#ifdef WLAN_NS_OFFLOAD
8230 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8231 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8232#endif
8233 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8234 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8235
Jeff Johnson88ba7742013-02-27 14:36:02 -08008236 if (VOS_FTM_MODE != hdd_get_conparam())
8237 {
Katya Nigamdc373382015-02-25 18:52:19 +05308238 /* This will issue a dump command which will clean up
8239 BTQM queues and unblock MC thread */
Mahesh A Saptasagar4f6d8622015-03-16 20:37:10 +05308240 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
Jeff Johnson88ba7742013-02-27 14:36:02 -08008241 // Unloading, restart logic is no more required.
8242 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008243
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308244#ifdef FEATURE_WLAN_TDLS
8245 /* At the time of driver unloading; if tdls connection is present;
8246 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8247 * wlan_hdd_tdls_find_peer always checks for valid context;
8248 * as load/unload in progress there can be a race condition.
8249 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8250 * when tdls state is enabled.
8251 * As soon as driver set load/unload flag; tdls flag also needs
8252 * to be disabled so that hdd_rx_packet_cbk won't call
8253 * wlan_hdd_tdls_find_peer.
8254 */
8255 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8256#endif
8257
c_hpothu5ab05e92014-06-13 17:34:05 +05308258 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8259 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308261 pAdapter = pAdapterNode->pAdapter;
8262 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008263 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308264 /* Disable TX on the interface, after this hard_start_xmit() will
8265 * not be called on that interface
8266 */
8267 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8268 netif_tx_disable(pAdapter->dev);
8269
8270 /* Mark the interface status as "down" for outside world */
8271 netif_carrier_off(pAdapter->dev);
8272
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308273 /* DeInit the adapter. This ensures that all data packets
8274 * are freed.
8275 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308276#ifdef FEATURE_WLAN_TDLS
8277 mutex_lock(&pHddCtx->tdls_lock);
8278#endif
c_hpothu002231a2015-02-05 14:58:51 +05308279 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308280#ifdef FEATURE_WLAN_TDLS
8281 mutex_unlock(&pHddCtx->tdls_lock);
8282#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308283
c_hpothu5ab05e92014-06-13 17:34:05 +05308284 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8285 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8286 {
8287 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8288 hdd_UnregisterWext(pAdapter->dev);
8289 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308290
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308292 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8293 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008294 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308295 // Cancel any outstanding scan requests. We are about to close all
8296 // of our adapters, but an adapter structure is what SME passes back
8297 // to our callback function. Hence if there are any outstanding scan
8298 // requests then there is a race condition between when the adapter
8299 // is closed and when the callback is invoked.We try to resolve that
8300 // race condition here by canceling any outstanding scans before we
8301 // close the adapters.
8302 // Note that the scans may be cancelled in an asynchronous manner,
8303 // so ideally there needs to be some kind of synchronization. Rather
8304 // than introduce a new synchronization here, we will utilize the
8305 // fact that we are about to Request Full Power, and since that is
8306 // synchronized, the expectation is that by the time Request Full
8307 // Power has completed all scans will be cancelled.
8308 if (pHddCtx->scan_info.mScanPending)
8309 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308310 if(NULL != pAdapter)
8311 {
8312 hddLog(VOS_TRACE_LEVEL_INFO,
8313 FL("abort scan mode: %d sessionId: %d"),
8314 pAdapter->device_mode,
8315 pAdapter->sessionId);
8316 }
8317 hdd_abort_mac_scan(pHddCtx,
8318 pHddCtx->scan_info.sessionId,
8319 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308320 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008321 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308322 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008323 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308324 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308325 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8326 {
8327 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8329 "%s: in middle of FTM START", __func__);
8330 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8331 msecs_to_jiffies(20000));
8332 if(!lrc)
8333 {
8334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8335 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8336 }
8337 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008338 wlan_hdd_ftm_close(pHddCtx);
8339 goto free_hdd_ctx;
8340 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308341
Jeff Johnson295189b2012-06-20 16:38:30 -07008342 /* DeRegister with platform driver as client for Suspend/Resume */
8343 vosStatus = hddDeregisterPmOps(pHddCtx);
8344 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8345 {
8346 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8347 VOS_ASSERT(0);
8348 }
8349
8350 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8351 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8352 {
8353 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8354 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008355
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008356 //Stop the traffic monitor timer
8357 if ( VOS_TIMER_STATE_RUNNING ==
8358 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8359 {
8360 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8361 }
8362
8363 // Destroy the traffic monitor timer
8364 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8365 &pHddCtx->tx_rx_trafficTmr)))
8366 {
8367 hddLog(VOS_TRACE_LEVEL_ERROR,
8368 "%s: Cannot deallocate Traffic monitor timer", __func__);
8369 }
8370
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 //Disable IMPS/BMPS as we do not want the device to enter any power
8372 //save mode during shutdown
8373 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8374 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8375 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8376
8377 //Ensure that device is in full power as we will touch H/W during vos_Stop
8378 init_completion(&powerContext.completion);
8379 powerContext.magic = POWER_CONTEXT_MAGIC;
8380
8381 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8382 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8383
8384 if (eHAL_STATUS_SUCCESS != halStatus)
8385 {
8386 if (eHAL_STATUS_PMC_PENDING == halStatus)
8387 {
8388 /* request was sent -- wait for the response */
8389 lrc = wait_for_completion_interruptible_timeout(
8390 &powerContext.completion,
8391 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 if (lrc <= 0)
8393 {
8394 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008395 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008396 }
8397 }
8398 else
8399 {
8400 hddLog(VOS_TRACE_LEVEL_ERROR,
8401 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008402 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008403 /* continue -- need to clean up as much as possible */
8404 }
8405 }
8406
Jeff Johnson72a40512013-12-19 10:14:15 -08008407 /* either we never sent a request, we sent a request and received a
8408 response or we sent a request and timed out. if we never sent a
8409 request or if we sent a request and got a response, we want to
8410 clear the magic out of paranoia. if we timed out there is a
8411 race condition such that the callback function could be
8412 executing at the same time we are. of primary concern is if the
8413 callback function had already verified the "magic" but had not
8414 yet set the completion variable when a timeout occurred. we
8415 serialize these activities by invalidating the magic while
8416 holding a shared spinlock which will cause us to block if the
8417 callback is currently executing */
8418 spin_lock(&hdd_context_lock);
8419 powerContext.magic = 0;
8420 spin_unlock(&hdd_context_lock);
8421
Yue Ma0d4891e2013-08-06 17:01:45 -07008422 hdd_debugfs_exit(pHddCtx);
8423
Jeff Johnson295189b2012-06-20 16:38:30 -07008424 // Unregister the Net Device Notifier
8425 unregister_netdevice_notifier(&hdd_netdev_notifier);
8426
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 hdd_stop_all_adapters( pHddCtx );
8428
Jeff Johnson295189b2012-06-20 16:38:30 -07008429#ifdef WLAN_BTAMP_FEATURE
8430 vosStatus = WLANBAP_Stop(pVosContext);
8431 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8432 {
8433 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8434 "%s: Failed to stop BAP",__func__);
8435 }
8436#endif //WLAN_BTAMP_FEATURE
8437
8438 //Stop all the modules
8439 vosStatus = vos_stop( pVosContext );
8440 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8441 {
8442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8443 "%s: Failed to stop VOSS",__func__);
8444 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8445 }
8446
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008449
8450 //Close the scheduler before calling vos_close to make sure no thread is
8451 // scheduled after the each module close is called i.e after all the data
8452 // structures are freed.
8453 vosStatus = vos_sched_close( pVosContext );
8454 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8455 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8456 "%s: Failed to close VOSS Scheduler",__func__);
8457 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8458 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008459#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008460#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8461 /* Destroy the wake lock */
8462 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8463#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008464 /* Destroy the wake lock */
8465 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008466#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008467
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308468#ifdef CONFIG_ENABLE_LINUX_REG
8469 vosStatus = vos_nv_close();
8470 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8471 {
8472 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8473 "%s: Failed to close NV", __func__);
8474 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8475 }
8476#endif
8477
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 //Close VOSS
8479 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8480 vos_close(pVosContext);
8481
Jeff Johnson295189b2012-06-20 16:38:30 -07008482 //Close Watchdog
8483 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8484 vos_watchdog_close(pVosContext);
8485
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308486 //Clean up HDD Nlink Service
8487 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308488
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308489#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308490 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308491 {
8492 wlan_logging_sock_deactivate_svc();
8493 }
8494#endif
8495
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308496#ifdef WLAN_KD_READY_NOTIFIER
8497 nl_srv_exit(pHddCtx->ptt_pid);
8498#else
8499 nl_srv_exit();
8500#endif /* WLAN_KD_READY_NOTIFIER */
8501
8502
Jeff Johnson295189b2012-06-20 16:38:30 -07008503 hdd_close_all_adapters( pHddCtx );
8504
Jeff Johnson295189b2012-06-20 16:38:30 -07008505 /* free the power on lock from platform driver */
8506 if (free_riva_power_on_lock("wlan"))
8507 {
8508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8509 __func__);
8510 }
8511
Jeff Johnson88ba7742013-02-27 14:36:02 -08008512free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308513
8514 //Free up dynamically allocated members inside HDD Adapter
8515 if (pHddCtx->cfg_ini)
8516 {
8517 kfree(pHddCtx->cfg_ini);
8518 pHddCtx->cfg_ini= NULL;
8519 }
8520
Leo Changf04ddad2013-09-18 13:46:38 -07008521 /* FTM mode, WIPHY did not registered
8522 If un-register here, system crash will happen */
8523 if (VOS_FTM_MODE != hdd_get_conparam())
8524 {
8525 wiphy_unregister(wiphy) ;
8526 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008527 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008528 if (hdd_is_ssr_required())
8529 {
8530 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008531 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 msleep(5000);
8533 }
8534 hdd_set_ssr_required (VOS_FALSE);
8535}
8536
8537
8538/**---------------------------------------------------------------------------
8539
8540 \brief hdd_update_config_from_nv() - Function to update the contents of
8541 the running configuration with parameters taken from NV storage
8542
8543 \param - pHddCtx - Pointer to the HDD global context
8544
8545 \return - VOS_STATUS_SUCCESS if successful
8546
8547 --------------------------------------------------------------------------*/
8548static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8549{
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 v_BOOL_t itemIsValid = VOS_FALSE;
8551 VOS_STATUS status;
8552 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8553 v_U8_t macLoop;
8554
8555 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8556 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8557 if(status != VOS_STATUS_SUCCESS)
8558 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008559 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008560 return VOS_STATUS_E_FAILURE;
8561 }
8562
8563 if (itemIsValid == VOS_TRUE)
8564 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008565 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008566 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8567 VOS_MAX_CONCURRENCY_PERSONA);
8568 if(status != VOS_STATUS_SUCCESS)
8569 {
8570 /* Get MAC from NV fail, not update CFG info
8571 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008572 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 return VOS_STATUS_E_FAILURE;
8574 }
8575
8576 /* If first MAC is not valid, treat all others are not valid
8577 * Then all MACs will be got from ini file */
8578 if(vos_is_macaddr_zero(&macFromNV[0]))
8579 {
8580 /* MAC address in NV file is not configured yet */
8581 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8582 return VOS_STATUS_E_INVAL;
8583 }
8584
8585 /* Get MAC address from NV, update CFG info */
8586 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8587 {
8588 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8589 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308590 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 /* This MAC is not valid, skip it
8592 * This MAC will be got from ini file */
8593 }
8594 else
8595 {
8596 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8597 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8598 VOS_MAC_ADDR_SIZE);
8599 }
8600 }
8601 }
8602 else
8603 {
8604 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8605 return VOS_STATUS_E_FAILURE;
8606 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008607
Jeff Johnson295189b2012-06-20 16:38:30 -07008608
8609 return VOS_STATUS_SUCCESS;
8610}
8611
8612/**---------------------------------------------------------------------------
8613
8614 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8615
8616 \param - pAdapter - Pointer to the HDD
8617
8618 \return - None
8619
8620 --------------------------------------------------------------------------*/
8621VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8622{
8623 eHalStatus halStatus;
8624 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308625 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008626
Jeff Johnson295189b2012-06-20 16:38:30 -07008627
8628 // Send ready indication to the HDD. This will kick off the MAC
8629 // into a 'running' state and should kick off an initial scan.
8630 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8631 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8632 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308633 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 "code %08d [x%08x]",__func__, halStatus, halStatus );
8635 return VOS_STATUS_E_FAILURE;
8636 }
8637
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308638 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8640 // And RIVA will crash
8641 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8642 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308643 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8644 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8645
8646
Jeff Johnson295189b2012-06-20 16:38:30 -07008647 return VOS_STATUS_SUCCESS;
8648}
8649
Jeff Johnson295189b2012-06-20 16:38:30 -07008650/* wake lock APIs for HDD */
8651void hdd_prevent_suspend(void)
8652{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008653#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008654 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008655#else
8656 wcnss_prevent_suspend();
8657#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008658}
8659
8660void hdd_allow_suspend(void)
8661{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008662#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008664#else
8665 wcnss_allow_suspend();
8666#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008667}
8668
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308669void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008670{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008671#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008672 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008673#else
8674 /* Do nothing as there is no API in wcnss for timeout*/
8675#endif
8676}
8677
Jeff Johnson295189b2012-06-20 16:38:30 -07008678/**---------------------------------------------------------------------------
8679
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008680 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8681 information between Host and Riva
8682
8683 This function gets reported version of FW
8684 It also finds the version of Riva headers used to compile the host
8685 It compares the above two and prints a warning if they are different
8686 It gets the SW and HW version string
8687 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8688 indicating the features they support through a bitmap
8689
8690 \param - pHddCtx - Pointer to HDD context
8691
8692 \return - void
8693
8694 --------------------------------------------------------------------------*/
8695
8696void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8697{
8698
8699 tSirVersionType versionCompiled;
8700 tSirVersionType versionReported;
8701 tSirVersionString versionString;
8702 tANI_U8 fwFeatCapsMsgSupported = 0;
8703 VOS_STATUS vstatus;
8704
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008705 memset(&versionCompiled, 0, sizeof(versionCompiled));
8706 memset(&versionReported, 0, sizeof(versionReported));
8707
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008708 /* retrieve and display WCNSS version information */
8709 do {
8710
8711 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8712 &versionCompiled);
8713 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8714 {
8715 hddLog(VOS_TRACE_LEVEL_FATAL,
8716 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008717 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008718 break;
8719 }
8720
8721 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8722 &versionReported);
8723 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8724 {
8725 hddLog(VOS_TRACE_LEVEL_FATAL,
8726 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008727 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008728 break;
8729 }
8730
8731 if ((versionCompiled.major != versionReported.major) ||
8732 (versionCompiled.minor != versionReported.minor) ||
8733 (versionCompiled.version != versionReported.version) ||
8734 (versionCompiled.revision != versionReported.revision))
8735 {
8736 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8737 "Host expected %u.%u.%u.%u\n",
8738 WLAN_MODULE_NAME,
8739 (int)versionReported.major,
8740 (int)versionReported.minor,
8741 (int)versionReported.version,
8742 (int)versionReported.revision,
8743 (int)versionCompiled.major,
8744 (int)versionCompiled.minor,
8745 (int)versionCompiled.version,
8746 (int)versionCompiled.revision);
8747 }
8748 else
8749 {
8750 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8751 WLAN_MODULE_NAME,
8752 (int)versionReported.major,
8753 (int)versionReported.minor,
8754 (int)versionReported.version,
8755 (int)versionReported.revision);
8756 }
8757
8758 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8759 versionString,
8760 sizeof(versionString));
8761 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8762 {
8763 hddLog(VOS_TRACE_LEVEL_FATAL,
8764 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008765 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008766 break;
8767 }
8768
8769 pr_info("%s: WCNSS software version %s\n",
8770 WLAN_MODULE_NAME, versionString);
8771
8772 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8773 versionString,
8774 sizeof(versionString));
8775 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8776 {
8777 hddLog(VOS_TRACE_LEVEL_FATAL,
8778 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008779 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008780 break;
8781 }
8782
8783 pr_info("%s: WCNSS hardware version %s\n",
8784 WLAN_MODULE_NAME, versionString);
8785
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008786 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8787 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008788 send the message only if it the riva is 1.1
8789 minor numbers for different riva branches:
8790 0 -> (1.0)Mainline Build
8791 1 -> (1.1)Mainline Build
8792 2->(1.04) Stability Build
8793 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008794 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008795 ((versionReported.minor>=1) && (versionReported.version>=1)))
8796 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8797 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008798
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008799 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008800 {
8801#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8802 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8803 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8804#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008805 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8806 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8807 {
8808 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8809 }
8810
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008811 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008812 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008813
8814 } while (0);
8815
8816}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308817void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8818{
8819 struct sk_buff *skb;
8820 struct nlmsghdr *nlh;
8821 tAniMsgHdr *ani_hdr;
8822
8823 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8824
8825 if(skb == NULL) {
8826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8827 "%s: alloc_skb failed", __func__);
8828 return;
8829 }
8830
8831 nlh = (struct nlmsghdr *)skb->data;
8832 nlh->nlmsg_pid = 0; /* from kernel */
8833 nlh->nlmsg_flags = 0;
8834 nlh->nlmsg_seq = 0;
8835 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8836
8837 ani_hdr = NLMSG_DATA(nlh);
8838 ani_hdr->type = type;
8839
8840 switch(type) {
8841 case WLAN_SVC_SAP_RESTART_IND:
8842 ani_hdr->length = 0;
8843 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8844 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8845 break;
8846 default:
8847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8848 "Attempt to send unknown nlink message %d", type);
8849 kfree_skb(skb);
8850 return;
8851 }
8852
8853 nl_srv_bcast(skb);
8854
8855 return;
8856}
8857
8858
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008859
8860/**---------------------------------------------------------------------------
8861
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308862 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8863
8864 \param - pHddCtx - Pointer to the hdd context
8865
8866 \return - true if hardware supports 5GHz
8867
8868 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308869boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308870{
8871 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8872 * then hardware support 5Ghz.
8873 */
8874 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8875 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308876 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308877 return true;
8878 }
8879 else
8880 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308881 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308882 __func__);
8883 return false;
8884 }
8885}
8886
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308887/**---------------------------------------------------------------------------
8888
8889 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8890 generate function
8891
8892 This is generate the random mac address for WLAN interface
8893
8894 \param - pHddCtx - Pointer to HDD context
8895 idx - Start interface index to get auto
8896 generated mac addr.
8897 mac_addr - Mac address
8898
8899 \return - 0 for success, < 0 for failure
8900
8901 --------------------------------------------------------------------------*/
8902
8903static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8904 int idx, v_MACADDR_t mac_addr)
8905{
8906 int i;
8907 unsigned int serialno;
8908 serialno = wcnss_get_serial_number();
8909
8910 if (0 != serialno)
8911 {
8912 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8913 bytes of the serial number that can be used to generate
8914 the other 3 bytes of the MAC address. Mask off all but
8915 the lower 3 bytes (this will also make sure we don't
8916 overflow in the next step) */
8917 serialno &= 0x00FFFFFF;
8918
8919 /* we need a unique address for each session */
8920 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8921
8922 /* autogen other Mac addresses */
8923 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8924 {
8925 /* start with the entire default address */
8926 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8927 /* then replace the lower 3 bytes */
8928 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8929 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8930 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8931
8932 serialno++;
8933 hddLog(VOS_TRACE_LEVEL_ERROR,
8934 "%s: Derived Mac Addr: "
8935 MAC_ADDRESS_STR, __func__,
8936 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8937 }
8938
8939 }
8940 else
8941 {
8942 hddLog(LOGE, FL("Failed to Get Serial NO"));
8943 return -1;
8944 }
8945 return 0;
8946}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308947
8948/**---------------------------------------------------------------------------
8949
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308950 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8951 completed to flush out the scan results
8952
8953 11d scan is done during driver load and is a passive scan on all
8954 channels supported by the device, 11d scans may find some APs on
8955 frequencies which are forbidden to be used in the regulatory domain
8956 the device is operating in. If these APs are notified to the supplicant
8957 it may try to connect to these APs, thus flush out all the scan results
8958 which are present in SME after 11d scan is done.
8959
8960 \return - eHalStatus
8961
8962 --------------------------------------------------------------------------*/
8963static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8964 tANI_U32 scanId, eCsrScanStatus status)
8965{
8966 ENTER();
8967
8968 sme_ScanFlushResult(halHandle, 0);
8969
8970 EXIT();
8971
8972 return eHAL_STATUS_SUCCESS;
8973}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05308974/**---------------------------------------------------------------------------
8975
8976 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
8977 logging is completed successfully.
8978
8979 \return - None
8980
8981 --------------------------------------------------------------------------*/
8982void hdd_init_frame_logging_done(void *mgmtlogInitCbContext, VOS_STATUS status)
8983{
8984 hdd_context_t* pHddCtx = (hdd_context_t*)mgmtlogInitCbContext;
8985
8986 if (NULL == pHddCtx)
8987 {
8988 hddLog(VOS_TRACE_LEVEL_ERROR,
8989 "%s: HDD context is NULL",__func__);
8990 return;
8991 }
8992
8993 if (VOS_STATUS_SUCCESS == status)
8994 {
8995 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
8996 pHddCtx->mgmt_frame_logging = TRUE;
8997 }
8998 else
8999 {
9000 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9001 pHddCtx->mgmt_frame_logging = FALSE;
9002 }
9003
9004 return;
9005}
9006/**---------------------------------------------------------------------------
9007
9008 \brief hdd_init_frame_logging - function to initialize frame logging.
9009 Currently only Mgmt Frames are logged in both TX
9010 and Rx direction and are sent to userspace
9011 application using logger thread when queried.
9012
9013 \return - None
9014
9015 --------------------------------------------------------------------------*/
9016void hdd_init_frame_logging(hdd_context_t* pHddCtx, v_BOOL_t enable)
9017{
9018 eHalStatus halStatus = eHAL_STATUS_FAILURE;
9019 tpSirMgmtLoggingInitParam wlanMgmtLoggingInitParam;
9020
9021 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING))
9022 {
9023 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9024 return;
9025 }
9026
9027 wlanMgmtLoggingInitParam = vos_mem_malloc(sizeof(tSirMgmtLoggingInitParam));
9028 if(NULL == wlanMgmtLoggingInitParam)
9029 {
9030 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9031 return;
9032 }
9033
9034 vos_mem_set(wlanMgmtLoggingInitParam, sizeof(tSirMgmtLoggingInitParam), 0);
9035
9036 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring Mgmt Frame Logging %d",
9037 __func__, enable);
9038
9039 if (enable)
9040 {
9041 wlanMgmtLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9042 }
9043
9044 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9045 {
9046 wlanMgmtLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
9047 }
9048
9049 wlanMgmtLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9050 wlanMgmtLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9051 wlanMgmtLoggingInitParam->bufferMode =
9052 WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9053
9054 wlanMgmtLoggingInitParam->enableFlag &= ~WLAN_QXDM_LOG_EN;
9055 wlanMgmtLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
9056
9057 wlanMgmtLoggingInitParam->mgmtlogInitCallback = hdd_init_frame_logging_done;
9058 wlanMgmtLoggingInitParam->mgmtlogInitCbContext= pHddCtx;
9059
9060 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal,
9061 wlanMgmtLoggingInitParam);
9062
9063 if (eHAL_STATUS_SUCCESS != halStatus)
9064 {
9065 vos_mem_free(wlanMgmtLoggingInitParam);
9066 }
9067
9068 return;
9069}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309070
9071/**---------------------------------------------------------------------------
9072
Jeff Johnson295189b2012-06-20 16:38:30 -07009073 \brief hdd_wlan_startup() - HDD init function
9074
9075 This is the driver startup code executed once a WLAN device has been detected
9076
9077 \param - dev - Pointer to the underlying device
9078
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009079 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009080
9081 --------------------------------------------------------------------------*/
9082
9083int hdd_wlan_startup(struct device *dev )
9084{
9085 VOS_STATUS status;
9086 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009087 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009088 hdd_context_t *pHddCtx = NULL;
9089 v_CONTEXT_t pVosContext= NULL;
9090#ifdef WLAN_BTAMP_FEATURE
9091 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9092 WLANBAP_ConfigType btAmpConfig;
9093 hdd_config_t *pConfig;
9094#endif
9095 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009096 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309097 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009098
9099 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009100 /*
9101 * cfg80211: wiphy allocation
9102 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309103 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009104
9105 if(wiphy == NULL)
9106 {
9107 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009108 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009110 pHddCtx = wiphy_priv(wiphy);
9111
Jeff Johnson295189b2012-06-20 16:38:30 -07009112 //Initialize the adapter context to zeros.
9113 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9114
Jeff Johnson295189b2012-06-20 16:38:30 -07009115 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05309117 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009118
9119 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9120
9121 /*Get vos context here bcoz vos_open requires it*/
9122 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9123
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009124 if(pVosContext == NULL)
9125 {
9126 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9127 goto err_free_hdd_context;
9128 }
9129
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 //Save the Global VOSS context in adapter context for future.
9131 pHddCtx->pvosContext = pVosContext;
9132
9133 //Save the adapter context in global context for future.
9134 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9135
Jeff Johnson295189b2012-06-20 16:38:30 -07009136 pHddCtx->parent_dev = dev;
9137
9138 init_completion(&pHddCtx->full_pwr_comp_var);
9139 init_completion(&pHddCtx->standby_comp_var);
9140 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009141 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009142 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309143 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309144 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009145
9146#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009147 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009148#else
9149 init_completion(&pHddCtx->driver_crda_req);
9150#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009151
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309152 spin_lock_init(&pHddCtx->schedScan_lock);
9153
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9155
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309156#ifdef FEATURE_WLAN_TDLS
9157 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9158 * invoked by other instances also) to protect the concurrent
9159 * access for the Adapters by TDLS module.
9160 */
9161 mutex_init(&pHddCtx->tdls_lock);
9162#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309163 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309164 mutex_init(&pHddCtx->wmmLock);
9165
Agarwal Ashish1f422872014-07-22 00:11:55 +05309166 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309167
Agarwal Ashish1f422872014-07-22 00:11:55 +05309168 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009169 // Load all config first as TL config is needed during vos_open
9170 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9171 if(pHddCtx->cfg_ini == NULL)
9172 {
9173 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9174 goto err_free_hdd_context;
9175 }
9176
9177 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9178
9179 // Read and parse the qcom_cfg.ini file
9180 status = hdd_parse_config_ini( pHddCtx );
9181 if ( VOS_STATUS_SUCCESS != status )
9182 {
9183 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9184 __func__, WLAN_INI_FILE);
9185 goto err_config;
9186 }
Arif Hussaind5218912013-12-05 01:10:55 -08009187#ifdef MEMORY_DEBUG
9188 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9189 vos_mem_init();
9190
9191 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9192 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009194
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309195 /* INI has been read, initialise the configuredMcastBcastFilter with
9196 * INI value as this will serve as the default value
9197 */
9198 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9199 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9200 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309201
9202 if (false == hdd_is_5g_supported(pHddCtx))
9203 {
9204 //5Ghz is not supported.
9205 if (1 != pHddCtx->cfg_ini->nBandCapability)
9206 {
9207 hddLog(VOS_TRACE_LEVEL_INFO,
9208 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9209 pHddCtx->cfg_ini->nBandCapability = 1;
9210 }
9211 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309212
9213 /* If SNR Monitoring is enabled, FW has to parse all beacons
9214 * for calcaluting and storing the average SNR, so set Nth beacon
9215 * filter to 1 to enable FW to parse all the beaocons
9216 */
9217 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9218 {
9219 /* The log level is deliberately set to WARN as overriding
9220 * nthBeaconFilter to 1 will increase power cosumption and this
9221 * might just prove helpful to detect the power issue.
9222 */
9223 hddLog(VOS_TRACE_LEVEL_WARN,
9224 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9225 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9226 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309228 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009230 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009231 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009232 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9233 {
9234 hddLog(VOS_TRACE_LEVEL_FATAL,
9235 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9236 goto err_config;
9237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009239
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009240 // Update VOS trace levels based upon the cfg.ini
9241 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9242 pHddCtx->cfg_ini->vosTraceEnableBAP);
9243 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9244 pHddCtx->cfg_ini->vosTraceEnableTL);
9245 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9246 pHddCtx->cfg_ini->vosTraceEnableWDI);
9247 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9248 pHddCtx->cfg_ini->vosTraceEnableHDD);
9249 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9250 pHddCtx->cfg_ini->vosTraceEnableSME);
9251 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9252 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309253 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9254 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009255 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9256 pHddCtx->cfg_ini->vosTraceEnableWDA);
9257 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9258 pHddCtx->cfg_ini->vosTraceEnableSYS);
9259 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9260 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009261 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9262 pHddCtx->cfg_ini->vosTraceEnableSAP);
9263 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9264 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009265
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 // Update WDI trace levels based upon the cfg.ini
9267 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9268 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9269 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9270 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9271 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9272 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9273 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9274 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009275
Jeff Johnson88ba7742013-02-27 14:36:02 -08009276 if (VOS_FTM_MODE == hdd_get_conparam())
9277 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9279 {
9280 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9281 goto err_free_hdd_context;
9282 }
9283 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309284 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309285 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009287 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009288
Jeff Johnson88ba7742013-02-27 14:36:02 -08009289 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9291 {
9292 status = vos_watchdog_open(pVosContext,
9293 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9294
9295 if(!VOS_IS_STATUS_SUCCESS( status ))
9296 {
9297 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309298 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 }
9300 }
9301
9302 pHddCtx->isLogpInProgress = FALSE;
9303 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9304
Amar Singhala49cbc52013-10-08 18:37:44 -07009305#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009306 /* initialize the NV module. This is required so that
9307 we can initialize the channel information in wiphy
9308 from the NV.bin data. The channel information in
9309 wiphy needs to be initialized before wiphy registration */
9310
9311 status = vos_nv_open();
9312 if (!VOS_IS_STATUS_SUCCESS(status))
9313 {
9314 /* NV module cannot be initialized */
9315 hddLog( VOS_TRACE_LEVEL_FATAL,
9316 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309317 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009318 }
9319
9320 status = vos_init_wiphy_from_nv_bin();
9321 if (!VOS_IS_STATUS_SUCCESS(status))
9322 {
9323 /* NV module cannot be initialized */
9324 hddLog( VOS_TRACE_LEVEL_FATAL,
9325 "%s: vos_init_wiphy failed", __func__);
9326 goto err_vos_nv_close;
9327 }
9328
Amar Singhala49cbc52013-10-08 18:37:44 -07009329#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309330 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309331 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 if ( !VOS_IS_STATUS_SUCCESS( status ))
9333 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009334 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309335 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 }
9337
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9339
9340 if ( NULL == pHddCtx->hHal )
9341 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009342 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 goto err_vosclose;
9344 }
9345
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009346 status = vos_preStart( pHddCtx->pvosContext );
9347 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9348 {
9349 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309350 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009351 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009352
Arif Hussaineaf68602013-12-30 23:10:44 -08009353 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9354 {
9355 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9356 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9357 __func__, enable_dfs_chan_scan);
9358 }
9359 if (0 == enable_11d || 1 == enable_11d)
9360 {
9361 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9362 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9363 __func__, enable_11d);
9364 }
9365
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009366 /* Note that the vos_preStart() sequence triggers the cfg download.
9367 The cfg download must occur before we update the SME config
9368 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009369 status = hdd_set_sme_config( pHddCtx );
9370
9371 if ( VOS_STATUS_SUCCESS != status )
9372 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009373 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309374 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009375 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009376
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 /* In the integrated architecture we update the configuration from
9378 the INI file and from NV before vOSS has been started so that
9379 the final contents are available to send down to the cCPU */
9380
9381 // Apply the cfg.ini to cfg.dat
9382 if (FALSE == hdd_update_config_dat(pHddCtx))
9383 {
9384 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309385 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 }
9387
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309388 // Get mac addr from platform driver
9389 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9390
9391 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309393 /* Store the mac addr for first interface */
9394 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9395
9396 hddLog(VOS_TRACE_LEVEL_ERROR,
9397 "%s: WLAN Mac Addr: "
9398 MAC_ADDRESS_STR, __func__,
9399 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9400
9401 /* Here, passing Arg2 as 1 because we do not want to change the
9402 last 3 bytes (means non OUI bytes) of first interface mac
9403 addr.
9404 */
9405 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9406 {
9407 hddLog(VOS_TRACE_LEVEL_ERROR,
9408 "%s: Failed to generate wlan interface mac addr "
9409 "using MAC from ini file ", __func__);
9410 }
9411 }
9412 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9413 {
9414 // Apply the NV to cfg.dat
9415 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009416#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9417 /* There was not a valid set of MAC Addresses in NV. See if the
9418 default addresses were modified by the cfg.ini settings. If so,
9419 we'll use them, but if not, we'll autogenerate a set of MAC
9420 addresses based upon the device serial number */
9421
9422 static const v_MACADDR_t default_address =
9423 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009424
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309425 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9426 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 {
9428 /* cfg.ini has the default address, invoke autogen logic */
9429
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309430 /* Here, passing Arg2 as 0 because we want to change the
9431 last 3 bytes (means non OUI bytes) of all the interfaces
9432 mac addr.
9433 */
9434 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9435 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309437 hddLog(VOS_TRACE_LEVEL_ERROR,
9438 "%s: Failed to generate wlan interface mac addr "
9439 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9440 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009441 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009442 }
9443 else
9444#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9445 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009446 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009447 "%s: Invalid MAC address in NV, using MAC from ini file "
9448 MAC_ADDRESS_STR, __func__,
9449 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9450 }
9451 }
9452 {
9453 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309454
9455 /* Set the MAC Address Currently this is used by HAL to
9456 * add self sta. Remove this once self sta is added as
9457 * part of session open.
9458 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9460 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9461 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309462
Jeff Johnson295189b2012-06-20 16:38:30 -07009463 if (!HAL_STATUS_SUCCESS( halStatus ))
9464 {
9465 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9466 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309467 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 }
9469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009470
9471 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9472 Note: Firmware image will be read and downloaded inside vos_start API */
9473 status = vos_start( pHddCtx->pvosContext );
9474 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9475 {
9476 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309477 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 }
9479
Leo Chang6cec3e22014-01-21 15:33:49 -08009480#ifdef FEATURE_WLAN_CH_AVOID
9481 /* Plug in avoid channel notification callback
9482 * This should happen before ADD_SELF_STA
9483 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309484
9485 /* check the Channel Avoidance is enabled */
9486 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9487 {
9488 sme_AddChAvoidCallback(pHddCtx->hHal,
9489 hdd_hostapd_ch_avoid_cb);
9490 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009491#endif /* FEATURE_WLAN_CH_AVOID */
9492
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009493 /* Exchange capability info between Host and FW and also get versioning info from FW */
9494 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009495
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309496#ifdef CONFIG_ENABLE_LINUX_REG
9497 status = wlan_hdd_init_channels(pHddCtx);
9498 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9499 {
9500 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9501 __func__);
9502 goto err_vosstop;
9503 }
9504#endif
9505
Jeff Johnson295189b2012-06-20 16:38:30 -07009506 status = hdd_post_voss_start_config( pHddCtx );
9507 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9508 {
9509 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9510 __func__);
9511 goto err_vosstop;
9512 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009513
9514#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309515 wlan_hdd_cfg80211_update_reg_info( wiphy );
9516
9517 /* registration of wiphy dev with cfg80211 */
9518 if (0 > wlan_hdd_cfg80211_register(wiphy))
9519 {
9520 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9521 goto err_vosstop;
9522 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009523#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009524
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309525#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309526 /* registration of wiphy dev with cfg80211 */
9527 if (0 > wlan_hdd_cfg80211_register(wiphy))
9528 {
9529 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9530 goto err_vosstop;
9531 }
9532
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309533 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309534 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9535 {
9536 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9537 __func__);
9538 goto err_unregister_wiphy;
9539 }
9540#endif
9541
c_hpothu4a298be2014-12-22 21:12:51 +05309542 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9543
Jeff Johnson295189b2012-06-20 16:38:30 -07009544 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9545 {
9546 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9547 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9548 }
9549 else
9550 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009551 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9552 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9553 if (pAdapter != NULL)
9554 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309555 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309557 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9558 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9559 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009560
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309561 /* Generate the P2P Device Address. This consists of the device's
9562 * primary MAC address with the locally administered bit set.
9563 */
9564 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009565 }
9566 else
9567 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309568 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9569 if (p2p_dev_addr != NULL)
9570 {
9571 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9572 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9573 }
9574 else
9575 {
9576 hddLog(VOS_TRACE_LEVEL_FATAL,
9577 "%s: Failed to allocate mac_address for p2p_device",
9578 __func__);
9579 goto err_close_adapter;
9580 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009582
9583 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9584 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9585 if ( NULL == pP2pAdapter )
9586 {
9587 hddLog(VOS_TRACE_LEVEL_FATAL,
9588 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009589 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009590 goto err_close_adapter;
9591 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009594
9595 if( pAdapter == NULL )
9596 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9598 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009599 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009600
Arif Hussain66559122013-11-21 10:11:40 -08009601 if (country_code)
9602 {
9603 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009604 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009605 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9606#ifndef CONFIG_ENABLE_LINUX_REG
9607 hdd_checkandupdate_phymode(pAdapter, country_code);
9608#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009609 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9610 (void *)(tSmeChangeCountryCallback)
9611 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009612 country_code,
9613 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309614 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009615 if (eHAL_STATUS_SUCCESS == ret)
9616 {
Arif Hussaincb607082013-12-20 11:57:42 -08009617 ret = wait_for_completion_interruptible_timeout(
9618 &pAdapter->change_country_code,
9619 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9620
9621 if (0 >= ret)
9622 {
9623 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9624 "%s: SME while setting country code timed out", __func__);
9625 }
Arif Hussain66559122013-11-21 10:11:40 -08009626 }
9627 else
9628 {
Arif Hussaincb607082013-12-20 11:57:42 -08009629 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9630 "%s: SME Change Country code from module param fail ret=%d",
9631 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009632 }
9633 }
9634
Jeff Johnson295189b2012-06-20 16:38:30 -07009635#ifdef WLAN_BTAMP_FEATURE
9636 vStatus = WLANBAP_Open(pVosContext);
9637 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9638 {
9639 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9640 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009641 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 }
9643
9644 vStatus = BSL_Init(pVosContext);
9645 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9646 {
9647 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9648 "%s: Failed to Init BSL",__func__);
9649 goto err_bap_close;
9650 }
9651 vStatus = WLANBAP_Start(pVosContext);
9652 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9653 {
9654 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9655 "%s: Failed to start TL",__func__);
9656 goto err_bap_close;
9657 }
9658
9659 pConfig = pHddCtx->cfg_ini;
9660 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9661 status = WLANBAP_SetConfig(&btAmpConfig);
9662
9663#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009664
Mihir Shete9c238772014-10-15 14:35:16 +05309665 /*
9666 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9667 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9668 * which is greater than 0xf. So the below check is safe to make
9669 * sure that there is no entry for UapsdMask in the ini
9670 */
9671 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9672 {
9673 if(IS_DYNAMIC_WMM_PS_ENABLED)
9674 {
9675 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9676 __func__);
9677 pHddCtx->cfg_ini->UapsdMask =
9678 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9679 }
9680 else
9681 {
9682 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9683 __func__);
9684 pHddCtx->cfg_ini->UapsdMask =
9685 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9686 }
9687 }
9688
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009689#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9690 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9691 {
9692 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9693 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9694 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9695 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9696 }
9697#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009698
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309699 wlan_hdd_tdls_init(pHddCtx);
9700
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309701 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9702
Jeff Johnson295189b2012-06-20 16:38:30 -07009703 /* Register with platform driver as client for Suspend/Resume */
9704 status = hddRegisterPmOps(pHddCtx);
9705 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9706 {
9707 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9708#ifdef WLAN_BTAMP_FEATURE
9709 goto err_bap_stop;
9710#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009711 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009712#endif //WLAN_BTAMP_FEATURE
9713 }
9714
Yue Ma0d4891e2013-08-06 17:01:45 -07009715 /* Open debugfs interface */
9716 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9717 {
9718 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9719 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009720 }
9721
Jeff Johnson295189b2012-06-20 16:38:30 -07009722 /* Register TM level change handler function to the platform */
9723 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9724 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9725 {
9726 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9727 goto err_unregister_pmops;
9728 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009729
9730 /* register for riva power on lock to platform driver */
9731 if (req_riva_power_on_lock("wlan"))
9732 {
9733 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9734 __func__);
9735 goto err_unregister_pmops;
9736 }
9737
Jeff Johnson295189b2012-06-20 16:38:30 -07009738 // register net device notifier for device change notification
9739 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9740
9741 if(ret < 0)
9742 {
9743 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9744 goto err_free_power_on_lock;
9745 }
9746
9747 //Initialize the nlink service
9748 if(nl_srv_init() != 0)
9749 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309750 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 goto err_reg_netdev;
9752 }
9753
Leo Chang4ce1cc52013-10-21 18:27:15 -07009754#ifdef WLAN_KD_READY_NOTIFIER
9755 pHddCtx->kd_nl_init = 1;
9756#endif /* WLAN_KD_READY_NOTIFIER */
9757
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 //Initialize the BTC service
9759 if(btc_activate_service(pHddCtx) != 0)
9760 {
9761 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9762 goto err_nl_srv;
9763 }
9764
9765#ifdef PTT_SOCK_SVC_ENABLE
9766 //Initialize the PTT service
9767 if(ptt_sock_activate_svc(pHddCtx) != 0)
9768 {
9769 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9770 goto err_nl_srv;
9771 }
9772#endif
9773
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309774#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9775 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9776 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309777 if(wlan_logging_sock_activate_svc(
9778 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9779 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9780 {
9781 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9782 " failed", __func__);
9783 goto err_nl_srv;
9784 }
9785 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9786 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309787 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9788 pHddCtx->cfg_ini->gEnableDebugLog =
9789 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309790 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309791
9792 if (pHddCtx->cfg_ini->enableMgmtLogging &&
9793 pHddCtx->cfg_ini->wlanLoggingEnable)
9794 {
9795 hdd_init_frame_logging(pHddCtx, TRUE);
9796 }
9797 else
9798 {
9799 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Logging disabled in ini"));
9800 }
9801
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309802#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309803
9804
Jeff Johnson295189b2012-06-20 16:38:30 -07009805 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009807 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009808 /* Action frame registered in one adapter which will
9809 * applicable to all interfaces
9810 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309811 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009813
9814 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309815 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009816
Jeff Johnson295189b2012-06-20 16:38:30 -07009817
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009818#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009819#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9820 /* Initialize the wake lcok */
9821 wake_lock_init(&pHddCtx->rx_wake_lock,
9822 WAKE_LOCK_SUSPEND,
9823 "qcom_rx_wakelock");
9824#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009825 /* Initialize the wake lcok */
9826 wake_lock_init(&pHddCtx->sap_wake_lock,
9827 WAKE_LOCK_SUSPEND,
9828 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009829#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009830
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009831 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9832 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009833
Katya Nigam5c306ea2014-06-19 15:39:54 +05309834 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009835 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9836 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309837
9838#ifdef FEATURE_WLAN_SCAN_PNO
9839 /*SME must send channel update configuration to RIVA*/
9840 sme_UpdateChannelConfig(pHddCtx->hHal);
9841#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309842 /* Send the update default channel list to the FW*/
9843 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +05309844
9845 /* Fwr capabilities received, Set the Dot11 mode */
9846 sme_SetDefDot11Mode(pHddCtx->hHal);
9847
Abhishek Singha306a442013-11-07 18:39:01 +05309848#ifndef CONFIG_ENABLE_LINUX_REG
9849 /*updating wiphy so that regulatory user hints can be processed*/
9850 if (wiphy)
9851 {
9852 regulatory_hint(wiphy, "00");
9853 }
9854#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009855 // Initialize the restart logic
9856 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309857
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009858 //Register the traffic monitor timer now
9859 if ( pHddCtx->cfg_ini->dynSplitscan)
9860 {
9861 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9862 VOS_TIMER_TYPE_SW,
9863 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9864 (void *)pHddCtx);
9865 }
Srinivas Dasari030bad32015-02-18 23:23:54 +05309866 wlan_hdd_cfg80211_nan_init(pHddCtx);
9867
Dino Mycle6fb96c12014-06-10 11:52:40 +05309868#ifdef WLAN_FEATURE_EXTSCAN
9869 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9870 wlan_hdd_cfg80211_extscan_callback,
9871 pHddCtx);
9872#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309873
9874#ifdef WLAN_NS_OFFLOAD
9875 // Register IPv6 notifier to notify if any change in IP
9876 // So that we can reconfigure the offload parameters
9877 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
9878 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
9879 if (ret)
9880 {
9881 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
9882 }
9883 else
9884 {
9885 hddLog(LOGE, FL("Registered IPv6 notifier"));
9886 }
9887#endif
9888
9889 // Register IPv4 notifier to notify if any change in IP
9890 // So that we can reconfigure the offload parameters
9891 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
9892 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
9893 if (ret)
9894 {
9895 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
9896 }
9897 else
9898 {
9899 hddLog(LOGE, FL("Registered IPv4 notifier"));
9900 }
9901
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 goto success;
9903
9904err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009905#ifdef WLAN_KD_READY_NOTIFIER
9906 nl_srv_exit(pHddCtx->ptt_pid);
9907#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009909#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009910err_reg_netdev:
9911 unregister_netdevice_notifier(&hdd_netdev_notifier);
9912
9913err_free_power_on_lock:
9914 free_riva_power_on_lock("wlan");
9915
9916err_unregister_pmops:
9917 hddDevTmUnregisterNotifyCallback(pHddCtx);
9918 hddDeregisterPmOps(pHddCtx);
9919
Yue Ma0d4891e2013-08-06 17:01:45 -07009920 hdd_debugfs_exit(pHddCtx);
9921
Jeff Johnson295189b2012-06-20 16:38:30 -07009922#ifdef WLAN_BTAMP_FEATURE
9923err_bap_stop:
9924 WLANBAP_Stop(pVosContext);
9925#endif
9926
9927#ifdef WLAN_BTAMP_FEATURE
9928err_bap_close:
9929 WLANBAP_Close(pVosContext);
9930#endif
9931
Jeff Johnson295189b2012-06-20 16:38:30 -07009932err_close_adapter:
9933 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309934#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309935err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309936#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309937 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009938err_vosstop:
9939 vos_stop(pVosContext);
9940
Amar Singhala49cbc52013-10-08 18:37:44 -07009941err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 status = vos_sched_close( pVosContext );
9943 if (!VOS_IS_STATUS_SUCCESS(status)) {
9944 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9945 "%s: Failed to close VOSS Scheduler", __func__);
9946 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9947 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009948 vos_close(pVosContext );
9949
Amar Singhal0a402232013-10-11 20:57:16 -07009950err_vos_nv_close:
9951
c_hpothue6a36282014-03-19 12:27:38 +05309952#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009953 vos_nv_close();
9954
c_hpothu70f8d812014-03-22 22:59:23 +05309955#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009956
9957err_wdclose:
9958 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9959 vos_watchdog_close(pVosContext);
9960
Jeff Johnson295189b2012-06-20 16:38:30 -07009961err_config:
9962 kfree(pHddCtx->cfg_ini);
9963 pHddCtx->cfg_ini= NULL;
9964
9965err_free_hdd_context:
9966 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 wiphy_free(wiphy) ;
9968 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 VOS_BUG(1);
9970
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009971 if (hdd_is_ssr_required())
9972 {
9973 /* WDI timeout had happened during load, so SSR is needed here */
9974 subsystem_restart("wcnss");
9975 msleep(5000);
9976 }
9977 hdd_set_ssr_required (VOS_FALSE);
9978
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009979 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009980
9981success:
9982 EXIT();
9983 return 0;
9984}
9985
9986/**---------------------------------------------------------------------------
9987
Jeff Johnson32d95a32012-09-10 13:15:23 -07009988 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009989
Jeff Johnson32d95a32012-09-10 13:15:23 -07009990 This is the driver entry point - called in different timeline depending
9991 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009992
9993 \param - None
9994
9995 \return - 0 for success, non zero for failure
9996
9997 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009998static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009999{
10000 VOS_STATUS status;
10001 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 struct device *dev = NULL;
10003 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010004#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10005 int max_retries = 0;
10006#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010007#ifdef HAVE_CBC_DONE
10008 int max_cbc_retries = 0;
10009#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010010
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010011#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10012 wlan_logging_sock_init_svc();
10013#endif
10014
Jeff Johnson295189b2012-06-20 16:38:30 -070010015 ENTER();
10016
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010017#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -070010019#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010020
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010021 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -070010022 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10023 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10024
Jeff Johnson295189b2012-06-20 16:38:30 -070010025#ifdef ANI_BUS_TYPE_PCI
10026
10027 dev = wcnss_wlan_get_device();
10028
10029#endif // ANI_BUS_TYPE_PCI
10030
10031#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010032
10033#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10034 /* wait until WCNSS driver downloads NV */
10035 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10036 msleep(1000);
10037 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010038
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010039 if (max_retries >= 5) {
10040 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +053010041#ifdef WLAN_OPEN_SOURCE
10042 wake_lock_destroy(&wlan_wake_lock);
10043#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010044
10045#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10046 wlan_logging_sock_deinit_svc();
10047#endif
10048
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010049 return -ENODEV;
10050 }
10051#endif
10052
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010053#ifdef HAVE_CBC_DONE
10054 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10055 msleep(1000);
10056 }
10057 if (max_cbc_retries >= 10) {
10058 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10059 }
10060#endif
10061
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 dev = wcnss_wlan_get_device();
10063#endif // ANI_BUS_TYPE_PLATFORM
10064
10065
10066 do {
10067 if (NULL == dev) {
10068 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10069 ret_status = -1;
10070 break;
10071 }
10072
Jeff Johnson295189b2012-06-20 16:38:30 -070010073#ifdef TIMER_MANAGER
10074 vos_timer_manager_init();
10075#endif
10076
10077 /* Preopen VOSS so that it is ready to start at least SAL */
10078 status = vos_preOpen(&pVosContext);
10079
10080 if (!VOS_IS_STATUS_SUCCESS(status))
10081 {
10082 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10083 ret_status = -1;
10084 break;
10085 }
10086
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010087#ifndef MODULE
10088 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10089 */
10090 hdd_set_conparam((v_UINT_t)con_mode);
10091#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010092
10093 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010094 if (hdd_wlan_startup(dev))
10095 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010096 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010097 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 vos_preClose( &pVosContext );
10099 ret_status = -1;
10100 break;
10101 }
10102
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 } while (0);
10104
10105 if (0 != ret_status)
10106 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010107#ifdef TIMER_MANAGER
10108 vos_timer_exit();
10109#endif
10110#ifdef MEMORY_DEBUG
10111 vos_mem_exit();
10112#endif
10113
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010114#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010116#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010117
10118#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10119 wlan_logging_sock_deinit_svc();
10120#endif
10121
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10123 }
10124 else
10125 {
10126 //Send WLAN UP indication to Nlink Service
10127 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10128
10129 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 }
10131
10132 EXIT();
10133
10134 return ret_status;
10135}
10136
Jeff Johnson32d95a32012-09-10 13:15:23 -070010137/**---------------------------------------------------------------------------
10138
10139 \brief hdd_module_init() - Init Function
10140
10141 This is the driver entry point (invoked when module is loaded using insmod)
10142
10143 \param - None
10144
10145 \return - 0 for success, non zero for failure
10146
10147 --------------------------------------------------------------------------*/
10148#ifdef MODULE
10149static int __init hdd_module_init ( void)
10150{
10151 return hdd_driver_init();
10152}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010153#else /* #ifdef MODULE */
10154static int __init hdd_module_init ( void)
10155{
10156 /* Driver initialization is delayed to fwpath_changed_handler */
10157 return 0;
10158}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010159#endif /* #ifdef MODULE */
10160
Jeff Johnson295189b2012-06-20 16:38:30 -070010161
10162/**---------------------------------------------------------------------------
10163
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010164 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010165
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010166 This is the driver exit point (invoked when module is unloaded using rmmod
10167 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010168
10169 \param - None
10170
10171 \return - None
10172
10173 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010174static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010175{
10176 hdd_context_t *pHddCtx = NULL;
10177 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010178 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010179 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010180
10181 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10182
10183 //Get the global vos context
10184 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10185
10186 if(!pVosContext)
10187 {
10188 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10189 goto done;
10190 }
10191
10192 //Get the HDD context.
10193 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10194
10195 if(!pHddCtx)
10196 {
10197 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10198 }
10199 else
10200 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010201 /* We wait for active entry threads to exit from driver
10202 * by waiting until rtnl_lock is available.
10203 */
10204 rtnl_lock();
10205 rtnl_unlock();
10206
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010207 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10208 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10209 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10210 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010212 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010213 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10214 msecs_to_jiffies(30000));
10215 if(!rc)
10216 {
10217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10218 "%s:SSR timedout, fatal error", __func__);
10219 VOS_BUG(0);
10220 }
10221 }
10222
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010223 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10224 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010225
c_hpothu8adb97b2014-12-08 19:38:20 +053010226 /* Driver Need to send country code 00 in below condition
10227 * 1) If gCountryCodePriority is set to 1; and last country
10228 * code set is through 11d. This needs to be done in case
10229 * when NV country code is 00.
10230 * This Needs to be done as when kernel store last country
10231 * code and if stored country code is not through 11d,
10232 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10233 * in next load/unload as soon as we get any country through
10234 * 11d. In sme_HandleChangeCountryCodeByUser
10235 * pMsg->countryCode will be last countryCode and
10236 * pMac->scan.countryCode11d will be country through 11d so
10237 * due to mismatch driver will disable 11d.
10238 *
10239 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010240
c_hpothu8adb97b2014-12-08 19:38:20 +053010241 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010242 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010243 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010244 {
10245 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010246 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010247 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10248 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010249
c_hpothu8adb97b2014-12-08 19:38:20 +053010250 //Do all the cleanup before deregistering the driver
10251 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010252 }
10253
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 vos_preClose( &pVosContext );
10255
10256#ifdef TIMER_MANAGER
10257 vos_timer_exit();
10258#endif
10259#ifdef MEMORY_DEBUG
10260 vos_mem_exit();
10261#endif
10262
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010263#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10264 wlan_logging_sock_deinit_svc();
10265#endif
10266
Jeff Johnson295189b2012-06-20 16:38:30 -070010267done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010268#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010270#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010271
Jeff Johnson295189b2012-06-20 16:38:30 -070010272 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10273}
10274
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010275/**---------------------------------------------------------------------------
10276
10277 \brief hdd_module_exit() - Exit function
10278
10279 This is the driver exit point (invoked when module is unloaded using rmmod)
10280
10281 \param - None
10282
10283 \return - None
10284
10285 --------------------------------------------------------------------------*/
10286static void __exit hdd_module_exit(void)
10287{
10288 hdd_driver_exit();
10289}
10290
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010291#ifdef MODULE
10292static int fwpath_changed_handler(const char *kmessage,
10293 struct kernel_param *kp)
10294{
Jeff Johnson76052702013-04-16 13:55:05 -070010295 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010296}
10297
10298static int con_mode_handler(const char *kmessage,
10299 struct kernel_param *kp)
10300{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010301 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010302}
10303#else /* #ifdef MODULE */
10304/**---------------------------------------------------------------------------
10305
Jeff Johnson76052702013-04-16 13:55:05 -070010306 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010307
Jeff Johnson76052702013-04-16 13:55:05 -070010308 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010309 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010310 - invoked when module parameter fwpath is modified from userspace to signal
10311 initializing the WLAN driver or when con_mode is modified from userspace
10312 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010313
10314 \return - 0 for success, non zero for failure
10315
10316 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010317static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010318{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010319 int ret_status;
10320
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010321 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010322 ret_status = hdd_driver_init();
10323 wlan_hdd_inited = ret_status ? 0 : 1;
10324 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010325 }
10326
10327 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010328
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010329 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010330
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010331 ret_status = hdd_driver_init();
10332 wlan_hdd_inited = ret_status ? 0 : 1;
10333 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010334}
10335
Jeff Johnson295189b2012-06-20 16:38:30 -070010336/**---------------------------------------------------------------------------
10337
Jeff Johnson76052702013-04-16 13:55:05 -070010338 \brief fwpath_changed_handler() - Handler Function
10339
10340 Handle changes to the fwpath parameter
10341
10342 \return - 0 for success, non zero for failure
10343
10344 --------------------------------------------------------------------------*/
10345static int fwpath_changed_handler(const char *kmessage,
10346 struct kernel_param *kp)
10347{
10348 int ret;
10349
10350 ret = param_set_copystring(kmessage, kp);
10351 if (0 == ret)
10352 ret = kickstart_driver();
10353 return ret;
10354}
10355
10356/**---------------------------------------------------------------------------
10357
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010358 \brief con_mode_handler() -
10359
10360 Handler function for module param con_mode when it is changed by userspace
10361 Dynamically linked - do nothing
10362 Statically linked - exit and init driver, as in rmmod and insmod
10363
Jeff Johnson76052702013-04-16 13:55:05 -070010364 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010365
Jeff Johnson76052702013-04-16 13:55:05 -070010366 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010367
10368 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010369static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010370{
Jeff Johnson76052702013-04-16 13:55:05 -070010371 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010372
Jeff Johnson76052702013-04-16 13:55:05 -070010373 ret = param_set_int(kmessage, kp);
10374 if (0 == ret)
10375 ret = kickstart_driver();
10376 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010377}
10378#endif /* #ifdef MODULE */
10379
10380/**---------------------------------------------------------------------------
10381
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 \brief hdd_get_conparam() -
10383
10384 This is the driver exit point (invoked when module is unloaded using rmmod)
10385
10386 \param - None
10387
10388 \return - tVOS_CON_MODE
10389
10390 --------------------------------------------------------------------------*/
10391tVOS_CON_MODE hdd_get_conparam ( void )
10392{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010393#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010394 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010395#else
10396 return (tVOS_CON_MODE)curr_con_mode;
10397#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010398}
10399void hdd_set_conparam ( v_UINT_t newParam )
10400{
10401 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010402#ifndef MODULE
10403 curr_con_mode = con_mode;
10404#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010405}
10406/**---------------------------------------------------------------------------
10407
10408 \brief hdd_softap_sta_deauth() - function
10409
10410 This to take counter measure to handle deauth req from HDD
10411
10412 \param - pAdapter - Pointer to the HDD
10413
10414 \param - enable - boolean value
10415
10416 \return - None
10417
10418 --------------------------------------------------------------------------*/
10419
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010420VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10421 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010422{
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010424 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010425
10426 ENTER();
10427
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010428 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10429 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010430
10431 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010432 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010433 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010434
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010435 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010436
10437 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010438 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010439}
10440
10441/**---------------------------------------------------------------------------
10442
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010443 \brief hdd_del_all_sta() - function
10444
10445 This function removes all the stations associated on stopping AP/P2P GO.
10446
10447 \param - pAdapter - Pointer to the HDD
10448
10449 \return - None
10450
10451 --------------------------------------------------------------------------*/
10452
10453int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10454{
10455 v_U16_t i;
10456 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010457 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10458 ptSapContext pSapCtx = NULL;
10459 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10460 if(pSapCtx == NULL){
10461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10462 FL("psapCtx is NULL"));
10463 return 1;
10464 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010465 ENTER();
10466
10467 hddLog(VOS_TRACE_LEVEL_INFO,
10468 "%s: Delete all STAs associated.",__func__);
10469 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10470 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10471 )
10472 {
10473 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10474 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010475 if ((pSapCtx->aStaInfo[i].isUsed) &&
10476 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010477 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010478 struct tagCsrDelStaParams delStaParams;
10479
10480 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010481 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010482 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10483 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010484 &delStaParams);
10485 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010486 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010487 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010488 }
10489 }
10490 }
10491
10492 EXIT();
10493 return 0;
10494}
10495
10496/**---------------------------------------------------------------------------
10497
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 \brief hdd_softap_sta_disassoc() - function
10499
10500 This to take counter measure to handle deauth req from HDD
10501
10502 \param - pAdapter - Pointer to the HDD
10503
10504 \param - enable - boolean value
10505
10506 \return - None
10507
10508 --------------------------------------------------------------------------*/
10509
10510void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10511{
10512 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10513
10514 ENTER();
10515
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010516 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010517
10518 //Ignore request to disassoc bcmc station
10519 if( pDestMacAddress[0] & 0x1 )
10520 return;
10521
10522 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10523}
10524
10525void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10526{
10527 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10528
10529 ENTER();
10530
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010531 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010532
10533 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10534}
10535
Jeff Johnson295189b2012-06-20 16:38:30 -070010536/**---------------------------------------------------------------------------
10537 *
10538 * \brief hdd_get__concurrency_mode() -
10539 *
10540 *
10541 * \param - None
10542 *
10543 * \return - CONCURRENCY MODE
10544 *
10545 * --------------------------------------------------------------------------*/
10546tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10547{
10548 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10549 hdd_context_t *pHddCtx;
10550
10551 if (NULL != pVosContext)
10552 {
10553 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10554 if (NULL != pHddCtx)
10555 {
10556 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10557 }
10558 }
10559
10560 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010561 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 return VOS_STA;
10563}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010564v_BOOL_t
10565wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10566{
10567 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010568
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010569 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10570 if (pAdapter == NULL)
10571 {
10572 hddLog(VOS_TRACE_LEVEL_INFO,
10573 FL("GO doesn't exist"));
10574 return TRUE;
10575 }
10576 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10577 {
10578 hddLog(VOS_TRACE_LEVEL_INFO,
10579 FL("GO started"));
10580 return TRUE;
10581 }
10582 else
10583 /* wait till GO changes its interface to p2p device */
10584 hddLog(VOS_TRACE_LEVEL_INFO,
10585 FL("Del_bss called, avoid apps suspend"));
10586 return FALSE;
10587
10588}
Jeff Johnson295189b2012-06-20 16:38:30 -070010589/* Decide whether to allow/not the apps power collapse.
10590 * Allow apps power collapse if we are in connected state.
10591 * if not, allow only if we are in IMPS */
10592v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10593{
10594 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010595 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010596 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10598 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10599 hdd_adapter_t *pAdapter = NULL;
10600 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010601 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010602
Jeff Johnson295189b2012-06-20 16:38:30 -070010603 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10604 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010605
Yathish9f22e662012-12-10 14:21:35 -080010606 concurrent_state = hdd_get_concurrency_mode();
10607
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010608 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10609 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10610 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010611#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010612
Yathish9f22e662012-12-10 14:21:35 -080010613 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010614 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010615 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10616 return TRUE;
10617#endif
10618
Jeff Johnson295189b2012-06-20 16:38:30 -070010619 /*loop through all adapters. TBD fix for Concurrency */
10620 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10621 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10622 {
10623 pAdapter = pAdapterNode->pAdapter;
10624 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10625 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10626 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010627 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010628 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010629 && pmcState != STOPPED && pmcState != STANDBY &&
10630 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010631 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10632 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010633 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010634 if(pmcState == FULL_POWER &&
10635 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10636 {
10637 /*
10638 * When SCO indication comes from Coex module , host will
10639 * enter in to full power mode, but this should not prevent
10640 * apps processor power collapse.
10641 */
10642 hddLog(LOG1,
10643 FL("Allow apps power collapse"
10644 "even when sco indication is set"));
10645 return TRUE;
10646 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010647 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010648 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10649 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010650 return FALSE;
10651 }
10652 }
10653 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10654 pAdapterNode = pNext;
10655 }
10656 return TRUE;
10657}
10658
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010659/* Decides whether to send suspend notification to Riva
10660 * if any adapter is in BMPS; then it is required */
10661v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10662{
10663 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10664 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10665
10666 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10667 {
10668 return TRUE;
10669 }
10670 return FALSE;
10671}
10672
Jeff Johnson295189b2012-06-20 16:38:30 -070010673void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10674{
10675 switch(mode)
10676 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010677 case VOS_STA_MODE:
10678 case VOS_P2P_CLIENT_MODE:
10679 case VOS_P2P_GO_MODE:
10680 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010681 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010682 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010683 break;
10684 default:
10685 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010686 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010687 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10688 "Number of open sessions for mode %d = %d"),
10689 pHddCtx->concurrency_mode, mode,
10690 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010691}
10692
10693
10694void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10695{
10696 switch(mode)
10697 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010698 case VOS_STA_MODE:
10699 case VOS_P2P_CLIENT_MODE:
10700 case VOS_P2P_GO_MODE:
10701 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010702 pHddCtx->no_of_open_sessions[mode]--;
10703 if (!(pHddCtx->no_of_open_sessions[mode]))
10704 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010705 break;
10706 default:
10707 break;
10708 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010709 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10710 "Number of open sessions for mode %d = %d"),
10711 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10712
10713}
10714/**---------------------------------------------------------------------------
10715 *
10716 * \brief wlan_hdd_incr_active_session()
10717 *
10718 * This function increments the number of active sessions
10719 * maintained per device mode
10720 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10721 * Incase of SAP/P2P GO upon bss start it is incremented
10722 *
10723 * \param pHddCtx - HDD Context
10724 * \param mode - device mode
10725 *
10726 * \return - None
10727 *
10728 * --------------------------------------------------------------------------*/
10729void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10730{
10731 switch (mode) {
10732 case VOS_STA_MODE:
10733 case VOS_P2P_CLIENT_MODE:
10734 case VOS_P2P_GO_MODE:
10735 case VOS_STA_SAP_MODE:
10736 pHddCtx->no_of_active_sessions[mode]++;
10737 break;
10738 default:
10739 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10740 break;
10741 }
10742 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10743 mode,
10744 pHddCtx->no_of_active_sessions[mode]);
10745}
10746
10747/**---------------------------------------------------------------------------
10748 *
10749 * \brief wlan_hdd_decr_active_session()
10750 *
10751 * This function decrements the number of active sessions
10752 * maintained per device mode
10753 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10754 * Incase of SAP/P2P GO upon bss stop it is decremented
10755 *
10756 * \param pHddCtx - HDD Context
10757 * \param mode - device mode
10758 *
10759 * \return - None
10760 *
10761 * --------------------------------------------------------------------------*/
10762void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10763{
10764 switch (mode) {
10765 case VOS_STA_MODE:
10766 case VOS_P2P_CLIENT_MODE:
10767 case VOS_P2P_GO_MODE:
10768 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010769 if (pHddCtx->no_of_active_sessions[mode] > 0)
10770 pHddCtx->no_of_active_sessions[mode]--;
10771 else
10772 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10773 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010774 break;
10775 default:
10776 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10777 break;
10778 }
10779 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10780 mode,
10781 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010782}
10783
Jeff Johnsone7245742012-09-05 17:12:55 -070010784/**---------------------------------------------------------------------------
10785 *
10786 * \brief wlan_hdd_restart_init
10787 *
10788 * This function initalizes restart timer/flag. An internal function.
10789 *
10790 * \param - pHddCtx
10791 *
10792 * \return - None
10793 *
10794 * --------------------------------------------------------------------------*/
10795
10796static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10797{
10798 /* Initialize */
10799 pHddCtx->hdd_restart_retries = 0;
10800 atomic_set(&pHddCtx->isRestartInProgress, 0);
10801 vos_timer_init(&pHddCtx->hdd_restart_timer,
10802 VOS_TIMER_TYPE_SW,
10803 wlan_hdd_restart_timer_cb,
10804 pHddCtx);
10805}
10806/**---------------------------------------------------------------------------
10807 *
10808 * \brief wlan_hdd_restart_deinit
10809 *
10810 * This function cleans up the resources used. An internal function.
10811 *
10812 * \param - pHddCtx
10813 *
10814 * \return - None
10815 *
10816 * --------------------------------------------------------------------------*/
10817
10818static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10819{
10820
10821 VOS_STATUS vos_status;
10822 /* Block any further calls */
10823 atomic_set(&pHddCtx->isRestartInProgress, 1);
10824 /* Cleanup */
10825 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10826 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010827 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010828 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10829 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010830 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010831
10832}
10833
10834/**---------------------------------------------------------------------------
10835 *
10836 * \brief wlan_hdd_framework_restart
10837 *
10838 * This function uses a cfg80211 API to start a framework initiated WLAN
10839 * driver module unload/load.
10840 *
10841 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10842 *
10843 *
10844 * \param - pHddCtx
10845 *
10846 * \return - VOS_STATUS_SUCCESS: Success
10847 * VOS_STATUS_E_EMPTY: Adapter is Empty
10848 * VOS_STATUS_E_NOMEM: No memory
10849
10850 * --------------------------------------------------------------------------*/
10851
10852static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10853{
10854 VOS_STATUS status = VOS_STATUS_SUCCESS;
10855 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010856 int len = (sizeof (struct ieee80211_mgmt));
10857 struct ieee80211_mgmt *mgmt = NULL;
10858
10859 /* Prepare the DEAUTH managment frame with reason code */
10860 mgmt = kzalloc(len, GFP_KERNEL);
10861 if(mgmt == NULL)
10862 {
10863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10864 "%s: memory allocation failed (%d bytes)", __func__, len);
10865 return VOS_STATUS_E_NOMEM;
10866 }
10867 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010868
10869 /* Iterate over all adapters/devices */
10870 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053010871 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
10872 {
10873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10874 FL("fail to get adapter: %p %d"), pAdapterNode, status);
10875 goto end;
10876 }
10877
Jeff Johnsone7245742012-09-05 17:12:55 -070010878 do
10879 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053010880 if(pAdapterNode->pAdapter &&
10881 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070010882 {
10883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10884 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10885 pAdapterNode->pAdapter->dev->name,
10886 pAdapterNode->pAdapter->device_mode,
10887 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010888 /*
10889 * CFG80211 event to restart the driver
10890 *
10891 * 'cfg80211_send_unprot_deauth' sends a
10892 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10893 * of SME(Linux Kernel) state machine.
10894 *
10895 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10896 * the driver.
10897 *
10898 */
10899
10900 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010901 }
10902 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10903 pAdapterNode = pNext;
10904 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10905
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053010906 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010907 /* Free the allocated management frame */
10908 kfree(mgmt);
10909
Jeff Johnsone7245742012-09-05 17:12:55 -070010910 /* Retry until we unload or reach max count */
10911 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10912 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10913
10914 return status;
10915
10916}
10917/**---------------------------------------------------------------------------
10918 *
10919 * \brief wlan_hdd_restart_timer_cb
10920 *
10921 * Restart timer callback. An internal function.
10922 *
10923 * \param - User data:
10924 *
10925 * \return - None
10926 *
10927 * --------------------------------------------------------------------------*/
10928
10929void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10930{
10931 hdd_context_t *pHddCtx = usrDataForCallback;
10932 wlan_hdd_framework_restart(pHddCtx);
10933 return;
10934
10935}
10936
10937
10938/**---------------------------------------------------------------------------
10939 *
10940 * \brief wlan_hdd_restart_driver
10941 *
10942 * This function sends an event to supplicant to restart the WLAN driver.
10943 *
10944 * This function is called from vos_wlanRestart.
10945 *
10946 * \param - pHddCtx
10947 *
10948 * \return - VOS_STATUS_SUCCESS: Success
10949 * VOS_STATUS_E_EMPTY: Adapter is Empty
10950 * VOS_STATUS_E_ALREADY: Request already in progress
10951
10952 * --------------------------------------------------------------------------*/
10953VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10954{
10955 VOS_STATUS status = VOS_STATUS_SUCCESS;
10956
10957 /* A tight check to make sure reentrancy */
10958 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10959 {
Mihir Shetefd528652014-06-23 19:07:50 +053010960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010961 "%s: WLAN restart is already in progress", __func__);
10962
10963 return VOS_STATUS_E_ALREADY;
10964 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010965 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010966#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010967 wcnss_reset_intr();
10968#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010969
Jeff Johnsone7245742012-09-05 17:12:55 -070010970 return status;
10971}
10972
Mihir Shetee1093ba2014-01-21 20:13:32 +053010973/**---------------------------------------------------------------------------
10974 *
10975 * \brief wlan_hdd_init_channels
10976 *
10977 * This function is used to initialize the channel list in CSR
10978 *
10979 * This function is called from hdd_wlan_startup
10980 *
10981 * \param - pHddCtx: HDD context
10982 *
10983 * \return - VOS_STATUS_SUCCESS: Success
10984 * VOS_STATUS_E_FAULT: Failure reported by SME
10985
10986 * --------------------------------------------------------------------------*/
10987static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10988{
10989 eHalStatus status;
10990
10991 status = sme_InitChannels(pHddCtx->hHal);
10992 if (HAL_STATUS_SUCCESS(status))
10993 {
10994 return VOS_STATUS_SUCCESS;
10995 }
10996 else
10997 {
10998 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10999 __func__, status);
11000 return VOS_STATUS_E_FAULT;
11001 }
11002}
11003
Mihir Shete04206452014-11-20 17:50:58 +053011004#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011005VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011006{
11007 eHalStatus status;
11008
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011009 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011010 if (HAL_STATUS_SUCCESS(status))
11011 {
11012 return VOS_STATUS_SUCCESS;
11013 }
11014 else
11015 {
11016 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11017 __func__, status);
11018 return VOS_STATUS_E_FAULT;
11019 }
11020}
Mihir Shete04206452014-11-20 17:50:58 +053011021#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011022/*
11023 * API to find if there is any STA or P2P-Client is connected
11024 */
11025VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11026{
11027 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11028}
Jeff Johnsone7245742012-09-05 17:12:55 -070011029
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011030
11031/*
11032 * API to find if the firmware will send logs using DXE channel
11033 */
11034v_U8_t hdd_is_fw_logging_enabled(void)
11035{
11036 hdd_context_t *pHddCtx;
11037
11038 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11039 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11040
11041 return (pHddCtx && pHddCtx->mgmt_frame_logging);
11042}
11043
Agarwal Ashish57e84372014-12-05 18:26:53 +053011044/*
11045 * API to find if there is any session connected
11046 */
11047VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11048{
11049 return sme_is_any_session_connected(pHddCtx->hHal);
11050}
11051
11052
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011053int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11054{
11055 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11056 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011057 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011058 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011059
11060 pScanInfo = &pHddCtx->scan_info;
11061 if (pScanInfo->mScanPending)
11062 {
c_hpothua3d45d52015-01-05 14:11:17 +053011063 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11064 eCSR_SCAN_ABORT_DEFAULT);
11065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11066 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011067
c_hpothua3d45d52015-01-05 14:11:17 +053011068 /* If there is active scan command lets wait for the completion else
11069 * there is no need to wait as scan command might be in the SME pending
11070 * command list.
11071 */
11072 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11073 {
11074 INIT_COMPLETION(pScanInfo->abortscan_event_var);
11075 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011076 &pScanInfo->abortscan_event_var,
11077 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011078 if (0 >= status)
11079 {
11080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011081 "%s: Timeout or Interrupt occurred while waiting for abort"
11082 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011083 return -ETIMEDOUT;
11084 }
11085 }
11086 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11087 {
11088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11089 FL("hdd_abort_mac_scan failed"));
11090 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011091 }
11092 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011093 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011094}
11095
c_hpothu225aa7c2014-10-22 17:45:13 +053011096VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11097{
11098 hdd_adapter_t *pAdapter;
11099 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11100 VOS_STATUS vosStatus;
11101
11102 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11103 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11104 {
11105 pAdapter = pAdapterNode->pAdapter;
11106 if (NULL != pAdapter)
11107 {
11108 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11109 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11110 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11111 {
11112 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11113 pAdapter->device_mode);
11114 if (VOS_STATUS_SUCCESS !=
11115 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11116 {
11117 hddLog(LOGE, FL("failed to abort ROC"));
11118 return VOS_STATUS_E_FAILURE;
11119 }
11120 }
11121 }
11122 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11123 pAdapterNode = pNext;
11124 }
11125 return VOS_STATUS_SUCCESS;
11126}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011127
Mihir Shete0be28772015-02-17 18:42:14 +053011128hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11129{
11130 hdd_adapter_t *pAdapter;
11131 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11132 hdd_cfg80211_state_t *cfgState;
11133 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11134 VOS_STATUS vosStatus;
11135
11136 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11137 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11138 {
11139 pAdapter = pAdapterNode->pAdapter;
11140 if (NULL != pAdapter)
11141 {
11142 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11143 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11144 if (pRemainChanCtx)
11145 break;
11146 }
11147 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11148 pAdapterNode = pNext;
11149 }
11150 return pRemainChanCtx;
11151}
11152
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011153/**
11154 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11155 *
11156 * @pHddCtx: HDD context within host driver
11157 * @dfsScanMode: dfsScanMode passed from ioctl
11158 *
11159 */
11160
11161VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11162 tANI_U8 dfsScanMode)
11163{
11164 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11165 hdd_adapter_t *pAdapter;
11166 VOS_STATUS vosStatus;
11167 hdd_station_ctx_t *pHddStaCtx;
11168 eHalStatus status = eHAL_STATUS_SUCCESS;
11169
11170 if(!pHddCtx)
11171 {
11172 hddLog(LOGE, FL("HDD context is Null"));
11173 return eHAL_STATUS_FAILURE;
11174 }
11175
11176 if (pHddCtx->scan_info.mScanPending)
11177 {
11178 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11179 pHddCtx->scan_info.sessionId);
11180 hdd_abort_mac_scan(pHddCtx,
11181 pHddCtx->scan_info.sessionId,
11182 eCSR_SCAN_ABORT_DEFAULT);
11183 }
11184
11185 if (!dfsScanMode)
11186 {
11187 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11188 while ((NULL != pAdapterNode) &&
11189 (VOS_STATUS_SUCCESS == vosStatus))
11190 {
11191 pAdapter = pAdapterNode->pAdapter;
11192
11193 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11194 {
11195 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11196
11197 if(!pHddStaCtx)
11198 {
11199 hddLog(LOGE, FL("HDD STA context is Null"));
11200 return eHAL_STATUS_FAILURE;
11201 }
11202
11203 /* if STA is already connected on DFS channel,
11204 disconnect immediately*/
11205 if (hdd_connIsConnected(pHddStaCtx) &&
11206 (NV_CHANNEL_DFS ==
11207 vos_nv_getChannelEnabledState(
11208 pHddStaCtx->conn_info.operationChannel)))
11209 {
11210 status = sme_RoamDisconnect(pHddCtx->hHal,
11211 pAdapter->sessionId,
11212 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11213 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11214 "sme_RoamDisconnect returned with status: %d"
11215 "for sessionid: %d"), pHddStaCtx->conn_info.
11216 operationChannel, status, pAdapter->sessionId);
11217 }
11218 }
11219
11220 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11221 &pNext);
11222 pAdapterNode = pNext;
11223 }
11224 }
11225
11226 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11227 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11228 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11229
11230 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11231 if (!HAL_STATUS_SUCCESS(status))
11232 {
11233 hddLog(LOGE,
11234 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11235 return status;
11236 }
11237
11238 return status;
11239}
11240
Jeff Johnson295189b2012-06-20 16:38:30 -070011241//Register the module init/exit functions
11242module_init(hdd_module_init);
11243module_exit(hdd_module_exit);
11244
11245MODULE_LICENSE("Dual BSD/GPL");
11246MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11247MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11248
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011249module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11250 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011251
Jeff Johnson76052702013-04-16 13:55:05 -070011252module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011253 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011254
11255module_param(enable_dfs_chan_scan, int,
11256 S_IRUSR | S_IRGRP | S_IROTH);
11257
11258module_param(enable_11d, int,
11259 S_IRUSR | S_IRGRP | S_IROTH);
11260
11261module_param(country_code, charp,
11262 S_IRUSR | S_IRGRP | S_IROTH);