blob: 25b3b307364a338960f8d301a1359aa6e32b9c74 [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 */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302617 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002618 {
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 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05302682 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002683 {
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 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303264 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003265 {
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 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303321 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003322 {
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 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303429 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003430 {
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 */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303781 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003782 {
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
Jeff Johnson88ba7742013-02-27 14:36:02 -08008230 if (VOS_FTM_MODE != hdd_get_conparam())
8231 {
8232 // Unloading, restart logic is no more required.
8233 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008234
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308235#ifdef FEATURE_WLAN_TDLS
8236 /* At the time of driver unloading; if tdls connection is present;
8237 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8238 * wlan_hdd_tdls_find_peer always checks for valid context;
8239 * as load/unload in progress there can be a race condition.
8240 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8241 * when tdls state is enabled.
8242 * As soon as driver set load/unload flag; tdls flag also needs
8243 * to be disabled so that hdd_rx_packet_cbk won't call
8244 * wlan_hdd_tdls_find_peer.
8245 */
8246 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8247#endif
8248
c_hpothu5ab05e92014-06-13 17:34:05 +05308249 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8250 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308252 pAdapter = pAdapterNode->pAdapter;
8253 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308255 /* Disable TX on the interface, after this hard_start_xmit() will
8256 * not be called on that interface
8257 */
8258 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8259 netif_tx_disable(pAdapter->dev);
8260
8261 /* Mark the interface status as "down" for outside world */
8262 netif_carrier_off(pAdapter->dev);
8263
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308264 /* DeInit the adapter. This ensures that all data packets
8265 * are freed.
8266 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308267#ifdef FEATURE_WLAN_TDLS
8268 mutex_lock(&pHddCtx->tdls_lock);
8269#endif
c_hpothu002231a2015-02-05 14:58:51 +05308270 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308271#ifdef FEATURE_WLAN_TDLS
8272 mutex_unlock(&pHddCtx->tdls_lock);
8273#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308274
c_hpothu5ab05e92014-06-13 17:34:05 +05308275 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8276 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8277 {
8278 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8279 hdd_UnregisterWext(pAdapter->dev);
8280 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308281
Jeff Johnson295189b2012-06-20 16:38:30 -07008282 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308283 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8284 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008285 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308286 // Cancel any outstanding scan requests. We are about to close all
8287 // of our adapters, but an adapter structure is what SME passes back
8288 // to our callback function. Hence if there are any outstanding scan
8289 // requests then there is a race condition between when the adapter
8290 // is closed and when the callback is invoked.We try to resolve that
8291 // race condition here by canceling any outstanding scans before we
8292 // close the adapters.
8293 // Note that the scans may be cancelled in an asynchronous manner,
8294 // so ideally there needs to be some kind of synchronization. Rather
8295 // than introduce a new synchronization here, we will utilize the
8296 // fact that we are about to Request Full Power, and since that is
8297 // synchronized, the expectation is that by the time Request Full
8298 // Power has completed all scans will be cancelled.
8299 if (pHddCtx->scan_info.mScanPending)
8300 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308301 if(NULL != pAdapter)
8302 {
8303 hddLog(VOS_TRACE_LEVEL_INFO,
8304 FL("abort scan mode: %d sessionId: %d"),
8305 pAdapter->device_mode,
8306 pAdapter->sessionId);
8307 }
8308 hdd_abort_mac_scan(pHddCtx,
8309 pHddCtx->scan_info.sessionId,
8310 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308311 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008312 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308313 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008314 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308315 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308316 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8317 {
8318 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8320 "%s: in middle of FTM START", __func__);
8321 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8322 msecs_to_jiffies(20000));
8323 if(!lrc)
8324 {
8325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8326 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8327 }
8328 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008329 wlan_hdd_ftm_close(pHddCtx);
8330 goto free_hdd_ctx;
8331 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308332
Jeff Johnson295189b2012-06-20 16:38:30 -07008333 /* DeRegister with platform driver as client for Suspend/Resume */
8334 vosStatus = hddDeregisterPmOps(pHddCtx);
8335 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8336 {
8337 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8338 VOS_ASSERT(0);
8339 }
8340
8341 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8342 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8343 {
8344 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8345 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008346
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008347 //Stop the traffic monitor timer
8348 if ( VOS_TIMER_STATE_RUNNING ==
8349 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8350 {
8351 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8352 }
8353
8354 // Destroy the traffic monitor timer
8355 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8356 &pHddCtx->tx_rx_trafficTmr)))
8357 {
8358 hddLog(VOS_TRACE_LEVEL_ERROR,
8359 "%s: Cannot deallocate Traffic monitor timer", __func__);
8360 }
8361
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 //Disable IMPS/BMPS as we do not want the device to enter any power
8363 //save mode during shutdown
8364 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8365 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8366 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8367
8368 //Ensure that device is in full power as we will touch H/W during vos_Stop
8369 init_completion(&powerContext.completion);
8370 powerContext.magic = POWER_CONTEXT_MAGIC;
8371
8372 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8373 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8374
8375 if (eHAL_STATUS_SUCCESS != halStatus)
8376 {
8377 if (eHAL_STATUS_PMC_PENDING == halStatus)
8378 {
8379 /* request was sent -- wait for the response */
8380 lrc = wait_for_completion_interruptible_timeout(
8381 &powerContext.completion,
8382 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008383 if (lrc <= 0)
8384 {
8385 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008386 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 }
8388 }
8389 else
8390 {
8391 hddLog(VOS_TRACE_LEVEL_ERROR,
8392 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008393 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008394 /* continue -- need to clean up as much as possible */
8395 }
8396 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +05308397 if ((eHAL_STATUS_SUCCESS == halStatus) ||
8398 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
8399 {
8400 /* This will issue a dump command which will clean up
8401 BTQM queues and unblock MC thread */
8402 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
8403 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008404
Jeff Johnson72a40512013-12-19 10:14:15 -08008405 /* either we never sent a request, we sent a request and received a
8406 response or we sent a request and timed out. if we never sent a
8407 request or if we sent a request and got a response, we want to
8408 clear the magic out of paranoia. if we timed out there is a
8409 race condition such that the callback function could be
8410 executing at the same time we are. of primary concern is if the
8411 callback function had already verified the "magic" but had not
8412 yet set the completion variable when a timeout occurred. we
8413 serialize these activities by invalidating the magic while
8414 holding a shared spinlock which will cause us to block if the
8415 callback is currently executing */
8416 spin_lock(&hdd_context_lock);
8417 powerContext.magic = 0;
8418 spin_unlock(&hdd_context_lock);
8419
Yue Ma0d4891e2013-08-06 17:01:45 -07008420 hdd_debugfs_exit(pHddCtx);
8421
Ratheesh S P35ed8b12015-04-27 14:01:07 +05308422#ifdef WLAN_NS_OFFLOAD
8423 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8424 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8425#endif
8426 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8427 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8428
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 // Unregister the Net Device Notifier
8430 unregister_netdevice_notifier(&hdd_netdev_notifier);
8431
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 hdd_stop_all_adapters( pHddCtx );
8433
Jeff Johnson295189b2012-06-20 16:38:30 -07008434#ifdef WLAN_BTAMP_FEATURE
8435 vosStatus = WLANBAP_Stop(pVosContext);
8436 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8437 {
8438 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8439 "%s: Failed to stop BAP",__func__);
8440 }
8441#endif //WLAN_BTAMP_FEATURE
8442
8443 //Stop all the modules
8444 vosStatus = vos_stop( pVosContext );
8445 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8446 {
8447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8448 "%s: Failed to stop VOSS",__func__);
8449 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8450 }
8451
Jeff Johnson295189b2012-06-20 16:38:30 -07008452 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008454
8455 //Close the scheduler before calling vos_close to make sure no thread is
8456 // scheduled after the each module close is called i.e after all the data
8457 // structures are freed.
8458 vosStatus = vos_sched_close( pVosContext );
8459 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8460 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8461 "%s: Failed to close VOSS Scheduler",__func__);
8462 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8463 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008464#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008465#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8466 /* Destroy the wake lock */
8467 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8468#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008469 /* Destroy the wake lock */
8470 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008471#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008472
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308473#ifdef CONFIG_ENABLE_LINUX_REG
8474 vosStatus = vos_nv_close();
8475 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8476 {
8477 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8478 "%s: Failed to close NV", __func__);
8479 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8480 }
8481#endif
8482
Jeff Johnson295189b2012-06-20 16:38:30 -07008483 //Close VOSS
8484 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8485 vos_close(pVosContext);
8486
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 //Close Watchdog
8488 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8489 vos_watchdog_close(pVosContext);
8490
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308491 //Clean up HDD Nlink Service
8492 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308493
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308494#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308495 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308496 {
8497 wlan_logging_sock_deactivate_svc();
8498 }
8499#endif
8500
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308501#ifdef WLAN_KD_READY_NOTIFIER
8502 nl_srv_exit(pHddCtx->ptt_pid);
8503#else
8504 nl_srv_exit();
8505#endif /* WLAN_KD_READY_NOTIFIER */
8506
8507
Jeff Johnson295189b2012-06-20 16:38:30 -07008508 hdd_close_all_adapters( pHddCtx );
8509
Jeff Johnson295189b2012-06-20 16:38:30 -07008510 /* free the power on lock from platform driver */
8511 if (free_riva_power_on_lock("wlan"))
8512 {
8513 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8514 __func__);
8515 }
8516
Jeff Johnson88ba7742013-02-27 14:36:02 -08008517free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308518
8519 //Free up dynamically allocated members inside HDD Adapter
8520 if (pHddCtx->cfg_ini)
8521 {
8522 kfree(pHddCtx->cfg_ini);
8523 pHddCtx->cfg_ini= NULL;
8524 }
8525
Leo Changf04ddad2013-09-18 13:46:38 -07008526 /* FTM mode, WIPHY did not registered
8527 If un-register here, system crash will happen */
8528 if (VOS_FTM_MODE != hdd_get_conparam())
8529 {
8530 wiphy_unregister(wiphy) ;
8531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008533 if (hdd_is_ssr_required())
8534 {
8535 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008536 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008537 msleep(5000);
8538 }
8539 hdd_set_ssr_required (VOS_FALSE);
8540}
8541
8542
8543/**---------------------------------------------------------------------------
8544
8545 \brief hdd_update_config_from_nv() - Function to update the contents of
8546 the running configuration with parameters taken from NV storage
8547
8548 \param - pHddCtx - Pointer to the HDD global context
8549
8550 \return - VOS_STATUS_SUCCESS if successful
8551
8552 --------------------------------------------------------------------------*/
8553static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8554{
Jeff Johnson295189b2012-06-20 16:38:30 -07008555 v_BOOL_t itemIsValid = VOS_FALSE;
8556 VOS_STATUS status;
8557 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8558 v_U8_t macLoop;
8559
8560 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8561 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8562 if(status != VOS_STATUS_SUCCESS)
8563 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008564 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 return VOS_STATUS_E_FAILURE;
8566 }
8567
8568 if (itemIsValid == VOS_TRUE)
8569 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008570 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008571 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8572 VOS_MAX_CONCURRENCY_PERSONA);
8573 if(status != VOS_STATUS_SUCCESS)
8574 {
8575 /* Get MAC from NV fail, not update CFG info
8576 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008577 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008578 return VOS_STATUS_E_FAILURE;
8579 }
8580
8581 /* If first MAC is not valid, treat all others are not valid
8582 * Then all MACs will be got from ini file */
8583 if(vos_is_macaddr_zero(&macFromNV[0]))
8584 {
8585 /* MAC address in NV file is not configured yet */
8586 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8587 return VOS_STATUS_E_INVAL;
8588 }
8589
8590 /* Get MAC address from NV, update CFG info */
8591 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8592 {
8593 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8594 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308595 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008596 /* This MAC is not valid, skip it
8597 * This MAC will be got from ini file */
8598 }
8599 else
8600 {
8601 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8602 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8603 VOS_MAC_ADDR_SIZE);
8604 }
8605 }
8606 }
8607 else
8608 {
8609 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8610 return VOS_STATUS_E_FAILURE;
8611 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008612
Jeff Johnson295189b2012-06-20 16:38:30 -07008613
8614 return VOS_STATUS_SUCCESS;
8615}
8616
8617/**---------------------------------------------------------------------------
8618
8619 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8620
8621 \param - pAdapter - Pointer to the HDD
8622
8623 \return - None
8624
8625 --------------------------------------------------------------------------*/
8626VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8627{
8628 eHalStatus halStatus;
8629 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308630 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008631
Jeff Johnson295189b2012-06-20 16:38:30 -07008632
8633 // Send ready indication to the HDD. This will kick off the MAC
8634 // into a 'running' state and should kick off an initial scan.
8635 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8636 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8637 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308638 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 "code %08d [x%08x]",__func__, halStatus, halStatus );
8640 return VOS_STATUS_E_FAILURE;
8641 }
8642
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308643 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008644 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8645 // And RIVA will crash
8646 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8647 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308648 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8649 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8650
8651
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 return VOS_STATUS_SUCCESS;
8653}
8654
Jeff Johnson295189b2012-06-20 16:38:30 -07008655/* wake lock APIs for HDD */
8656void hdd_prevent_suspend(void)
8657{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008658#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008659 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008660#else
8661 wcnss_prevent_suspend();
8662#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008663}
8664
8665void hdd_allow_suspend(void)
8666{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008667#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008668 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008669#else
8670 wcnss_allow_suspend();
8671#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008672}
8673
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308674void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008675{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008676#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008677 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008678#else
8679 /* Do nothing as there is no API in wcnss for timeout*/
8680#endif
8681}
8682
Jeff Johnson295189b2012-06-20 16:38:30 -07008683/**---------------------------------------------------------------------------
8684
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008685 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8686 information between Host and Riva
8687
8688 This function gets reported version of FW
8689 It also finds the version of Riva headers used to compile the host
8690 It compares the above two and prints a warning if they are different
8691 It gets the SW and HW version string
8692 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8693 indicating the features they support through a bitmap
8694
8695 \param - pHddCtx - Pointer to HDD context
8696
8697 \return - void
8698
8699 --------------------------------------------------------------------------*/
8700
8701void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8702{
8703
8704 tSirVersionType versionCompiled;
8705 tSirVersionType versionReported;
8706 tSirVersionString versionString;
8707 tANI_U8 fwFeatCapsMsgSupported = 0;
8708 VOS_STATUS vstatus;
8709
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008710 memset(&versionCompiled, 0, sizeof(versionCompiled));
8711 memset(&versionReported, 0, sizeof(versionReported));
8712
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008713 /* retrieve and display WCNSS version information */
8714 do {
8715
8716 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8717 &versionCompiled);
8718 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8719 {
8720 hddLog(VOS_TRACE_LEVEL_FATAL,
8721 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008722 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008723 break;
8724 }
8725
8726 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8727 &versionReported);
8728 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8729 {
8730 hddLog(VOS_TRACE_LEVEL_FATAL,
8731 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008732 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008733 break;
8734 }
8735
8736 if ((versionCompiled.major != versionReported.major) ||
8737 (versionCompiled.minor != versionReported.minor) ||
8738 (versionCompiled.version != versionReported.version) ||
8739 (versionCompiled.revision != versionReported.revision))
8740 {
8741 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8742 "Host expected %u.%u.%u.%u\n",
8743 WLAN_MODULE_NAME,
8744 (int)versionReported.major,
8745 (int)versionReported.minor,
8746 (int)versionReported.version,
8747 (int)versionReported.revision,
8748 (int)versionCompiled.major,
8749 (int)versionCompiled.minor,
8750 (int)versionCompiled.version,
8751 (int)versionCompiled.revision);
8752 }
8753 else
8754 {
8755 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8756 WLAN_MODULE_NAME,
8757 (int)versionReported.major,
8758 (int)versionReported.minor,
8759 (int)versionReported.version,
8760 (int)versionReported.revision);
8761 }
8762
8763 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8764 versionString,
8765 sizeof(versionString));
8766 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8767 {
8768 hddLog(VOS_TRACE_LEVEL_FATAL,
8769 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008770 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008771 break;
8772 }
8773
8774 pr_info("%s: WCNSS software version %s\n",
8775 WLAN_MODULE_NAME, versionString);
8776
8777 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8778 versionString,
8779 sizeof(versionString));
8780 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8781 {
8782 hddLog(VOS_TRACE_LEVEL_FATAL,
8783 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008784 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008785 break;
8786 }
8787
8788 pr_info("%s: WCNSS hardware version %s\n",
8789 WLAN_MODULE_NAME, versionString);
8790
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008791 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8792 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008793 send the message only if it the riva is 1.1
8794 minor numbers for different riva branches:
8795 0 -> (1.0)Mainline Build
8796 1 -> (1.1)Mainline Build
8797 2->(1.04) Stability Build
8798 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008799 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008800 ((versionReported.minor>=1) && (versionReported.version>=1)))
8801 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8802 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008803
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008804 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008805 {
8806#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8807 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8808 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8809#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008810 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8811 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8812 {
8813 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8814 }
8815
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008816 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008817 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008818
8819 } while (0);
8820
8821}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308822void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8823{
8824 struct sk_buff *skb;
8825 struct nlmsghdr *nlh;
8826 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05308827 int flags = GFP_KERNEL;
Neelansh Mittaledafed22014-09-04 18:54:39 +05308828
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +05308829 if (in_interrupt() || irqs_disabled() || in_atomic())
8830 flags = GFP_ATOMIC;
8831
8832 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +05308833
8834 if(skb == NULL) {
8835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8836 "%s: alloc_skb failed", __func__);
8837 return;
8838 }
8839
8840 nlh = (struct nlmsghdr *)skb->data;
8841 nlh->nlmsg_pid = 0; /* from kernel */
8842 nlh->nlmsg_flags = 0;
8843 nlh->nlmsg_seq = 0;
8844 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8845
8846 ani_hdr = NLMSG_DATA(nlh);
8847 ani_hdr->type = type;
8848
8849 switch(type) {
8850 case WLAN_SVC_SAP_RESTART_IND:
8851 ani_hdr->length = 0;
8852 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8853 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8854 break;
8855 default:
8856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8857 "Attempt to send unknown nlink message %d", type);
8858 kfree_skb(skb);
8859 return;
8860 }
8861
8862 nl_srv_bcast(skb);
8863
8864 return;
8865}
8866
8867
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008868
8869/**---------------------------------------------------------------------------
8870
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308871 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8872
8873 \param - pHddCtx - Pointer to the hdd context
8874
8875 \return - true if hardware supports 5GHz
8876
8877 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308878boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308879{
8880 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8881 * then hardware support 5Ghz.
8882 */
8883 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8884 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308886 return true;
8887 }
8888 else
8889 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308890 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308891 __func__);
8892 return false;
8893 }
8894}
8895
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308896/**---------------------------------------------------------------------------
8897
8898 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8899 generate function
8900
8901 This is generate the random mac address for WLAN interface
8902
8903 \param - pHddCtx - Pointer to HDD context
8904 idx - Start interface index to get auto
8905 generated mac addr.
8906 mac_addr - Mac address
8907
8908 \return - 0 for success, < 0 for failure
8909
8910 --------------------------------------------------------------------------*/
8911
8912static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8913 int idx, v_MACADDR_t mac_addr)
8914{
8915 int i;
8916 unsigned int serialno;
8917 serialno = wcnss_get_serial_number();
8918
8919 if (0 != serialno)
8920 {
8921 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8922 bytes of the serial number that can be used to generate
8923 the other 3 bytes of the MAC address. Mask off all but
8924 the lower 3 bytes (this will also make sure we don't
8925 overflow in the next step) */
8926 serialno &= 0x00FFFFFF;
8927
8928 /* we need a unique address for each session */
8929 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8930
8931 /* autogen other Mac addresses */
8932 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8933 {
8934 /* start with the entire default address */
8935 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8936 /* then replace the lower 3 bytes */
8937 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8938 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8939 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8940
8941 serialno++;
8942 hddLog(VOS_TRACE_LEVEL_ERROR,
8943 "%s: Derived Mac Addr: "
8944 MAC_ADDRESS_STR, __func__,
8945 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8946 }
8947
8948 }
8949 else
8950 {
8951 hddLog(LOGE, FL("Failed to Get Serial NO"));
8952 return -1;
8953 }
8954 return 0;
8955}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308956
8957/**---------------------------------------------------------------------------
8958
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308959 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8960 completed to flush out the scan results
8961
8962 11d scan is done during driver load and is a passive scan on all
8963 channels supported by the device, 11d scans may find some APs on
8964 frequencies which are forbidden to be used in the regulatory domain
8965 the device is operating in. If these APs are notified to the supplicant
8966 it may try to connect to these APs, thus flush out all the scan results
8967 which are present in SME after 11d scan is done.
8968
8969 \return - eHalStatus
8970
8971 --------------------------------------------------------------------------*/
8972static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8973 tANI_U32 scanId, eCsrScanStatus status)
8974{
8975 ENTER();
8976
8977 sme_ScanFlushResult(halHandle, 0);
8978
8979 EXIT();
8980
8981 return eHAL_STATUS_SUCCESS;
8982}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05308983/**---------------------------------------------------------------------------
8984
8985 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
8986 logging is completed successfully.
8987
8988 \return - None
8989
8990 --------------------------------------------------------------------------*/
8991void hdd_init_frame_logging_done(void *mgmtlogInitCbContext, VOS_STATUS status)
8992{
8993 hdd_context_t* pHddCtx = (hdd_context_t*)mgmtlogInitCbContext;
8994
8995 if (NULL == pHddCtx)
8996 {
8997 hddLog(VOS_TRACE_LEVEL_ERROR,
8998 "%s: HDD context is NULL",__func__);
8999 return;
9000 }
9001
9002 if (VOS_STATUS_SUCCESS == status)
9003 {
9004 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
9005 pHddCtx->mgmt_frame_logging = TRUE;
9006 }
9007 else
9008 {
9009 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
9010 pHddCtx->mgmt_frame_logging = FALSE;
9011 }
9012
9013 return;
9014}
9015/**---------------------------------------------------------------------------
9016
9017 \brief hdd_init_frame_logging - function to initialize frame logging.
9018 Currently only Mgmt Frames are logged in both TX
9019 and Rx direction and are sent to userspace
9020 application using logger thread when queried.
9021
9022 \return - None
9023
9024 --------------------------------------------------------------------------*/
9025void hdd_init_frame_logging(hdd_context_t* pHddCtx, v_BOOL_t enable)
9026{
9027 eHalStatus halStatus = eHAL_STATUS_FAILURE;
9028 tpSirMgmtLoggingInitParam wlanMgmtLoggingInitParam;
9029
9030 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING))
9031 {
9032 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
9033 return;
9034 }
9035
9036 wlanMgmtLoggingInitParam = vos_mem_malloc(sizeof(tSirMgmtLoggingInitParam));
9037 if(NULL == wlanMgmtLoggingInitParam)
9038 {
9039 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_mem_alloc failed ", __func__);
9040 return;
9041 }
9042
9043 vos_mem_set(wlanMgmtLoggingInitParam, sizeof(tSirMgmtLoggingInitParam), 0);
9044
9045 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring Mgmt Frame Logging %d",
9046 __func__, enable);
9047
9048 if (enable)
9049 {
9050 wlanMgmtLoggingInitParam->enableFlag |= WLAN_FRAME_LOG_EN;
9051 }
9052
9053 if (pHddCtx->cfg_ini->enableBMUHWtracing)
9054 {
9055 wlanMgmtLoggingInitParam->enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
9056 }
9057
9058 wlanMgmtLoggingInitParam->frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
9059 wlanMgmtLoggingInitParam->frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
9060 wlanMgmtLoggingInitParam->bufferMode =
9061 WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
9062
9063 wlanMgmtLoggingInitParam->enableFlag &= ~WLAN_QXDM_LOG_EN;
9064 wlanMgmtLoggingInitParam->enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
9065
9066 wlanMgmtLoggingInitParam->mgmtlogInitCallback = hdd_init_frame_logging_done;
9067 wlanMgmtLoggingInitParam->mgmtlogInitCbContext= pHddCtx;
9068
9069 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal,
9070 wlanMgmtLoggingInitParam);
9071
9072 if (eHAL_STATUS_SUCCESS != halStatus)
9073 {
9074 vos_mem_free(wlanMgmtLoggingInitParam);
9075 }
9076
9077 return;
9078}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309079
9080/**---------------------------------------------------------------------------
9081
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 \brief hdd_wlan_startup() - HDD init function
9083
9084 This is the driver startup code executed once a WLAN device has been detected
9085
9086 \param - dev - Pointer to the underlying device
9087
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009088 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07009089
9090 --------------------------------------------------------------------------*/
9091
9092int hdd_wlan_startup(struct device *dev )
9093{
9094 VOS_STATUS status;
9095 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07009096 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009097 hdd_context_t *pHddCtx = NULL;
9098 v_CONTEXT_t pVosContext= NULL;
9099#ifdef WLAN_BTAMP_FEATURE
9100 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
9101 WLANBAP_ConfigType btAmpConfig;
9102 hdd_config_t *pConfig;
9103#endif
9104 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009105 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309106 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07009107
9108 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 /*
9110 * cfg80211: wiphy allocation
9111 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309112 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009113
9114 if(wiphy == NULL)
9115 {
9116 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009117 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009119 pHddCtx = wiphy_priv(wiphy);
9120
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 //Initialize the adapter context to zeros.
9122 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
9123
Jeff Johnson295189b2012-06-20 16:38:30 -07009124 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07009125 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05309126 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009127
9128 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9129
9130 /*Get vos context here bcoz vos_open requires it*/
9131 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9132
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08009133 if(pVosContext == NULL)
9134 {
9135 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
9136 goto err_free_hdd_context;
9137 }
9138
Jeff Johnson295189b2012-06-20 16:38:30 -07009139 //Save the Global VOSS context in adapter context for future.
9140 pHddCtx->pvosContext = pVosContext;
9141
9142 //Save the adapter context in global context for future.
9143 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
9144
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 pHddCtx->parent_dev = dev;
9146
9147 init_completion(&pHddCtx->full_pwr_comp_var);
9148 init_completion(&pHddCtx->standby_comp_var);
9149 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009150 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08009151 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05309152 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309153 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07009154
9155#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07009156 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07009157#else
9158 init_completion(&pHddCtx->driver_crda_req);
9159#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009160
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309161 spin_lock_init(&pHddCtx->schedScan_lock);
9162
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9164
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309165#ifdef FEATURE_WLAN_TDLS
9166 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9167 * invoked by other instances also) to protect the concurrent
9168 * access for the Adapters by TDLS module.
9169 */
9170 mutex_init(&pHddCtx->tdls_lock);
9171#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309172 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309173 mutex_init(&pHddCtx->wmmLock);
9174
Agarwal Ashish1f422872014-07-22 00:11:55 +05309175 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309176
Agarwal Ashish1f422872014-07-22 00:11:55 +05309177 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009178 // Load all config first as TL config is needed during vos_open
9179 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9180 if(pHddCtx->cfg_ini == NULL)
9181 {
9182 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9183 goto err_free_hdd_context;
9184 }
9185
9186 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9187
9188 // Read and parse the qcom_cfg.ini file
9189 status = hdd_parse_config_ini( pHddCtx );
9190 if ( VOS_STATUS_SUCCESS != status )
9191 {
9192 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9193 __func__, WLAN_INI_FILE);
9194 goto err_config;
9195 }
Arif Hussaind5218912013-12-05 01:10:55 -08009196#ifdef MEMORY_DEBUG
9197 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9198 vos_mem_init();
9199
9200 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9201 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9202#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009203
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309204 /* INI has been read, initialise the configuredMcastBcastFilter with
9205 * INI value as this will serve as the default value
9206 */
9207 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9208 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9209 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309210
9211 if (false == hdd_is_5g_supported(pHddCtx))
9212 {
9213 //5Ghz is not supported.
9214 if (1 != pHddCtx->cfg_ini->nBandCapability)
9215 {
9216 hddLog(VOS_TRACE_LEVEL_INFO,
9217 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9218 pHddCtx->cfg_ini->nBandCapability = 1;
9219 }
9220 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309221
9222 /* If SNR Monitoring is enabled, FW has to parse all beacons
9223 * for calcaluting and storing the average SNR, so set Nth beacon
9224 * filter to 1 to enable FW to parse all the beaocons
9225 */
9226 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9227 {
9228 /* The log level is deliberately set to WARN as overriding
9229 * nthBeaconFilter to 1 will increase power cosumption and this
9230 * might just prove helpful to detect the power issue.
9231 */
9232 hddLog(VOS_TRACE_LEVEL_WARN,
9233 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9234 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9235 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309237 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009239 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009241 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9242 {
9243 hddLog(VOS_TRACE_LEVEL_FATAL,
9244 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9245 goto err_config;
9246 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009247 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009248
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009249 // Update VOS trace levels based upon the cfg.ini
9250 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9251 pHddCtx->cfg_ini->vosTraceEnableBAP);
9252 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9253 pHddCtx->cfg_ini->vosTraceEnableTL);
9254 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9255 pHddCtx->cfg_ini->vosTraceEnableWDI);
9256 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9257 pHddCtx->cfg_ini->vosTraceEnableHDD);
9258 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9259 pHddCtx->cfg_ini->vosTraceEnableSME);
9260 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9261 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309262 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9263 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009264 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9265 pHddCtx->cfg_ini->vosTraceEnableWDA);
9266 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9267 pHddCtx->cfg_ini->vosTraceEnableSYS);
9268 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9269 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009270 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9271 pHddCtx->cfg_ini->vosTraceEnableSAP);
9272 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9273 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009274
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 // Update WDI trace levels based upon the cfg.ini
9276 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9277 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9278 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9279 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9280 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9281 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9282 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9283 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009284
Jeff Johnson88ba7742013-02-27 14:36:02 -08009285 if (VOS_FTM_MODE == hdd_get_conparam())
9286 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9288 {
9289 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9290 goto err_free_hdd_context;
9291 }
9292 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309293 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309294 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009296 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009297
Jeff Johnson88ba7742013-02-27 14:36:02 -08009298 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9300 {
9301 status = vos_watchdog_open(pVosContext,
9302 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9303
9304 if(!VOS_IS_STATUS_SUCCESS( status ))
9305 {
9306 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309307 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 }
9309 }
9310
9311 pHddCtx->isLogpInProgress = FALSE;
9312 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9313
Amar Singhala49cbc52013-10-08 18:37:44 -07009314#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009315 /* initialize the NV module. This is required so that
9316 we can initialize the channel information in wiphy
9317 from the NV.bin data. The channel information in
9318 wiphy needs to be initialized before wiphy registration */
9319
9320 status = vos_nv_open();
9321 if (!VOS_IS_STATUS_SUCCESS(status))
9322 {
9323 /* NV module cannot be initialized */
9324 hddLog( VOS_TRACE_LEVEL_FATAL,
9325 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309326 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009327 }
9328
9329 status = vos_init_wiphy_from_nv_bin();
9330 if (!VOS_IS_STATUS_SUCCESS(status))
9331 {
9332 /* NV module cannot be initialized */
9333 hddLog( VOS_TRACE_LEVEL_FATAL,
9334 "%s: vos_init_wiphy failed", __func__);
9335 goto err_vos_nv_close;
9336 }
9337
Amar Singhala49cbc52013-10-08 18:37:44 -07009338#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309339 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309340 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 if ( !VOS_IS_STATUS_SUCCESS( status ))
9342 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009343 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309344 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 }
9346
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9348
9349 if ( NULL == pHddCtx->hHal )
9350 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009351 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 goto err_vosclose;
9353 }
9354
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009355 status = vos_preStart( pHddCtx->pvosContext );
9356 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9357 {
9358 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309359 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009360 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009361
Arif Hussaineaf68602013-12-30 23:10:44 -08009362 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9363 {
9364 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9365 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9366 __func__, enable_dfs_chan_scan);
9367 }
9368 if (0 == enable_11d || 1 == enable_11d)
9369 {
9370 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9371 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9372 __func__, enable_11d);
9373 }
9374
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009375 /* Note that the vos_preStart() sequence triggers the cfg download.
9376 The cfg download must occur before we update the SME config
9377 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009378 status = hdd_set_sme_config( pHddCtx );
9379
9380 if ( VOS_STATUS_SUCCESS != status )
9381 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009382 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309383 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009384 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009385
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 /* In the integrated architecture we update the configuration from
9387 the INI file and from NV before vOSS has been started so that
9388 the final contents are available to send down to the cCPU */
9389
9390 // Apply the cfg.ini to cfg.dat
9391 if (FALSE == hdd_update_config_dat(pHddCtx))
9392 {
9393 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309394 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 }
9396
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309397 // Get mac addr from platform driver
9398 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9399
9400 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309402 /* Store the mac addr for first interface */
9403 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9404
9405 hddLog(VOS_TRACE_LEVEL_ERROR,
9406 "%s: WLAN Mac Addr: "
9407 MAC_ADDRESS_STR, __func__,
9408 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9409
9410 /* Here, passing Arg2 as 1 because we do not want to change the
9411 last 3 bytes (means non OUI bytes) of first interface mac
9412 addr.
9413 */
9414 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9415 {
9416 hddLog(VOS_TRACE_LEVEL_ERROR,
9417 "%s: Failed to generate wlan interface mac addr "
9418 "using MAC from ini file ", __func__);
9419 }
9420 }
9421 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9422 {
9423 // Apply the NV to cfg.dat
9424 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009425#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9426 /* There was not a valid set of MAC Addresses in NV. See if the
9427 default addresses were modified by the cfg.ini settings. If so,
9428 we'll use them, but if not, we'll autogenerate a set of MAC
9429 addresses based upon the device serial number */
9430
9431 static const v_MACADDR_t default_address =
9432 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009433
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309434 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9435 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 {
9437 /* cfg.ini has the default address, invoke autogen logic */
9438
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309439 /* Here, passing Arg2 as 0 because we want to change the
9440 last 3 bytes (means non OUI bytes) of all the interfaces
9441 mac addr.
9442 */
9443 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9444 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009445 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309446 hddLog(VOS_TRACE_LEVEL_ERROR,
9447 "%s: Failed to generate wlan interface mac addr "
9448 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9449 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 }
9452 else
9453#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9454 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009455 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009456 "%s: Invalid MAC address in NV, using MAC from ini file "
9457 MAC_ADDRESS_STR, __func__,
9458 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9459 }
9460 }
9461 {
9462 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309463
9464 /* Set the MAC Address Currently this is used by HAL to
9465 * add self sta. Remove this once self sta is added as
9466 * part of session open.
9467 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9469 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9470 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309471
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 if (!HAL_STATUS_SUCCESS( halStatus ))
9473 {
9474 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9475 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309476 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009477 }
9478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009479
9480 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9481 Note: Firmware image will be read and downloaded inside vos_start API */
9482 status = vos_start( pHddCtx->pvosContext );
9483 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9484 {
9485 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309486 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009487 }
9488
Leo Chang6cec3e22014-01-21 15:33:49 -08009489#ifdef FEATURE_WLAN_CH_AVOID
9490 /* Plug in avoid channel notification callback
9491 * This should happen before ADD_SELF_STA
9492 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309493
9494 /* check the Channel Avoidance is enabled */
9495 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9496 {
9497 sme_AddChAvoidCallback(pHddCtx->hHal,
9498 hdd_hostapd_ch_avoid_cb);
9499 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009500#endif /* FEATURE_WLAN_CH_AVOID */
9501
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009502 /* Exchange capability info between Host and FW and also get versioning info from FW */
9503 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009504
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309505#ifdef CONFIG_ENABLE_LINUX_REG
9506 status = wlan_hdd_init_channels(pHddCtx);
9507 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9508 {
9509 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9510 __func__);
9511 goto err_vosstop;
9512 }
9513#endif
9514
Jeff Johnson295189b2012-06-20 16:38:30 -07009515 status = hdd_post_voss_start_config( pHddCtx );
9516 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9517 {
9518 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9519 __func__);
9520 goto err_vosstop;
9521 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009522
9523#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309524 wlan_hdd_cfg80211_update_reg_info( wiphy );
9525
9526 /* 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 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009532#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009533
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309534#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309535 /* registration of wiphy dev with cfg80211 */
9536 if (0 > wlan_hdd_cfg80211_register(wiphy))
9537 {
9538 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9539 goto err_vosstop;
9540 }
9541
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309542 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309543 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9544 {
9545 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9546 __func__);
9547 goto err_unregister_wiphy;
9548 }
9549#endif
9550
c_hpothu4a298be2014-12-22 21:12:51 +05309551 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9552
Jeff Johnson295189b2012-06-20 16:38:30 -07009553 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9554 {
9555 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9556 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9557 }
9558 else
9559 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009560 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9561 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9562 if (pAdapter != NULL)
9563 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309564 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309566 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9567 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9568 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009569
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309570 /* Generate the P2P Device Address. This consists of the device's
9571 * primary MAC address with the locally administered bit set.
9572 */
9573 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009574 }
9575 else
9576 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309577 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9578 if (p2p_dev_addr != NULL)
9579 {
9580 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9581 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9582 }
9583 else
9584 {
9585 hddLog(VOS_TRACE_LEVEL_FATAL,
9586 "%s: Failed to allocate mac_address for p2p_device",
9587 __func__);
9588 goto err_close_adapter;
9589 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009591
9592 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9593 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9594 if ( NULL == pP2pAdapter )
9595 {
9596 hddLog(VOS_TRACE_LEVEL_FATAL,
9597 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009598 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009599 goto err_close_adapter;
9600 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009601 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009602 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009603
9604 if( pAdapter == NULL )
9605 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9607 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009609
Arif Hussain66559122013-11-21 10:11:40 -08009610 if (country_code)
9611 {
9612 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009613 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009614 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9615#ifndef CONFIG_ENABLE_LINUX_REG
9616 hdd_checkandupdate_phymode(pAdapter, country_code);
9617#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009618 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9619 (void *)(tSmeChangeCountryCallback)
9620 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009621 country_code,
9622 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309623 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009624 if (eHAL_STATUS_SUCCESS == ret)
9625 {
Arif Hussaincb607082013-12-20 11:57:42 -08009626 ret = wait_for_completion_interruptible_timeout(
9627 &pAdapter->change_country_code,
9628 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9629
9630 if (0 >= ret)
9631 {
9632 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9633 "%s: SME while setting country code timed out", __func__);
9634 }
Arif Hussain66559122013-11-21 10:11:40 -08009635 }
9636 else
9637 {
Arif Hussaincb607082013-12-20 11:57:42 -08009638 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9639 "%s: SME Change Country code from module param fail ret=%d",
9640 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009641 }
9642 }
9643
Jeff Johnson295189b2012-06-20 16:38:30 -07009644#ifdef WLAN_BTAMP_FEATURE
9645 vStatus = WLANBAP_Open(pVosContext);
9646 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9647 {
9648 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9649 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009650 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 }
9652
9653 vStatus = BSL_Init(pVosContext);
9654 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9655 {
9656 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9657 "%s: Failed to Init BSL",__func__);
9658 goto err_bap_close;
9659 }
9660 vStatus = WLANBAP_Start(pVosContext);
9661 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9662 {
9663 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9664 "%s: Failed to start TL",__func__);
9665 goto err_bap_close;
9666 }
9667
9668 pConfig = pHddCtx->cfg_ini;
9669 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9670 status = WLANBAP_SetConfig(&btAmpConfig);
9671
9672#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009673
Mihir Shete9c238772014-10-15 14:35:16 +05309674 /*
9675 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9676 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9677 * which is greater than 0xf. So the below check is safe to make
9678 * sure that there is no entry for UapsdMask in the ini
9679 */
9680 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9681 {
9682 if(IS_DYNAMIC_WMM_PS_ENABLED)
9683 {
9684 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9685 __func__);
9686 pHddCtx->cfg_ini->UapsdMask =
9687 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9688 }
9689 else
9690 {
9691 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9692 __func__);
9693 pHddCtx->cfg_ini->UapsdMask =
9694 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9695 }
9696 }
9697
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009698#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9699 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9700 {
9701 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9702 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9703 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9704 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9705 }
9706#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009707
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309708 wlan_hdd_tdls_init(pHddCtx);
9709
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309710 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9711
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 /* Register with platform driver as client for Suspend/Resume */
9713 status = hddRegisterPmOps(pHddCtx);
9714 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9715 {
9716 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9717#ifdef WLAN_BTAMP_FEATURE
9718 goto err_bap_stop;
9719#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009720 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009721#endif //WLAN_BTAMP_FEATURE
9722 }
9723
Yue Ma0d4891e2013-08-06 17:01:45 -07009724 /* Open debugfs interface */
9725 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9726 {
9727 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9728 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009729 }
9730
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 /* Register TM level change handler function to the platform */
9732 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9733 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9734 {
9735 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9736 goto err_unregister_pmops;
9737 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009738
9739 /* register for riva power on lock to platform driver */
9740 if (req_riva_power_on_lock("wlan"))
9741 {
9742 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9743 __func__);
9744 goto err_unregister_pmops;
9745 }
9746
Jeff Johnson295189b2012-06-20 16:38:30 -07009747 // register net device notifier for device change notification
9748 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9749
9750 if(ret < 0)
9751 {
9752 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9753 goto err_free_power_on_lock;
9754 }
9755
9756 //Initialize the nlink service
9757 if(nl_srv_init() != 0)
9758 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309759 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009760 goto err_reg_netdev;
9761 }
9762
Leo Chang4ce1cc52013-10-21 18:27:15 -07009763#ifdef WLAN_KD_READY_NOTIFIER
9764 pHddCtx->kd_nl_init = 1;
9765#endif /* WLAN_KD_READY_NOTIFIER */
9766
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 //Initialize the BTC service
9768 if(btc_activate_service(pHddCtx) != 0)
9769 {
9770 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9771 goto err_nl_srv;
9772 }
9773
9774#ifdef PTT_SOCK_SVC_ENABLE
9775 //Initialize the PTT service
9776 if(ptt_sock_activate_svc(pHddCtx) != 0)
9777 {
9778 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9779 goto err_nl_srv;
9780 }
9781#endif
9782
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309783#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9784 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9785 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309786 if(wlan_logging_sock_activate_svc(
9787 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9788 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9789 {
9790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9791 " failed", __func__);
9792 goto err_nl_srv;
9793 }
9794 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9795 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309796 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9797 pHddCtx->cfg_ini->gEnableDebugLog =
9798 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309799 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309800
9801 if (pHddCtx->cfg_ini->enableMgmtLogging &&
9802 pHddCtx->cfg_ini->wlanLoggingEnable)
9803 {
9804 hdd_init_frame_logging(pHddCtx, TRUE);
9805 }
9806 else
9807 {
9808 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Logging disabled in ini"));
9809 }
9810
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309811#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +05309812
9813
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009817 /* Action frame registered in one adapter which will
9818 * applicable to all interfaces
9819 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309820 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009822
9823 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309824 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009825
Jeff Johnson295189b2012-06-20 16:38:30 -07009826
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009827#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009828#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9829 /* Initialize the wake lcok */
9830 wake_lock_init(&pHddCtx->rx_wake_lock,
9831 WAKE_LOCK_SUSPEND,
9832 "qcom_rx_wakelock");
9833#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009834 /* Initialize the wake lcok */
9835 wake_lock_init(&pHddCtx->sap_wake_lock,
9836 WAKE_LOCK_SUSPEND,
9837 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009838#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009839
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009840 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9841 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009842
Katya Nigam5c306ea2014-06-19 15:39:54 +05309843 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009844 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9845 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309846
9847#ifdef FEATURE_WLAN_SCAN_PNO
9848 /*SME must send channel update configuration to RIVA*/
9849 sme_UpdateChannelConfig(pHddCtx->hHal);
9850#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309851 /* Send the update default channel list to the FW*/
9852 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +05309853
9854 /* Fwr capabilities received, Set the Dot11 mode */
9855 sme_SetDefDot11Mode(pHddCtx->hHal);
9856
Abhishek Singha306a442013-11-07 18:39:01 +05309857#ifndef CONFIG_ENABLE_LINUX_REG
9858 /*updating wiphy so that regulatory user hints can be processed*/
9859 if (wiphy)
9860 {
9861 regulatory_hint(wiphy, "00");
9862 }
9863#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009864 // Initialize the restart logic
9865 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309866
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009867 //Register the traffic monitor timer now
9868 if ( pHddCtx->cfg_ini->dynSplitscan)
9869 {
9870 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9871 VOS_TIMER_TYPE_SW,
9872 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9873 (void *)pHddCtx);
9874 }
Srinivas Dasari030bad32015-02-18 23:23:54 +05309875 wlan_hdd_cfg80211_nan_init(pHddCtx);
9876
Dino Mycle6fb96c12014-06-10 11:52:40 +05309877#ifdef WLAN_FEATURE_EXTSCAN
9878 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9879 wlan_hdd_cfg80211_extscan_callback,
9880 pHddCtx);
9881#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309882
9883#ifdef WLAN_NS_OFFLOAD
9884 // Register IPv6 notifier to notify if any change in IP
9885 // So that we can reconfigure the offload parameters
9886 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
9887 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
9888 if (ret)
9889 {
9890 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
9891 }
9892 else
9893 {
9894 hddLog(LOGE, FL("Registered IPv6 notifier"));
9895 }
9896#endif
9897
9898 // Register IPv4 notifier to notify if any change in IP
9899 // So that we can reconfigure the offload parameters
9900 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
9901 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
9902 if (ret)
9903 {
9904 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
9905 }
9906 else
9907 {
9908 hddLog(LOGE, FL("Registered IPv4 notifier"));
9909 }
9910
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 goto success;
9912
9913err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009914#ifdef WLAN_KD_READY_NOTIFIER
9915 nl_srv_exit(pHddCtx->ptt_pid);
9916#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009918#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009919err_reg_netdev:
9920 unregister_netdevice_notifier(&hdd_netdev_notifier);
9921
9922err_free_power_on_lock:
9923 free_riva_power_on_lock("wlan");
9924
9925err_unregister_pmops:
9926 hddDevTmUnregisterNotifyCallback(pHddCtx);
9927 hddDeregisterPmOps(pHddCtx);
9928
Yue Ma0d4891e2013-08-06 17:01:45 -07009929 hdd_debugfs_exit(pHddCtx);
9930
Jeff Johnson295189b2012-06-20 16:38:30 -07009931#ifdef WLAN_BTAMP_FEATURE
9932err_bap_stop:
9933 WLANBAP_Stop(pVosContext);
9934#endif
9935
9936#ifdef WLAN_BTAMP_FEATURE
9937err_bap_close:
9938 WLANBAP_Close(pVosContext);
9939#endif
9940
Jeff Johnson295189b2012-06-20 16:38:30 -07009941err_close_adapter:
9942 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309943#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309944err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309945#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309946 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009947err_vosstop:
9948 vos_stop(pVosContext);
9949
Amar Singhala49cbc52013-10-08 18:37:44 -07009950err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 status = vos_sched_close( pVosContext );
9952 if (!VOS_IS_STATUS_SUCCESS(status)) {
9953 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9954 "%s: Failed to close VOSS Scheduler", __func__);
9955 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9956 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009957 vos_close(pVosContext );
9958
Amar Singhal0a402232013-10-11 20:57:16 -07009959err_vos_nv_close:
9960
c_hpothue6a36282014-03-19 12:27:38 +05309961#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009962 vos_nv_close();
9963
c_hpothu70f8d812014-03-22 22:59:23 +05309964#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009965
9966err_wdclose:
9967 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9968 vos_watchdog_close(pVosContext);
9969
Jeff Johnson295189b2012-06-20 16:38:30 -07009970err_config:
9971 kfree(pHddCtx->cfg_ini);
9972 pHddCtx->cfg_ini= NULL;
9973
9974err_free_hdd_context:
9975 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009976 wiphy_free(wiphy) ;
9977 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 VOS_BUG(1);
9979
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009980 if (hdd_is_ssr_required())
9981 {
9982 /* WDI timeout had happened during load, so SSR is needed here */
9983 subsystem_restart("wcnss");
9984 msleep(5000);
9985 }
9986 hdd_set_ssr_required (VOS_FALSE);
9987
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009988 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009989
9990success:
9991 EXIT();
9992 return 0;
9993}
9994
9995/**---------------------------------------------------------------------------
9996
Jeff Johnson32d95a32012-09-10 13:15:23 -07009997 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009998
Jeff Johnson32d95a32012-09-10 13:15:23 -07009999 This is the driver entry point - called in different timeline depending
10000 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070010001
10002 \param - None
10003
10004 \return - 0 for success, non zero for failure
10005
10006 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070010007static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010008{
10009 VOS_STATUS status;
10010 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 struct device *dev = NULL;
10012 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010013#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10014 int max_retries = 0;
10015#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010016#ifdef HAVE_CBC_DONE
10017 int max_cbc_retries = 0;
10018#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010019
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010020#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10021 wlan_logging_sock_init_svc();
10022#endif
10023
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 ENTER();
10025
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010026#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -070010028#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010029
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010030 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
10032 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
10033
Jeff Johnson295189b2012-06-20 16:38:30 -070010034#ifdef ANI_BUS_TYPE_PCI
10035
10036 dev = wcnss_wlan_get_device();
10037
10038#endif // ANI_BUS_TYPE_PCI
10039
10040#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010041
10042#ifdef HAVE_WCNSS_CAL_DOWNLOAD
10043 /* wait until WCNSS driver downloads NV */
10044 while (!wcnss_device_ready() && 5 >= ++max_retries) {
10045 msleep(1000);
10046 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010047
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010048 if (max_retries >= 5) {
10049 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +053010050#ifdef WLAN_OPEN_SOURCE
10051 wake_lock_destroy(&wlan_wake_lock);
10052#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010053
10054#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10055 wlan_logging_sock_deinit_svc();
10056#endif
10057
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070010058 return -ENODEV;
10059 }
10060#endif
10061
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053010062#ifdef HAVE_CBC_DONE
10063 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
10064 msleep(1000);
10065 }
10066 if (max_cbc_retries >= 10) {
10067 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
10068 }
10069#endif
10070
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 dev = wcnss_wlan_get_device();
10072#endif // ANI_BUS_TYPE_PLATFORM
10073
10074
10075 do {
10076 if (NULL == dev) {
10077 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
10078 ret_status = -1;
10079 break;
10080 }
10081
Jeff Johnson295189b2012-06-20 16:38:30 -070010082#ifdef TIMER_MANAGER
10083 vos_timer_manager_init();
10084#endif
10085
10086 /* Preopen VOSS so that it is ready to start at least SAL */
10087 status = vos_preOpen(&pVosContext);
10088
10089 if (!VOS_IS_STATUS_SUCCESS(status))
10090 {
10091 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
10092 ret_status = -1;
10093 break;
10094 }
10095
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010096#ifndef MODULE
10097 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
10098 */
10099 hdd_set_conparam((v_UINT_t)con_mode);
10100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010101
10102 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010103 if (hdd_wlan_startup(dev))
10104 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080010106 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010107 vos_preClose( &pVosContext );
10108 ret_status = -1;
10109 break;
10110 }
10111
Jeff Johnson295189b2012-06-20 16:38:30 -070010112 } while (0);
10113
10114 if (0 != ret_status)
10115 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010116#ifdef TIMER_MANAGER
10117 vos_timer_exit();
10118#endif
10119#ifdef MEMORY_DEBUG
10120 vos_mem_exit();
10121#endif
10122
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010123#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010125#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010126
10127#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10128 wlan_logging_sock_deinit_svc();
10129#endif
10130
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
10132 }
10133 else
10134 {
10135 //Send WLAN UP indication to Nlink Service
10136 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
10137
10138 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070010139 }
10140
10141 EXIT();
10142
10143 return ret_status;
10144}
10145
Jeff Johnson32d95a32012-09-10 13:15:23 -070010146/**---------------------------------------------------------------------------
10147
10148 \brief hdd_module_init() - Init Function
10149
10150 This is the driver entry point (invoked when module is loaded using insmod)
10151
10152 \param - None
10153
10154 \return - 0 for success, non zero for failure
10155
10156 --------------------------------------------------------------------------*/
10157#ifdef MODULE
10158static int __init hdd_module_init ( void)
10159{
10160 return hdd_driver_init();
10161}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010162#else /* #ifdef MODULE */
10163static int __init hdd_module_init ( void)
10164{
10165 /* Driver initialization is delayed to fwpath_changed_handler */
10166 return 0;
10167}
Jeff Johnson32d95a32012-09-10 13:15:23 -070010168#endif /* #ifdef MODULE */
10169
Jeff Johnson295189b2012-06-20 16:38:30 -070010170
10171/**---------------------------------------------------------------------------
10172
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010173 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070010174
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010175 This is the driver exit point (invoked when module is unloaded using rmmod
10176 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010177
10178 \param - None
10179
10180 \return - None
10181
10182 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010183static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010184{
10185 hdd_context_t *pHddCtx = NULL;
10186 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010187 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010188 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010189
10190 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10191
10192 //Get the global vos context
10193 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10194
10195 if(!pVosContext)
10196 {
10197 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10198 goto done;
10199 }
10200
10201 //Get the HDD context.
10202 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10203
10204 if(!pHddCtx)
10205 {
10206 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10207 }
10208 else
10209 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053010210 /* We wait for active entry threads to exit from driver
10211 * by waiting until rtnl_lock is available.
10212 */
10213 rtnl_lock();
10214 rtnl_unlock();
10215
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010216 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10217 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10218 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10219 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010221 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010222 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10223 msecs_to_jiffies(30000));
10224 if(!rc)
10225 {
10226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10227 "%s:SSR timedout, fatal error", __func__);
10228 VOS_BUG(0);
10229 }
10230 }
10231
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010232 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10233 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010234
c_hpothu8adb97b2014-12-08 19:38:20 +053010235 /* Driver Need to send country code 00 in below condition
10236 * 1) If gCountryCodePriority is set to 1; and last country
10237 * code set is through 11d. This needs to be done in case
10238 * when NV country code is 00.
10239 * This Needs to be done as when kernel store last country
10240 * code and if stored country code is not through 11d,
10241 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10242 * in next load/unload as soon as we get any country through
10243 * 11d. In sme_HandleChangeCountryCodeByUser
10244 * pMsg->countryCode will be last countryCode and
10245 * pMac->scan.countryCode11d will be country through 11d so
10246 * due to mismatch driver will disable 11d.
10247 *
10248 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010249
c_hpothu8adb97b2014-12-08 19:38:20 +053010250 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010251 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010252 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010253 {
10254 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010255 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010256 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10257 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010258
c_hpothu8adb97b2014-12-08 19:38:20 +053010259 //Do all the cleanup before deregistering the driver
10260 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 }
10262
Jeff Johnson295189b2012-06-20 16:38:30 -070010263 vos_preClose( &pVosContext );
10264
10265#ifdef TIMER_MANAGER
10266 vos_timer_exit();
10267#endif
10268#ifdef MEMORY_DEBUG
10269 vos_mem_exit();
10270#endif
10271
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010272#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10273 wlan_logging_sock_deinit_svc();
10274#endif
10275
Jeff Johnson295189b2012-06-20 16:38:30 -070010276done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010277#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010278 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010279#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010280
Jeff Johnson295189b2012-06-20 16:38:30 -070010281 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10282}
10283
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010284/**---------------------------------------------------------------------------
10285
10286 \brief hdd_module_exit() - Exit function
10287
10288 This is the driver exit point (invoked when module is unloaded using rmmod)
10289
10290 \param - None
10291
10292 \return - None
10293
10294 --------------------------------------------------------------------------*/
10295static void __exit hdd_module_exit(void)
10296{
10297 hdd_driver_exit();
10298}
10299
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010300#ifdef MODULE
10301static int fwpath_changed_handler(const char *kmessage,
10302 struct kernel_param *kp)
10303{
Jeff Johnson76052702013-04-16 13:55:05 -070010304 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010305}
10306
10307static int con_mode_handler(const char *kmessage,
10308 struct kernel_param *kp)
10309{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010310 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010311}
10312#else /* #ifdef MODULE */
10313/**---------------------------------------------------------------------------
10314
Jeff Johnson76052702013-04-16 13:55:05 -070010315 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010316
Jeff Johnson76052702013-04-16 13:55:05 -070010317 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010318 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010319 - invoked when module parameter fwpath is modified from userspace to signal
10320 initializing the WLAN driver or when con_mode is modified from userspace
10321 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010322
10323 \return - 0 for success, non zero for failure
10324
10325 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010326static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010327{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010328 int ret_status;
10329
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010330 if (!wlan_hdd_inited) {
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
10336 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010337
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010338 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010339
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010340 ret_status = hdd_driver_init();
10341 wlan_hdd_inited = ret_status ? 0 : 1;
10342 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010343}
10344
Jeff Johnson295189b2012-06-20 16:38:30 -070010345/**---------------------------------------------------------------------------
10346
Jeff Johnson76052702013-04-16 13:55:05 -070010347 \brief fwpath_changed_handler() - Handler Function
10348
10349 Handle changes to the fwpath parameter
10350
10351 \return - 0 for success, non zero for failure
10352
10353 --------------------------------------------------------------------------*/
10354static int fwpath_changed_handler(const char *kmessage,
10355 struct kernel_param *kp)
10356{
10357 int ret;
10358
10359 ret = param_set_copystring(kmessage, kp);
10360 if (0 == ret)
10361 ret = kickstart_driver();
10362 return ret;
10363}
10364
10365/**---------------------------------------------------------------------------
10366
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010367 \brief con_mode_handler() -
10368
10369 Handler function for module param con_mode when it is changed by userspace
10370 Dynamically linked - do nothing
10371 Statically linked - exit and init driver, as in rmmod and insmod
10372
Jeff Johnson76052702013-04-16 13:55:05 -070010373 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010374
Jeff Johnson76052702013-04-16 13:55:05 -070010375 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010376
10377 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010378static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010379{
Jeff Johnson76052702013-04-16 13:55:05 -070010380 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010381
Jeff Johnson76052702013-04-16 13:55:05 -070010382 ret = param_set_int(kmessage, kp);
10383 if (0 == ret)
10384 ret = kickstart_driver();
10385 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010386}
10387#endif /* #ifdef MODULE */
10388
10389/**---------------------------------------------------------------------------
10390
Jeff Johnson295189b2012-06-20 16:38:30 -070010391 \brief hdd_get_conparam() -
10392
10393 This is the driver exit point (invoked when module is unloaded using rmmod)
10394
10395 \param - None
10396
10397 \return - tVOS_CON_MODE
10398
10399 --------------------------------------------------------------------------*/
10400tVOS_CON_MODE hdd_get_conparam ( void )
10401{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010402#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010404#else
10405 return (tVOS_CON_MODE)curr_con_mode;
10406#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010407}
10408void hdd_set_conparam ( v_UINT_t newParam )
10409{
10410 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010411#ifndef MODULE
10412 curr_con_mode = con_mode;
10413#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010414}
10415/**---------------------------------------------------------------------------
10416
10417 \brief hdd_softap_sta_deauth() - function
10418
10419 This to take counter measure to handle deauth req from HDD
10420
10421 \param - pAdapter - Pointer to the HDD
10422
10423 \param - enable - boolean value
10424
10425 \return - None
10426
10427 --------------------------------------------------------------------------*/
10428
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010429VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10430 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010431{
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010433 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010434
10435 ENTER();
10436
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010437 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10438 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010439
10440 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010441 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010442 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010443
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010444 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010445
10446 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010447 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010448}
10449
10450/**---------------------------------------------------------------------------
10451
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010452 \brief hdd_del_all_sta() - function
10453
10454 This function removes all the stations associated on stopping AP/P2P GO.
10455
10456 \param - pAdapter - Pointer to the HDD
10457
10458 \return - None
10459
10460 --------------------------------------------------------------------------*/
10461
10462int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10463{
10464 v_U16_t i;
10465 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010466 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10467 ptSapContext pSapCtx = NULL;
10468 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10469 if(pSapCtx == NULL){
10470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10471 FL("psapCtx is NULL"));
10472 return 1;
10473 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010474 ENTER();
10475
10476 hddLog(VOS_TRACE_LEVEL_INFO,
10477 "%s: Delete all STAs associated.",__func__);
10478 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10479 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10480 )
10481 {
10482 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10483 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010484 if ((pSapCtx->aStaInfo[i].isUsed) &&
10485 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010486 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010487 struct tagCsrDelStaParams delStaParams;
10488
10489 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010490 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010491 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10492 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010493 &delStaParams);
10494 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010495 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010496 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010497 }
10498 }
10499 }
10500
10501 EXIT();
10502 return 0;
10503}
10504
10505/**---------------------------------------------------------------------------
10506
Jeff Johnson295189b2012-06-20 16:38:30 -070010507 \brief hdd_softap_sta_disassoc() - function
10508
10509 This to take counter measure to handle deauth req from HDD
10510
10511 \param - pAdapter - Pointer to the HDD
10512
10513 \param - enable - boolean value
10514
10515 \return - None
10516
10517 --------------------------------------------------------------------------*/
10518
10519void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10520{
10521 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10522
10523 ENTER();
10524
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010525 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010526
10527 //Ignore request to disassoc bcmc station
10528 if( pDestMacAddress[0] & 0x1 )
10529 return;
10530
10531 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10532}
10533
10534void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10535{
10536 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10537
10538 ENTER();
10539
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010540 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010541
10542 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10543}
10544
Jeff Johnson295189b2012-06-20 16:38:30 -070010545/**---------------------------------------------------------------------------
10546 *
10547 * \brief hdd_get__concurrency_mode() -
10548 *
10549 *
10550 * \param - None
10551 *
10552 * \return - CONCURRENCY MODE
10553 *
10554 * --------------------------------------------------------------------------*/
10555tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10556{
10557 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10558 hdd_context_t *pHddCtx;
10559
10560 if (NULL != pVosContext)
10561 {
10562 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10563 if (NULL != pHddCtx)
10564 {
10565 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10566 }
10567 }
10568
10569 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010570 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010571 return VOS_STA;
10572}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010573v_BOOL_t
10574wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10575{
10576 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010577
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010578 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10579 if (pAdapter == NULL)
10580 {
10581 hddLog(VOS_TRACE_LEVEL_INFO,
10582 FL("GO doesn't exist"));
10583 return TRUE;
10584 }
10585 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10586 {
10587 hddLog(VOS_TRACE_LEVEL_INFO,
10588 FL("GO started"));
10589 return TRUE;
10590 }
10591 else
10592 /* wait till GO changes its interface to p2p device */
10593 hddLog(VOS_TRACE_LEVEL_INFO,
10594 FL("Del_bss called, avoid apps suspend"));
10595 return FALSE;
10596
10597}
Jeff Johnson295189b2012-06-20 16:38:30 -070010598/* Decide whether to allow/not the apps power collapse.
10599 * Allow apps power collapse if we are in connected state.
10600 * if not, allow only if we are in IMPS */
10601v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10602{
10603 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010604 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010605 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010606 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10607 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10608 hdd_adapter_t *pAdapter = NULL;
10609 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010610 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010611
Jeff Johnson295189b2012-06-20 16:38:30 -070010612 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10613 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010614
Yathish9f22e662012-12-10 14:21:35 -080010615 concurrent_state = hdd_get_concurrency_mode();
10616
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010617 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10618 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10619 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010620#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010621
Yathish9f22e662012-12-10 14:21:35 -080010622 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010623 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010624 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10625 return TRUE;
10626#endif
10627
Jeff Johnson295189b2012-06-20 16:38:30 -070010628 /*loop through all adapters. TBD fix for Concurrency */
10629 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10630 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10631 {
10632 pAdapter = pAdapterNode->pAdapter;
10633 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10634 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10635 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010636 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010637 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010638 && pmcState != STOPPED && pmcState != STANDBY &&
10639 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010640 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10641 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010643 if(pmcState == FULL_POWER &&
10644 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10645 {
10646 /*
10647 * When SCO indication comes from Coex module , host will
10648 * enter in to full power mode, but this should not prevent
10649 * apps processor power collapse.
10650 */
10651 hddLog(LOG1,
10652 FL("Allow apps power collapse"
10653 "even when sco indication is set"));
10654 return TRUE;
10655 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010656 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010657 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10658 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010659 return FALSE;
10660 }
10661 }
10662 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10663 pAdapterNode = pNext;
10664 }
10665 return TRUE;
10666}
10667
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010668/* Decides whether to send suspend notification to Riva
10669 * if any adapter is in BMPS; then it is required */
10670v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10671{
10672 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10673 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10674
10675 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10676 {
10677 return TRUE;
10678 }
10679 return FALSE;
10680}
10681
Jeff Johnson295189b2012-06-20 16:38:30 -070010682void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10683{
10684 switch(mode)
10685 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010686 case VOS_STA_MODE:
10687 case VOS_P2P_CLIENT_MODE:
10688 case VOS_P2P_GO_MODE:
10689 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010690 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010691 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010692 break;
10693 default:
10694 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010695 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010696 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10697 "Number of open sessions for mode %d = %d"),
10698 pHddCtx->concurrency_mode, mode,
10699 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010700}
10701
10702
10703void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10704{
10705 switch(mode)
10706 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010707 case VOS_STA_MODE:
10708 case VOS_P2P_CLIENT_MODE:
10709 case VOS_P2P_GO_MODE:
10710 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010711 pHddCtx->no_of_open_sessions[mode]--;
10712 if (!(pHddCtx->no_of_open_sessions[mode]))
10713 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010714 break;
10715 default:
10716 break;
10717 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010718 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10719 "Number of open sessions for mode %d = %d"),
10720 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10721
10722}
10723/**---------------------------------------------------------------------------
10724 *
10725 * \brief wlan_hdd_incr_active_session()
10726 *
10727 * This function increments the number of active sessions
10728 * maintained per device mode
10729 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10730 * Incase of SAP/P2P GO upon bss start it is incremented
10731 *
10732 * \param pHddCtx - HDD Context
10733 * \param mode - device mode
10734 *
10735 * \return - None
10736 *
10737 * --------------------------------------------------------------------------*/
10738void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10739{
10740 switch (mode) {
10741 case VOS_STA_MODE:
10742 case VOS_P2P_CLIENT_MODE:
10743 case VOS_P2P_GO_MODE:
10744 case VOS_STA_SAP_MODE:
10745 pHddCtx->no_of_active_sessions[mode]++;
10746 break;
10747 default:
10748 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10749 break;
10750 }
10751 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10752 mode,
10753 pHddCtx->no_of_active_sessions[mode]);
10754}
10755
10756/**---------------------------------------------------------------------------
10757 *
10758 * \brief wlan_hdd_decr_active_session()
10759 *
10760 * This function decrements the number of active sessions
10761 * maintained per device mode
10762 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10763 * Incase of SAP/P2P GO upon bss stop it is decremented
10764 *
10765 * \param pHddCtx - HDD Context
10766 * \param mode - device mode
10767 *
10768 * \return - None
10769 *
10770 * --------------------------------------------------------------------------*/
10771void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10772{
10773 switch (mode) {
10774 case VOS_STA_MODE:
10775 case VOS_P2P_CLIENT_MODE:
10776 case VOS_P2P_GO_MODE:
10777 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010778 if (pHddCtx->no_of_active_sessions[mode] > 0)
10779 pHddCtx->no_of_active_sessions[mode]--;
10780 else
10781 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10782 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010783 break;
10784 default:
10785 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10786 break;
10787 }
10788 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10789 mode,
10790 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010791}
10792
Jeff Johnsone7245742012-09-05 17:12:55 -070010793/**---------------------------------------------------------------------------
10794 *
10795 * \brief wlan_hdd_restart_init
10796 *
10797 * This function initalizes restart timer/flag. An internal function.
10798 *
10799 * \param - pHddCtx
10800 *
10801 * \return - None
10802 *
10803 * --------------------------------------------------------------------------*/
10804
10805static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10806{
10807 /* Initialize */
10808 pHddCtx->hdd_restart_retries = 0;
10809 atomic_set(&pHddCtx->isRestartInProgress, 0);
10810 vos_timer_init(&pHddCtx->hdd_restart_timer,
10811 VOS_TIMER_TYPE_SW,
10812 wlan_hdd_restart_timer_cb,
10813 pHddCtx);
10814}
10815/**---------------------------------------------------------------------------
10816 *
10817 * \brief wlan_hdd_restart_deinit
10818 *
10819 * This function cleans up the resources used. An internal function.
10820 *
10821 * \param - pHddCtx
10822 *
10823 * \return - None
10824 *
10825 * --------------------------------------------------------------------------*/
10826
10827static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10828{
10829
10830 VOS_STATUS vos_status;
10831 /* Block any further calls */
10832 atomic_set(&pHddCtx->isRestartInProgress, 1);
10833 /* Cleanup */
10834 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10835 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010836 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010837 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10838 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010839 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010840
10841}
10842
10843/**---------------------------------------------------------------------------
10844 *
10845 * \brief wlan_hdd_framework_restart
10846 *
10847 * This function uses a cfg80211 API to start a framework initiated WLAN
10848 * driver module unload/load.
10849 *
10850 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10851 *
10852 *
10853 * \param - pHddCtx
10854 *
10855 * \return - VOS_STATUS_SUCCESS: Success
10856 * VOS_STATUS_E_EMPTY: Adapter is Empty
10857 * VOS_STATUS_E_NOMEM: No memory
10858
10859 * --------------------------------------------------------------------------*/
10860
10861static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10862{
10863 VOS_STATUS status = VOS_STATUS_SUCCESS;
10864 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010865 int len = (sizeof (struct ieee80211_mgmt));
10866 struct ieee80211_mgmt *mgmt = NULL;
10867
10868 /* Prepare the DEAUTH managment frame with reason code */
10869 mgmt = kzalloc(len, GFP_KERNEL);
10870 if(mgmt == NULL)
10871 {
10872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10873 "%s: memory allocation failed (%d bytes)", __func__, len);
10874 return VOS_STATUS_E_NOMEM;
10875 }
10876 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010877
10878 /* Iterate over all adapters/devices */
10879 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053010880 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
10881 {
10882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10883 FL("fail to get adapter: %p %d"), pAdapterNode, status);
10884 goto end;
10885 }
10886
Jeff Johnsone7245742012-09-05 17:12:55 -070010887 do
10888 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053010889 if(pAdapterNode->pAdapter &&
10890 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070010891 {
10892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10893 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10894 pAdapterNode->pAdapter->dev->name,
10895 pAdapterNode->pAdapter->device_mode,
10896 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010897 /*
10898 * CFG80211 event to restart the driver
10899 *
10900 * 'cfg80211_send_unprot_deauth' sends a
10901 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10902 * of SME(Linux Kernel) state machine.
10903 *
10904 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10905 * the driver.
10906 *
10907 */
10908
10909 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010910 }
10911 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10912 pAdapterNode = pNext;
10913 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10914
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053010915 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010916 /* Free the allocated management frame */
10917 kfree(mgmt);
10918
Jeff Johnsone7245742012-09-05 17:12:55 -070010919 /* Retry until we unload or reach max count */
10920 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10921 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10922
10923 return status;
10924
10925}
10926/**---------------------------------------------------------------------------
10927 *
10928 * \brief wlan_hdd_restart_timer_cb
10929 *
10930 * Restart timer callback. An internal function.
10931 *
10932 * \param - User data:
10933 *
10934 * \return - None
10935 *
10936 * --------------------------------------------------------------------------*/
10937
10938void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10939{
10940 hdd_context_t *pHddCtx = usrDataForCallback;
10941 wlan_hdd_framework_restart(pHddCtx);
10942 return;
10943
10944}
10945
10946
10947/**---------------------------------------------------------------------------
10948 *
10949 * \brief wlan_hdd_restart_driver
10950 *
10951 * This function sends an event to supplicant to restart the WLAN driver.
10952 *
10953 * This function is called from vos_wlanRestart.
10954 *
10955 * \param - pHddCtx
10956 *
10957 * \return - VOS_STATUS_SUCCESS: Success
10958 * VOS_STATUS_E_EMPTY: Adapter is Empty
10959 * VOS_STATUS_E_ALREADY: Request already in progress
10960
10961 * --------------------------------------------------------------------------*/
10962VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10963{
10964 VOS_STATUS status = VOS_STATUS_SUCCESS;
10965
10966 /* A tight check to make sure reentrancy */
10967 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10968 {
Mihir Shetefd528652014-06-23 19:07:50 +053010969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010970 "%s: WLAN restart is already in progress", __func__);
10971
10972 return VOS_STATUS_E_ALREADY;
10973 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010974 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010975#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053010976 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010977#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010978
Jeff Johnsone7245742012-09-05 17:12:55 -070010979 return status;
10980}
10981
Mihir Shetee1093ba2014-01-21 20:13:32 +053010982/**---------------------------------------------------------------------------
10983 *
10984 * \brief wlan_hdd_init_channels
10985 *
10986 * This function is used to initialize the channel list in CSR
10987 *
10988 * This function is called from hdd_wlan_startup
10989 *
10990 * \param - pHddCtx: HDD context
10991 *
10992 * \return - VOS_STATUS_SUCCESS: Success
10993 * VOS_STATUS_E_FAULT: Failure reported by SME
10994
10995 * --------------------------------------------------------------------------*/
10996static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10997{
10998 eHalStatus status;
10999
11000 status = sme_InitChannels(pHddCtx->hHal);
11001 if (HAL_STATUS_SUCCESS(status))
11002 {
11003 return VOS_STATUS_SUCCESS;
11004 }
11005 else
11006 {
11007 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
11008 __func__, status);
11009 return VOS_STATUS_E_FAULT;
11010 }
11011}
11012
Mihir Shete04206452014-11-20 17:50:58 +053011013#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011014VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011015{
11016 eHalStatus status;
11017
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011018 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011019 if (HAL_STATUS_SUCCESS(status))
11020 {
11021 return VOS_STATUS_SUCCESS;
11022 }
11023 else
11024 {
11025 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
11026 __func__, status);
11027 return VOS_STATUS_E_FAULT;
11028 }
11029}
Mihir Shete04206452014-11-20 17:50:58 +053011030#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070011031/*
11032 * API to find if there is any STA or P2P-Client is connected
11033 */
11034VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
11035{
11036 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
11037}
Jeff Johnsone7245742012-09-05 17:12:55 -070011038
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011039
11040/*
11041 * API to find if the firmware will send logs using DXE channel
11042 */
11043v_U8_t hdd_is_fw_logging_enabled(void)
11044{
11045 hdd_context_t *pHddCtx;
11046
11047 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
11048 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
11049
Mihir Sheteb7d351f2015-04-17 12:25:32 +053011050 return (pHddCtx && (pHddCtx->cfg_ini->enableMgmtLogging ||
11051 pHddCtx->cfg_ini->enableBMUHWtracing));
Mihir Shetee2ae82a2015-03-16 14:08:49 +053011052}
11053
Agarwal Ashish57e84372014-12-05 18:26:53 +053011054/*
11055 * API to find if there is any session connected
11056 */
11057VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
11058{
11059 return sme_is_any_session_connected(pHddCtx->hHal);
11060}
11061
11062
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011063int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
11064{
11065 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11066 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053011067 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053011068 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011069
11070 pScanInfo = &pHddCtx->scan_info;
11071 if (pScanInfo->mScanPending)
11072 {
c_hpothua3d45d52015-01-05 14:11:17 +053011073 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
11074 eCSR_SCAN_ABORT_DEFAULT);
11075 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11076 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011077
c_hpothua3d45d52015-01-05 14:11:17 +053011078 /* If there is active scan command lets wait for the completion else
11079 * there is no need to wait as scan command might be in the SME pending
11080 * command list.
11081 */
11082 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
11083 {
11084 INIT_COMPLETION(pScanInfo->abortscan_event_var);
11085 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011086 &pScanInfo->abortscan_event_var,
11087 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053011088 if (0 >= status)
11089 {
11090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053011091 "%s: Timeout or Interrupt occurred while waiting for abort"
11092 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053011093 return -ETIMEDOUT;
11094 }
11095 }
11096 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
11097 {
11098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11099 FL("hdd_abort_mac_scan failed"));
11100 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011101 }
11102 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053011103 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011104}
11105
c_hpothu225aa7c2014-10-22 17:45:13 +053011106VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
11107{
11108 hdd_adapter_t *pAdapter;
11109 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11110 VOS_STATUS vosStatus;
11111
11112 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11113 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11114 {
11115 pAdapter = pAdapterNode->pAdapter;
11116 if (NULL != pAdapter)
11117 {
11118 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
11119 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
11120 WLAN_HDD_P2P_GO == pAdapter->device_mode)
11121 {
11122 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
11123 pAdapter->device_mode);
11124 if (VOS_STATUS_SUCCESS !=
11125 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
11126 {
11127 hddLog(LOGE, FL("failed to abort ROC"));
11128 return VOS_STATUS_E_FAILURE;
11129 }
11130 }
11131 }
11132 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11133 pAdapterNode = pNext;
11134 }
11135 return VOS_STATUS_SUCCESS;
11136}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053011137
Mihir Shete0be28772015-02-17 18:42:14 +053011138hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
11139{
11140 hdd_adapter_t *pAdapter;
11141 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11142 hdd_cfg80211_state_t *cfgState;
11143 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
11144 VOS_STATUS vosStatus;
11145
11146 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
11147 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
11148 {
11149 pAdapter = pAdapterNode->pAdapter;
11150 if (NULL != pAdapter)
11151 {
11152 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
11153 pRemainChanCtx = cfgState->remain_on_chan_ctx;
11154 if (pRemainChanCtx)
11155 break;
11156 }
11157 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
11158 pAdapterNode = pNext;
11159 }
11160 return pRemainChanCtx;
11161}
11162
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053011163/**
11164 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
11165 *
11166 * @pHddCtx: HDD context within host driver
11167 * @dfsScanMode: dfsScanMode passed from ioctl
11168 *
11169 */
11170
11171VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
11172 tANI_U8 dfsScanMode)
11173{
11174 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11175 hdd_adapter_t *pAdapter;
11176 VOS_STATUS vosStatus;
11177 hdd_station_ctx_t *pHddStaCtx;
11178 eHalStatus status = eHAL_STATUS_SUCCESS;
11179
11180 if(!pHddCtx)
11181 {
11182 hddLog(LOGE, FL("HDD context is Null"));
11183 return eHAL_STATUS_FAILURE;
11184 }
11185
11186 if (pHddCtx->scan_info.mScanPending)
11187 {
11188 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
11189 pHddCtx->scan_info.sessionId);
11190 hdd_abort_mac_scan(pHddCtx,
11191 pHddCtx->scan_info.sessionId,
11192 eCSR_SCAN_ABORT_DEFAULT);
11193 }
11194
11195 if (!dfsScanMode)
11196 {
11197 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11198 while ((NULL != pAdapterNode) &&
11199 (VOS_STATUS_SUCCESS == vosStatus))
11200 {
11201 pAdapter = pAdapterNode->pAdapter;
11202
11203 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
11204 {
11205 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11206
11207 if(!pHddStaCtx)
11208 {
11209 hddLog(LOGE, FL("HDD STA context is Null"));
11210 return eHAL_STATUS_FAILURE;
11211 }
11212
11213 /* if STA is already connected on DFS channel,
11214 disconnect immediately*/
11215 if (hdd_connIsConnected(pHddStaCtx) &&
11216 (NV_CHANNEL_DFS ==
11217 vos_nv_getChannelEnabledState(
11218 pHddStaCtx->conn_info.operationChannel)))
11219 {
11220 status = sme_RoamDisconnect(pHddCtx->hHal,
11221 pAdapter->sessionId,
11222 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11223 hddLog(LOG1, FL("Client connected on DFS channel %d,"
11224 "sme_RoamDisconnect returned with status: %d"
11225 "for sessionid: %d"), pHddStaCtx->conn_info.
11226 operationChannel, status, pAdapter->sessionId);
11227 }
11228 }
11229
11230 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
11231 &pNext);
11232 pAdapterNode = pNext;
11233 }
11234 }
11235
11236 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
11237 sme_UpdateDFSRoamMode(pHddCtx->hHal,
11238 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
11239
11240 status = sme_HandleDFSChanScan(pHddCtx->hHal);
11241 if (!HAL_STATUS_SUCCESS(status))
11242 {
11243 hddLog(LOGE,
11244 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
11245 return status;
11246 }
11247
11248 return status;
11249}
11250
Jeff Johnson295189b2012-06-20 16:38:30 -070011251//Register the module init/exit functions
11252module_init(hdd_module_init);
11253module_exit(hdd_module_exit);
11254
11255MODULE_LICENSE("Dual BSD/GPL");
11256MODULE_AUTHOR("Qualcomm Atheros, Inc.");
11257MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
11258
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070011259module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
11260 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011261
Jeff Johnson76052702013-04-16 13:55:05 -070011262module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011263 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080011264
11265module_param(enable_dfs_chan_scan, int,
11266 S_IRUSR | S_IRGRP | S_IROTH);
11267
11268module_param(enable_11d, int,
11269 S_IRUSR | S_IRGRP | S_IROTH);
11270
11271module_param(country_code, charp,
11272 S_IRUSR | S_IRGRP | S_IROTH);