blob: 354b421d0127af3ff6efc9120aad7e8a235a698e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
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
37 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
38
39 Qualcomm Confidential and Proprietary.
40
41 ========================================================================*/
42
43/**=========================================================================
44
45 EDIT HISTORY FOR FILE
46
47
48 This section contains comments describing changes made to the module.
49 Notice that changes are listed in reverse chronological order.
50
51
52 $Header:$ $DateTime: $ $Author: $
53
54
55 when who what, where, why
56 -------- --- --------------------------------------------------------
57 04/5/09 Shailender Created module.
58 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
59 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
60 ==========================================================================*/
61
62/*--------------------------------------------------------------------------
63 Include Files
64 ------------------------------------------------------------------------*/
65//#include <wlan_qct_driver.h>
66#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <vos_api.h>
68#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070069#include <linux/etherdevice.h>
70#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070071#ifdef ANI_BUS_TYPE_PLATFORM
72#include <linux/wcnss_wlan.h>
73#endif //ANI_BUS_TYPE_PLATFORM
74#ifdef ANI_BUS_TYPE_PCI
75#include "wcnss_wlan.h"
76#endif /* ANI_BUS_TYPE_PCI */
77#include <wlan_hdd_tx_rx.h>
78#include <palTimer.h>
79#include <wniApi.h>
80#include <wlan_nlink_srv.h>
81#include <wlan_btc_svc.h>
82#include <wlan_hdd_cfg.h>
83#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053084#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070085#include <wlan_hdd_wowl.h>
86#include <wlan_hdd_misc.h>
87#include <wlan_hdd_wext.h>
88#ifdef WLAN_BTAMP_FEATURE
89#include <bap_hdd_main.h>
90#include <bapInternal.h>
91#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053092#include "wlan_hdd_trace.h"
93#include "vos_types.h"
94#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070095#include <linux/wireless.h>
96#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053097#include <linux/inetdevice.h>
98#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099#include "wlan_hdd_cfg80211.h"
100#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700101#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700102int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700103#include "sapApi.h"
104#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700105#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
107#include <soc/qcom/subsystem_restart.h>
108#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include <wlan_hdd_hostapd.h>
112#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "wlan_hdd_dev_pwr.h"
115#ifdef WLAN_BTAMP_FEATURE
116#include "bap_hdd_misc.h"
117#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700118#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800120#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530121#ifdef FEATURE_WLAN_TDLS
122#include "wlan_hdd_tdls.h"
123#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700124#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530125#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700126
127#ifdef MODULE
128#define WLAN_MODULE_NAME module_name(THIS_MODULE)
129#else
130#define WLAN_MODULE_NAME "wlan"
131#endif
132
133#ifdef TIMER_MANAGER
134#define TIMER_MANAGER_STR " +TIMER_MANAGER"
135#else
136#define TIMER_MANAGER_STR ""
137#endif
138
139#ifdef MEMORY_DEBUG
140#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
141#else
142#define MEMORY_DEBUG_STR ""
143#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530144#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700145/* the Android framework expects this param even though we don't use it */
146#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700147static char fwpath_buffer[BUF_LEN];
148static struct kparam_string fwpath = {
149 .string = fwpath_buffer,
150 .maxlen = BUF_LEN,
151};
Arif Hussain66559122013-11-21 10:11:40 -0800152
153static char *country_code;
154static int enable_11d = -1;
155static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530156static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800157
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700158#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700159static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700160#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700161
Jeff Johnsone7245742012-09-05 17:12:55 -0700162/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800163 * spinlock for synchronizing asynchronous request/response
164 * (full description of use in wlan_hdd_main.h)
165 */
166DEFINE_SPINLOCK(hdd_context_lock);
167
168/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700169 * The rate at which the driver sends RESTART event to supplicant
170 * once the function 'vos_wlanRestart()' is called
171 *
172 */
173#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
174#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700175
176/*
177 * Size of Driver command strings from upper layer
178 */
179#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
180#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
181
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800182#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700183#define TID_MIN_VALUE 0
184#define TID_MAX_VALUE 15
185static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
186 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800187static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
188 tCsrEseBeaconReq *pEseBcnReq);
189#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700190
Atul Mittal1d722422014-03-19 11:15:07 +0530191/*
192 * Maximum buffer size used for returning the data back to user space
193 */
194#define WLAN_MAX_BUF_SIZE 1024
195#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700196
c_hpothu92367912014-05-01 15:18:17 +0530197//wait time for beacon miss rate.
198#define BCN_MISS_RATE_TIME 500
199
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800200#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700201static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700202#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700203/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700204static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700205
206//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700207static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
208static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
209static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
210void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800211void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700212
Jeff Johnson295189b2012-06-20 16:38:30 -0700213v_U16_t hdd_select_queue(struct net_device *dev,
214 struct sk_buff *skb);
215
216#ifdef WLAN_FEATURE_PACKET_FILTERING
217static void hdd_set_multicast_list(struct net_device *dev);
218#endif
219
220void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
221
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800222#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800223void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
224static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700225static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
226 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
227 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700228static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
229 tANI_U8 *pTargetApBssid,
230 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800231#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800232#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700233VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800234#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700235
Mihir Shetee1093ba2014-01-21 20:13:32 +0530236static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530237const char * hdd_device_modetoString(v_U8_t device_mode)
238{
239 switch(device_mode)
240 {
241 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
242 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
243 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
244 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
245 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
246 CASE_RETURN_STRING( WLAN_HDD_FTM );
247 CASE_RETURN_STRING( WLAN_HDD_IBSS );
248 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
249 default:
250 return "device_mode Unknown";
251 }
252}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530253
Jeff Johnson295189b2012-06-20 16:38:30 -0700254static int hdd_netdev_notifier_call(struct notifier_block * nb,
255 unsigned long state,
256 void *ndev)
257{
258 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700259 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700260 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700261#ifdef WLAN_BTAMP_FEATURE
262 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700263#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530264 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700265
266 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700267 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700268 (strncmp(dev->name, "p2p", 3)))
269 return NOTIFY_DONE;
270
Jeff Johnson295189b2012-06-20 16:38:30 -0700271 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700272 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700273
Jeff Johnson27cee452013-03-27 11:10:24 -0700274 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800276 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 VOS_ASSERT(0);
278 return NOTIFY_DONE;
279 }
280
Jeff Johnson27cee452013-03-27 11:10:24 -0700281 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
282 if (NULL == pHddCtx)
283 {
284 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
285 VOS_ASSERT(0);
286 return NOTIFY_DONE;
287 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800288 if (pHddCtx->isLogpInProgress)
289 return NOTIFY_DONE;
290
Jeff Johnson27cee452013-03-27 11:10:24 -0700291
292 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
293 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700294
295 switch (state) {
296 case NETDEV_REGISTER:
297 break;
298
299 case NETDEV_UNREGISTER:
300 break;
301
302 case NETDEV_UP:
303 break;
304
305 case NETDEV_DOWN:
306 break;
307
308 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700309 if(TRUE == pAdapter->isLinkUpSvcNeeded)
310 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700311 break;
312
313 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530314 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530315 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530316 {
317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
318 "%s: Timeout occurred while waiting for abortscan %ld",
319 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 }
321 else
322 {
323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530324 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 }
326#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 status = WLANBAP_StopAmp();
329 if(VOS_STATUS_SUCCESS != status )
330 {
331 pHddCtx->isAmpAllowed = VOS_TRUE;
332 hddLog(VOS_TRACE_LEVEL_FATAL,
333 "%s: Failed to stop AMP", __func__);
334 }
335 else
336 {
337 //a state m/c implementation in PAL is TBD to avoid this delay
338 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700339 if ( pHddCtx->isAmpAllowed )
340 {
341 WLANBAP_DeregisterFromHCI();
342 pHddCtx->isAmpAllowed = VOS_FALSE;
343 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700344 }
345#endif //WLAN_BTAMP_FEATURE
346 break;
347
348 default:
349 break;
350 }
351
352 return NOTIFY_DONE;
353}
354
355struct notifier_block hdd_netdev_notifier = {
356 .notifier_call = hdd_netdev_notifier_call,
357};
358
359/*---------------------------------------------------------------------------
360 * Function definitions
361 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700362void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
363void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700364//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700365static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700366#ifndef MODULE
367/* current con_mode - used only for statically linked driver
368 * con_mode is changed by userspace to indicate a mode change which will
369 * result in calling the module exit and init functions. The module
370 * exit function will clean up based on the value of con_mode prior to it
371 * being changed by userspace. So curr_con_mode records the current con_mode
372 * for exit when con_mode becomes the next mode for init
373 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700374static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700375#endif
376
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800377/**---------------------------------------------------------------------------
378
379 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
380
381 Called immediately after the cfg.ini is read in order to configure
382 the desired trace levels.
383
384 \param - moduleId - module whose trace level is being configured
385 \param - bitmask - bitmask of log levels to be enabled
386
387 \return - void
388
389 --------------------------------------------------------------------------*/
390static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
391{
392 wpt_tracelevel level;
393
394 /* if the bitmask is the default value, then a bitmask was not
395 specified in cfg.ini, so leave the logging level alone (it
396 will remain at the "compiled in" default value) */
397 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
398 {
399 return;
400 }
401
402 /* a mask was specified. start by disabling all logging */
403 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
404
405 /* now cycle through the bitmask until all "set" bits are serviced */
406 level = VOS_TRACE_LEVEL_FATAL;
407 while (0 != bitmask)
408 {
409 if (bitmask & 1)
410 {
411 vos_trace_setValue(moduleId, level, 1);
412 }
413 level++;
414 bitmask >>= 1;
415 }
416}
417
418
Jeff Johnson295189b2012-06-20 16:38:30 -0700419/**---------------------------------------------------------------------------
420
421 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
422
423 Called immediately after the cfg.ini is read in order to configure
424 the desired trace levels in the WDI.
425
426 \param - moduleId - module whose trace level is being configured
427 \param - bitmask - bitmask of log levels to be enabled
428
429 \return - void
430
431 --------------------------------------------------------------------------*/
432static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
433{
434 wpt_tracelevel level;
435
436 /* if the bitmask is the default value, then a bitmask was not
437 specified in cfg.ini, so leave the logging level alone (it
438 will remain at the "compiled in" default value) */
439 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
440 {
441 return;
442 }
443
444 /* a mask was specified. start by disabling all logging */
445 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
446
447 /* now cycle through the bitmask until all "set" bits are serviced */
448 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
449 while (0 != bitmask)
450 {
451 if (bitmask & 1)
452 {
453 wpalTraceSetLevel(moduleId, level, 1);
454 }
455 level++;
456 bitmask >>= 1;
457 }
458}
Jeff Johnson295189b2012-06-20 16:38:30 -0700459
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530460/*
461 * FUNCTION: wlan_hdd_validate_context
462 * This function is used to check the HDD context
463 */
464int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
465{
466 ENTER();
467
468 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
469 {
470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
471 "%s: HDD context is Null", __func__);
472 return -ENODEV;
473 }
474
475 if (pHddCtx->isLogpInProgress)
476 {
477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu8adb97b2014-12-08 19:38:20 +0530478 "%s: LOGP %s. Ignore!!", __func__,
479 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
480 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530481 return -EAGAIN;
482 }
483
Mihir Shete18156292014-03-11 15:38:30 +0530484 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530485 {
486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
487 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
488 return -EAGAIN;
489 }
490 return 0;
491}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700492#ifdef CONFIG_ENABLE_LINUX_REG
493void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
494{
495 hdd_adapter_t *pAdapter = NULL;
496 hdd_station_ctx_t *pHddStaCtx = NULL;
497 eCsrPhyMode phyMode;
498 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530499
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700500 if (NULL == pHddCtx)
501 {
502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
503 "HDD Context is null !!");
504 return ;
505 }
506
507 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
508 if (NULL == pAdapter)
509 {
510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
511 "pAdapter is null !!");
512 return ;
513 }
514
515 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
516 if (NULL == pHddStaCtx)
517 {
518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
519 "pHddStaCtx is null !!");
520 return ;
521 }
522
523 cfg_param = pHddCtx->cfg_ini;
524 if (NULL == cfg_param)
525 {
526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
527 "cfg_params not available !!");
528 return ;
529 }
530
531 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
532
533 if (!pHddCtx->isVHT80Allowed)
534 {
535 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
536 (eCSR_DOT11_MODE_11ac == phyMode) ||
537 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
538 {
539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
540 "Setting phymode to 11n!!");
541 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
542 }
543 }
544 else
545 {
546 /*New country Supports 11ac as well resetting value back from .ini*/
547 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
548 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
549 return ;
550 }
551
552 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
553 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
554 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
555 {
556 VOS_STATUS vosStatus;
557
558 // need to issue a disconnect to CSR.
559 INIT_COMPLETION(pAdapter->disconnect_comp_var);
560 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
561 pAdapter->sessionId,
562 eCSR_DISCONNECT_REASON_UNSPECIFIED );
563
564 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530565 {
566 long ret;
567
568 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700569 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530570 if (0 >= ret)
571 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
572 ret);
573 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700574
575 }
576}
577#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530578void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
579{
580 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
581 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
582 hdd_config_t *cfg_param;
583 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530584 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530585
586 if (NULL == pHddCtx)
587 {
588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
589 "HDD Context is null !!");
590 return ;
591 }
592
593 cfg_param = pHddCtx->cfg_ini;
594
595 if (NULL == cfg_param)
596 {
597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
598 "cfg_params not available !!");
599 return ;
600 }
601
602 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
603
604 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
605 {
606 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
607 (eCSR_DOT11_MODE_11ac == phyMode) ||
608 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
609 {
610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
611 "Setting phymode to 11n!!");
612 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
613 }
614 }
615 else
616 {
617 /*New country Supports 11ac as well resetting value back from .ini*/
618 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
619 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
620 return ;
621 }
622
623 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
624 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
625 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
626 {
627 VOS_STATUS vosStatus;
628
629 // need to issue a disconnect to CSR.
630 INIT_COMPLETION(pAdapter->disconnect_comp_var);
631 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
632 pAdapter->sessionId,
633 eCSR_DISCONNECT_REASON_UNSPECIFIED );
634
635 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530636 {
637 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530638 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530639 if (ret <= 0)
640 {
641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
642 "wait on disconnect_comp_var is failed %ld", ret);
643 }
644 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530645
646 }
647}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700648#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530649
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700650void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
651{
652 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
653 hdd_config_t *cfg_param;
654
655 if (NULL == pHddCtx)
656 {
657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
658 "HDD Context is null !!");
659 return ;
660 }
661
662 cfg_param = pHddCtx->cfg_ini;
663
664 if (NULL == cfg_param)
665 {
666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
667 "cfg_params not available !!");
668 return ;
669 }
670
Agarwal Ashish738843c2014-09-25 12:27:56 +0530671 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
672 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700673 {
674 /*New country doesn't support DFS */
675 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
676 }
677 else
678 {
679 /*New country Supports DFS as well resetting value back from .ini*/
680 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
681 }
682
683}
684
Rajeev79dbe4c2013-10-05 11:03:42 +0530685#ifdef FEATURE_WLAN_BATCH_SCAN
686
687/**---------------------------------------------------------------------------
688
689 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
690 input string
691
692 This function extracts assigned integer from string in below format:
693 "STRING=10" : extracts integer 10 from this string
694
695 \param - pInPtr Pointer to input string
696 \param - base Base for string to int conversion(10 for decimal 16 for hex)
697 \param - pOutPtr Pointer to variable in which extracted integer needs to be
698 assigned
699 \param - pLastArg to tell whether it is last arguement in input string or
700 not
701
702 \return - NULL for failure cases
703 pointer to next arguement in input string for success cases
704 --------------------------------------------------------------------------*/
705static tANI_U8 *
706hdd_extract_assigned_int_from_str
707(
708 tANI_U8 *pInPtr,
709 tANI_U8 base,
710 tANI_U32 *pOutPtr,
711 tANI_U8 *pLastArg
712)
713{
714 int tempInt;
715 int v = 0;
716 char buf[32];
717 int val = 0;
718 *pLastArg = FALSE;
719
720 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
721 if (NULL == pInPtr)
722 {
723 return NULL;
724 }
725
726 pInPtr++;
727
728 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
729
730 val = sscanf(pInPtr, "%32s ", buf);
731 if (val < 0 && val > strlen(pInPtr))
732 {
733 return NULL;
734 }
735 pInPtr += val;
736 v = kstrtos32(buf, base, &tempInt);
737 if (v < 0)
738 {
739 return NULL;
740 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800741 if (tempInt < 0)
742 {
743 tempInt = 0;
744 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530745 *pOutPtr = tempInt;
746
747 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
748 if (NULL == pInPtr)
749 {
750 *pLastArg = TRUE;
751 return NULL;
752 }
753 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
754
755 return pInPtr;
756}
757
758/**---------------------------------------------------------------------------
759
760 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
761 input string
762
763 This function extracts assigned character from string in below format:
764 "STRING=A" : extracts char 'A' from this string
765
766 \param - pInPtr Pointer to input string
767 \param - pOutPtr Pointer to variable in which extracted char needs to be
768 assigned
769 \param - pLastArg to tell whether it is last arguement in input string or
770 not
771
772 \return - NULL for failure cases
773 pointer to next arguement in input string for success cases
774 --------------------------------------------------------------------------*/
775static tANI_U8 *
776hdd_extract_assigned_char_from_str
777(
778 tANI_U8 *pInPtr,
779 tANI_U8 *pOutPtr,
780 tANI_U8 *pLastArg
781)
782{
783 *pLastArg = FALSE;
784
785 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
786 if (NULL == pInPtr)
787 {
788 return NULL;
789 }
790
791 pInPtr++;
792
793 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
794
795 *pOutPtr = *pInPtr;
796
797 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
798 if (NULL == pInPtr)
799 {
800 *pLastArg = TRUE;
801 return NULL;
802 }
803 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
804
805 return pInPtr;
806}
807
808
809/**---------------------------------------------------------------------------
810
811 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
812
813 This function parses set batch scan command in below format:
814 WLS_BATCHING_SET <space> followed by below arguements
815 "SCANFREQ=XX" : Optional defaults to 30 sec
816 "MSCAN=XX" : Required number of scans to attempt to batch
817 "BESTN=XX" : Best Network (RSSI) defaults to 16
818 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
819 A. implies only 5 GHz , B. implies only 2.4GHz
820 "RTT=X" : optional defaults to 0
821 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
822 error
823
824 For example input commands:
825 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
826 translated into set batch scan with following parameters:
827 a) Frequence 60 seconds
828 b) Batch 10 scans together
829 c) Best RSSI to be 20
830 d) 5GHz band only
831 e) RTT is equal to 0
832
833 \param - pValue Pointer to input channel list
834 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
835
836 \return - 0 for success non-zero for failure
837
838 --------------------------------------------------------------------------*/
839static int
840hdd_parse_set_batchscan_command
841(
842 tANI_U8 *pValue,
843 tSirSetBatchScanReq *pHddSetBatchScanReq
844)
845{
846 tANI_U8 *inPtr = pValue;
847 tANI_U8 val = 0;
848 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800849 tANI_U32 nScanFreq;
850 tANI_U32 nMscan;
851 tANI_U32 nBestN;
852 tANI_U8 ucRfBand;
853 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800854 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530855
856 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800857 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
858 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
859 nRtt = 0;
860 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530861
862 /*go to space after WLS_BATCHING_SET command*/
863 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
864 /*no argument after the command*/
865 if (NULL == inPtr)
866 {
867 return -EINVAL;
868 }
869
870 /*no space after the command*/
871 else if (SPACE_ASCII_VALUE != *inPtr)
872 {
873 return -EINVAL;
874 }
875
876 /*removing empty spaces*/
877 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
878
879 /*no argument followed by spaces*/
880 if ('\0' == *inPtr)
881 {
882 return -EINVAL;
883 }
884
885 /*check and parse SCANFREQ*/
886 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
887 {
888 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800889 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800890
Rajeev Kumarc933d982013-11-18 20:04:20 -0800891 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800892 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800893 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800894 }
895
Rajeev79dbe4c2013-10-05 11:03:42 +0530896 if ( (NULL == inPtr) || (TRUE == lastArg))
897 {
898 return -EINVAL;
899 }
900 }
901
902 /*check and parse MSCAN*/
903 if ((strncmp(inPtr, "MSCAN", 5) == 0))
904 {
905 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800906 &nMscan, &lastArg);
907
908 if (0 == nMscan)
909 {
910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
911 "invalid MSCAN=%d", nMscan);
912 return -EINVAL;
913 }
914
Rajeev79dbe4c2013-10-05 11:03:42 +0530915 if (TRUE == lastArg)
916 {
917 goto done;
918 }
919 else if (NULL == inPtr)
920 {
921 return -EINVAL;
922 }
923 }
924 else
925 {
926 return -EINVAL;
927 }
928
929 /*check and parse BESTN*/
930 if ((strncmp(inPtr, "BESTN", 5) == 0))
931 {
932 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800933 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800934
Rajeev Kumarc933d982013-11-18 20:04:20 -0800935 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800936 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800937 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800938 }
939
Rajeev79dbe4c2013-10-05 11:03:42 +0530940 if (TRUE == lastArg)
941 {
942 goto done;
943 }
944 else if (NULL == inPtr)
945 {
946 return -EINVAL;
947 }
948 }
949
950 /*check and parse CHANNEL*/
951 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
952 {
953 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800954
Rajeev79dbe4c2013-10-05 11:03:42 +0530955 if (('A' == val) || ('a' == val))
956 {
c_hpothuebf89732014-02-25 13:00:24 +0530957 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530958 }
959 else if (('B' == val) || ('b' == val))
960 {
c_hpothuebf89732014-02-25 13:00:24 +0530961 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530962 }
963 else
964 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800965 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
966 }
967
968 if (TRUE == lastArg)
969 {
970 goto done;
971 }
972 else if (NULL == inPtr)
973 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530974 return -EINVAL;
975 }
976 }
977
978 /*check and parse RTT*/
979 if ((strncmp(inPtr, "RTT", 3) == 0))
980 {
981 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800982 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530983 if (TRUE == lastArg)
984 {
985 goto done;
986 }
987 if (NULL == inPtr)
988 {
989 return -EINVAL;
990 }
991 }
992
993
994done:
995
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800996 pHddSetBatchScanReq->scanFrequency = nScanFreq;
997 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
998 pHddSetBatchScanReq->bestNetwork = nBestN;
999 pHddSetBatchScanReq->rfBand = ucRfBand;
1000 pHddSetBatchScanReq->rtt = nRtt;
1001
Rajeev79dbe4c2013-10-05 11:03:42 +05301002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1003 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1004 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1005 pHddSetBatchScanReq->scanFrequency,
1006 pHddSetBatchScanReq->numberOfScansToBatch,
1007 pHddSetBatchScanReq->bestNetwork,
1008 pHddSetBatchScanReq->rfBand,
1009 pHddSetBatchScanReq->rtt);
1010
1011 return 0;
1012}/*End of hdd_parse_set_batchscan_command*/
1013
1014/**---------------------------------------------------------------------------
1015
1016 \brief hdd_set_batch_scan_req_callback () - This function is called after
1017 receiving set batch scan response from FW and it saves set batch scan
1018 response data FW to HDD context and sets the completion event on
1019 which hdd_ioctl is waiting
1020
1021 \param - callbackContext Pointer to HDD adapter
1022 \param - pRsp Pointer to set batch scan response data received from FW
1023
1024 \return - nothing
1025
1026 --------------------------------------------------------------------------*/
1027static void hdd_set_batch_scan_req_callback
1028(
1029 void *callbackContext,
1030 tSirSetBatchScanRsp *pRsp
1031)
1032{
1033 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1034 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1035
1036 /*sanity check*/
1037 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1038 {
1039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1040 "%s: Invalid pAdapter magic", __func__);
1041 VOS_ASSERT(0);
1042 return;
1043 }
1044 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1045
1046 /*save set batch scan response*/
1047 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1048
1049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1050 "Received set batch scan rsp from FW with nScansToBatch=%d",
1051 pHddSetBatchScanRsp->nScansToBatch);
1052
1053 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1054 complete(&pAdapter->hdd_set_batch_scan_req_var);
1055
1056 return;
1057}/*End of hdd_set_batch_scan_req_callback*/
1058
1059
1060/**---------------------------------------------------------------------------
1061
1062 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1063 info in hdd batch scan response queue
1064
1065 \param - pAdapter Pointer to hdd adapter
1066 \param - pAPMetaInfo Pointer to access point meta info
1067 \param - scanId scan ID of batch scan response
1068 \param - isLastAp tells whether AP is last AP in batch scan response or not
1069
1070 \return - nothing
1071
1072 --------------------------------------------------------------------------*/
1073static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1074 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1075{
1076 tHddBatchScanRsp *pHead;
1077 tHddBatchScanRsp *pNode;
1078 tHddBatchScanRsp *pPrev;
1079 tHddBatchScanRsp *pTemp;
1080 tANI_U8 ssidLen;
1081
1082 /*head of hdd batch scan response queue*/
1083 pHead = pAdapter->pBatchScanRsp;
1084
1085 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1086 if (NULL == pNode)
1087 {
1088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1089 "%s: Could not allocate memory", __func__);
1090 VOS_ASSERT(0);
1091 return;
1092 }
1093
1094 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1095 sizeof(pNode->ApInfo.bssid));
1096 ssidLen = strlen(pApMetaInfo->ssid);
1097 if (SIR_MAX_SSID_SIZE < ssidLen)
1098 {
1099 /*invalid scan result*/
1100 vos_mem_free(pNode);
1101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1102 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1103 return;
1104 }
1105 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1106 /*null terminate ssid*/
1107 pNode->ApInfo.ssid[ssidLen] = '\0';
1108 pNode->ApInfo.ch = pApMetaInfo->ch;
1109 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1110 pNode->ApInfo.age = pApMetaInfo->timestamp;
1111 pNode->ApInfo.batchId = scanId;
1112 pNode->ApInfo.isLastAp = isLastAp;
1113
1114 pNode->pNext = NULL;
1115 if (NULL == pHead)
1116 {
1117 pAdapter->pBatchScanRsp = pNode;
1118 }
1119 else
1120 {
1121 pTemp = pHead;
1122 while (NULL != pTemp)
1123 {
1124 pPrev = pTemp;
1125 pTemp = pTemp->pNext;
1126 }
1127 pPrev->pNext = pNode;
1128 }
1129
1130 return;
1131}/*End of hdd_populate_batch_scan_rsp_queue*/
1132
1133/**---------------------------------------------------------------------------
1134
1135 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1136 receiving batch scan response indication from FW. It saves get batch scan
1137 response data in HDD batch scan response queue. This callback sets the
1138 completion event on which hdd_ioctl is waiting only after getting complete
1139 batch scan response data from FW
1140
1141 \param - callbackContext Pointer to HDD adapter
1142 \param - pRsp Pointer to get batch scan response data received from FW
1143
1144 \return - nothing
1145
1146 --------------------------------------------------------------------------*/
1147static void hdd_batch_scan_result_ind_callback
1148(
1149 void *callbackContext,
1150 void *pRsp
1151)
1152{
1153 v_BOOL_t isLastAp;
1154 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001155 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301156 tANI_U32 numberScanList;
1157 tANI_U32 nextScanListOffset;
1158 tANI_U32 nextApMetaInfoOffset;
1159 hdd_adapter_t* pAdapter;
1160 tpSirBatchScanList pScanList;
1161 tpSirBatchScanNetworkInfo pApMetaInfo;
1162 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1163 tSirSetBatchScanReq *pReq;
1164
1165 pAdapter = (hdd_adapter_t *)callbackContext;
1166 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001167 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301168 {
1169 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1170 "%s: Invalid pAdapter magic", __func__);
1171 VOS_ASSERT(0);
1172 return;
1173 }
1174
1175 /*initialize locals*/
1176 pReq = &pAdapter->hddSetBatchScanReq;
1177 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1178 isLastAp = FALSE;
1179 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001180 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301181 numberScanList = 0;
1182 nextScanListOffset = 0;
1183 nextApMetaInfoOffset = 0;
1184 pScanList = NULL;
1185 pApMetaInfo = NULL;
1186
1187 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1188 {
1189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1190 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1191 isLastAp = TRUE;
1192 goto done;
1193 }
1194
1195 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1197 "Batch scan rsp: numberScalList %d", numberScanList);
1198
1199 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1200 {
1201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1202 "%s: numberScanList %d", __func__, numberScanList);
1203 isLastAp = TRUE;
1204 goto done;
1205 }
1206
1207 while (numberScanList)
1208 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001209 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301210 nextScanListOffset);
1211 if (NULL == pScanList)
1212 {
1213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1214 "%s: pScanList is %p", __func__, pScanList);
1215 isLastAp = TRUE;
1216 goto done;
1217 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001218 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001220 "Batch scan rsp: numApMetaInfo %d scanId %d",
1221 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301222
1223 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1224 {
1225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1226 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1227 isLastAp = TRUE;
1228 goto done;
1229 }
1230
Rajeev Kumarce651e42013-10-21 18:57:15 -07001231 /*Initialize next AP meta info offset for next scan list*/
1232 nextApMetaInfoOffset = 0;
1233
Rajeev79dbe4c2013-10-05 11:03:42 +05301234 while (numApMetaInfo)
1235 {
1236 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1237 nextApMetaInfoOffset);
1238 if (NULL == pApMetaInfo)
1239 {
1240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1241 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1242 isLastAp = TRUE;
1243 goto done;
1244 }
1245 /*calculate AP age*/
1246 pApMetaInfo->timestamp =
1247 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1248
1249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001250 "%s: bssId "MAC_ADDRESS_STR
1251 " ch %d rssi %d timestamp %d", __func__,
1252 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1253 pApMetaInfo->ch, pApMetaInfo->rssi,
1254 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301255
1256 /*mark last AP in batch scan response*/
1257 if ((TRUE == pBatchScanRsp->isLastResult) &&
1258 (1 == numberScanList) && (1 == numApMetaInfo))
1259 {
1260 isLastAp = TRUE;
1261 }
1262
1263 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1264 /*store batch scan repsonse in hdd queue*/
1265 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1266 pScanList->scanId, isLastAp);
1267 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1268
1269 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1270 numApMetaInfo--;
1271 }
1272
Rajeev Kumarce651e42013-10-21 18:57:15 -07001273 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1274 + (sizeof(tSirBatchScanNetworkInfo)
1275 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301276 numberScanList--;
1277 }
1278
1279done:
1280
1281 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1282 requested from hdd_ioctl*/
1283 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1284 (TRUE == isLastAp))
1285 {
1286 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1287 complete(&pAdapter->hdd_get_batch_scan_req_var);
1288 }
1289
1290 return;
1291}/*End of hdd_batch_scan_result_ind_callback*/
1292
1293/**---------------------------------------------------------------------------
1294
1295 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1296 response as per batch scan FR request format by putting proper markers
1297
1298 \param - pDest pointer to destination buffer
1299 \param - cur_len current length
1300 \param - tot_len total remaining size which can be written to user space
1301 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1302 \param - pAdapter Pointer to HDD adapter
1303
1304 \return - ret no of characters written
1305
1306 --------------------------------------------------------------------------*/
1307static tANI_U32
1308hdd_format_batch_scan_rsp
1309(
1310 tANI_U8 *pDest,
1311 tANI_U32 cur_len,
1312 tANI_U32 tot_len,
1313 tHddBatchScanRsp *pApMetaInfo,
1314 hdd_adapter_t* pAdapter
1315)
1316{
1317 tANI_U32 ret = 0;
1318 tANI_U32 rem_len = 0;
1319 tANI_U8 temp_len = 0;
1320 tANI_U8 temp_total_len = 0;
1321 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1322 tANI_U8 *pTemp = temp;
1323
1324 /*Batch scan reponse needs to be returned to user space in
1325 following format:
1326 "scancount=X\n" where X is the number of scans in current batch
1327 batch
1328 "trunc\n" optional present if current scan truncated
1329 "bssid=XX:XX:XX:XX:XX:XX\n"
1330 "ssid=XXXX\n"
1331 "freq=X\n" frequency in Mhz
1332 "level=XX\n"
1333 "age=X\n" ms
1334 "dist=X\n" cm (-1 if not available)
1335 "errror=X\n" (-1if not available)
1336 "====\n" (end of ap marker)
1337 "####\n" (end of scan marker)
1338 "----\n" (end of results)*/
1339 /*send scan result in above format to user space based on
1340 available length*/
1341 /*The GET response may have more data than the driver can return in its
1342 buffer. In that case the buffer should be filled to the nearest complete
1343 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1344 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1345 The final buffer should end with "----\n"*/
1346
1347 /*sanity*/
1348 if (cur_len > tot_len)
1349 {
1350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1351 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1352 return 0;
1353 }
1354 else
1355 {
1356 rem_len = (tot_len - cur_len);
1357 }
1358
1359 /*end scan marker*/
1360 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1361 {
1362 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1363 pTemp += temp_len;
1364 temp_total_len += temp_len;
1365 }
1366
1367 /*bssid*/
1368 temp_len = snprintf(pTemp, sizeof(temp),
1369 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1370 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1371 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1372 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1373 pTemp += temp_len;
1374 temp_total_len += temp_len;
1375
1376 /*ssid*/
1377 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1378 pApMetaInfo->ApInfo.ssid);
1379 pTemp += temp_len;
1380 temp_total_len += temp_len;
1381
1382 /*freq*/
1383 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001384 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301385 pTemp += temp_len;
1386 temp_total_len += temp_len;
1387
1388 /*level*/
1389 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1390 pApMetaInfo->ApInfo.rssi);
1391 pTemp += temp_len;
1392 temp_total_len += temp_len;
1393
1394 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001395 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301396 pApMetaInfo->ApInfo.age);
1397 pTemp += temp_len;
1398 temp_total_len += temp_len;
1399
1400 /*dist*/
1401 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1402 pTemp += temp_len;
1403 temp_total_len += temp_len;
1404
1405 /*error*/
1406 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1407 pTemp += temp_len;
1408 temp_total_len += temp_len;
1409
1410 /*end AP marker*/
1411 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1412 pTemp += temp_len;
1413 temp_total_len += temp_len;
1414
1415 /*last AP in batch scan response*/
1416 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1417 {
1418 /*end scan marker*/
1419 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1420 pTemp += temp_len;
1421 temp_total_len += temp_len;
1422
1423 /*end batch scan result marker*/
1424 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1425 pTemp += temp_len;
1426 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001427
Rajeev79dbe4c2013-10-05 11:03:42 +05301428 }
1429
1430 if (temp_total_len < rem_len)
1431 {
1432 ret = temp_total_len + 1;
1433 strlcpy(pDest, temp, ret);
1434 pAdapter->isTruncated = FALSE;
1435 }
1436 else
1437 {
1438 pAdapter->isTruncated = TRUE;
1439 if (rem_len >= strlen("%%%%"))
1440 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001441 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301442 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001443 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301444 {
1445 ret = 0;
1446 }
1447 }
1448
1449 return ret;
1450
1451}/*End of hdd_format_batch_scan_rsp*/
1452
1453/**---------------------------------------------------------------------------
1454
1455 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1456 buffer starting with head of hdd batch scan response queue
1457
1458 \param - pAdapter Pointer to HDD adapter
1459 \param - pDest Pointer to user data buffer
1460 \param - cur_len current offset in user buffer
1461 \param - rem_len remaining no of bytes in user buffer
1462
1463 \return - number of bytes written in user buffer
1464
1465 --------------------------------------------------------------------------*/
1466
1467tANI_U32 hdd_populate_user_batch_scan_rsp
1468(
1469 hdd_adapter_t* pAdapter,
1470 tANI_U8 *pDest,
1471 tANI_U32 cur_len,
1472 tANI_U32 rem_len
1473)
1474{
1475 tHddBatchScanRsp *pHead;
1476 tHddBatchScanRsp *pPrev;
1477 tANI_U32 len;
1478
Rajeev79dbe4c2013-10-05 11:03:42 +05301479 pAdapter->isTruncated = FALSE;
1480
1481 /*head of hdd batch scan response queue*/
1482 pHead = pAdapter->pBatchScanRsp;
1483 while (pHead)
1484 {
1485 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1486 pAdapter);
1487 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001488 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301489 cur_len += len;
1490 if(TRUE == pAdapter->isTruncated)
1491 {
1492 /*result is truncated return rest of scan rsp in next req*/
1493 cur_len = rem_len;
1494 break;
1495 }
1496 pPrev = pHead;
1497 pHead = pHead->pNext;
1498 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001499 if (TRUE == pPrev->ApInfo.isLastAp)
1500 {
1501 pAdapter->prev_batch_id = 0;
1502 }
1503 else
1504 {
1505 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1506 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301507 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001508 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301509 }
1510
1511 return cur_len;
1512}/*End of hdd_populate_user_batch_scan_rsp*/
1513
1514/**---------------------------------------------------------------------------
1515
1516 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1517 scan response data from HDD queue to user space
1518 It does following in detail:
1519 a) if HDD has enough data in its queue then it 1st copies data to user
1520 space and then send get batch scan indication message to FW. In this
1521 case it does not wait on any event and batch scan response data will
1522 be populated in HDD response queue in MC thread context after receiving
1523 indication from FW
1524 b) else send get batch scan indication message to FW and wait on an event
1525 which will be set once HDD receives complete batch scan response from
1526 FW and then this function returns batch scan response to user space
1527
1528 \param - pAdapter Pointer to HDD adapter
1529 \param - pPrivData Pointer to priv_data
1530
1531 \return - 0 for success -EFAULT for failure
1532
1533 --------------------------------------------------------------------------*/
1534
1535int hdd_return_batch_scan_rsp_to_user
1536(
1537 hdd_adapter_t* pAdapter,
1538 hdd_priv_data_t *pPrivData,
1539 tANI_U8 *command
1540)
1541{
1542 tANI_U8 *pDest;
1543 tANI_U32 count = 0;
1544 tANI_U32 len = 0;
1545 tANI_U32 cur_len = 0;
1546 tANI_U32 rem_len = 0;
1547 eHalStatus halStatus;
1548 unsigned long rc;
1549 tSirTriggerBatchScanResultInd *pReq;
1550
1551 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1552 pReq->param = 0;/*batch scan client*/
1553 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1554 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1555
1556 cur_len = pPrivData->used_len;
1557 if (pPrivData->total_len > pPrivData->used_len)
1558 {
1559 rem_len = pPrivData->total_len - pPrivData->used_len;
1560 }
1561 else
1562 {
1563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1564 "%s: Invalid user data buffer total_len %d used_len %d",
1565 __func__, pPrivData->total_len, pPrivData->used_len);
1566 return -EFAULT;
1567 }
1568
1569 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1570 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1571 cur_len, rem_len);
1572 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1573
1574 /*enough scan result available in cache to return to user space or
1575 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001576 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301577 {
1578 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1579 halStatus = sme_TriggerBatchScanResultInd(
1580 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1581 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1582 pAdapter);
1583 if ( eHAL_STATUS_SUCCESS == halStatus )
1584 {
1585 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1586 {
1587 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1588 rc = wait_for_completion_timeout(
1589 &pAdapter->hdd_get_batch_scan_req_var,
1590 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1591 if (0 == rc)
1592 {
1593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1594 "%s: Timeout waiting to fetch batch scan rsp from fw",
1595 __func__);
1596 return -EFAULT;
1597 }
1598 }
1599
1600 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001601 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301602 pDest += len;
1603 cur_len += len;
1604
1605 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1606 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1607 cur_len, rem_len);
1608 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1609
1610 count = 0;
1611 len = (len - pPrivData->used_len);
1612 pDest = (command + pPrivData->used_len);
1613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001614 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301615 while(count < len)
1616 {
1617 printk("%c", *(pDest + count));
1618 count++;
1619 }
1620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1621 "%s: copy %d data to user buffer", __func__, len);
1622 if (copy_to_user(pPrivData->buf, pDest, len))
1623 {
1624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1625 "%s: failed to copy data to user buffer", __func__);
1626 return -EFAULT;
1627 }
1628 }
1629 else
1630 {
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1632 "sme_GetBatchScanScan returned failure halStatus %d",
1633 halStatus);
1634 return -EINVAL;
1635 }
1636 }
1637 else
1638 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301639 count = 0;
1640 len = (len - pPrivData->used_len);
1641 pDest = (command + pPrivData->used_len);
1642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001643 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301644 while(count < len)
1645 {
1646 printk("%c", *(pDest + count));
1647 count++;
1648 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1650 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301651 if (copy_to_user(pPrivData->buf, pDest, len))
1652 {
1653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1654 "%s: failed to copy data to user buffer", __func__);
1655 return -EFAULT;
1656 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301657 }
1658
1659 return 0;
1660} /*End of hdd_return_batch_scan_rsp_to_user*/
1661
Rajeev Kumar8b373292014-01-08 20:36:55 -08001662
1663/**---------------------------------------------------------------------------
1664
1665 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1666 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1667 WLS_BATCHING VERSION
1668 WLS_BATCHING SET
1669 WLS_BATCHING GET
1670 WLS_BATCHING STOP
1671
1672 \param - pAdapter Pointer to HDD adapter
1673 \param - pPrivdata Pointer to priv_data
1674 \param - command Pointer to command
1675
1676 \return - 0 for success -EFAULT for failure
1677
1678 --------------------------------------------------------------------------*/
1679
1680int hdd_handle_batch_scan_ioctl
1681(
1682 hdd_adapter_t *pAdapter,
1683 hdd_priv_data_t *pPrivdata,
1684 tANI_U8 *command
1685)
1686{
1687 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001688 hdd_context_t *pHddCtx;
1689
1690 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1691 ret = wlan_hdd_validate_context(pHddCtx);
1692 if (ret)
1693 {
1694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1695 "%s: HDD context is not valid!", __func__);
1696 goto exit;
1697 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001698
1699 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1700 {
1701 char extra[32];
1702 tANI_U8 len = 0;
1703 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1704
1705 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1706 {
1707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1708 "%s: Batch scan feature is not supported by FW", __func__);
1709 ret = -EINVAL;
1710 goto exit;
1711 }
1712
1713 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1714 version);
1715 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1716 {
1717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1718 "%s: failed to copy data to user buffer", __func__);
1719 ret = -EFAULT;
1720 goto exit;
1721 }
1722 ret = HDD_BATCH_SCAN_VERSION;
1723 }
1724 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1725 {
1726 int status;
1727 tANI_U8 *value = (command + 16);
1728 eHalStatus halStatus;
1729 unsigned long rc;
1730 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1731 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1732
1733 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1734 {
1735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1736 "%s: Batch scan feature is not supported by FW", __func__);
1737 ret = -EINVAL;
1738 goto exit;
1739 }
1740
1741 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1742 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1743 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1744 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1745 {
1746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301747 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001748 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301749 hdd_device_modetoString(pAdapter->device_mode),
1750 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001751 ret = -EINVAL;
1752 goto exit;
1753 }
1754
1755 status = hdd_parse_set_batchscan_command(value, pReq);
1756 if (status)
1757 {
1758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1759 "Invalid WLS_BATCHING SET command");
1760 ret = -EINVAL;
1761 goto exit;
1762 }
1763
1764
1765 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1766 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1767 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1768 pAdapter);
1769
1770 if ( eHAL_STATUS_SUCCESS == halStatus )
1771 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301772 char extra[32];
1773 tANI_U8 len = 0;
1774 tANI_U8 mScan = 0;
1775
Rajeev Kumar8b373292014-01-08 20:36:55 -08001776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1777 "sme_SetBatchScanReq returned success halStatus %d",
1778 halStatus);
1779 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1780 {
1781 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1782 rc = wait_for_completion_timeout(
1783 &pAdapter->hdd_set_batch_scan_req_var,
1784 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1785 if (0 == rc)
1786 {
1787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1788 "%s: Timeout waiting for set batch scan to complete",
1789 __func__);
1790 ret = -EINVAL;
1791 goto exit;
1792 }
1793 }
1794 if ( !pRsp->nScansToBatch )
1795 {
1796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1797 "%s: Received set batch scan failure response from FW",
1798 __func__);
1799 ret = -EINVAL;
1800 goto exit;
1801 }
1802 /*As per the Batch Scan Framework API we should return the MIN of
1803 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301804 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001805
1806 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1807
1808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1809 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301810 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1811 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1812 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1813 {
1814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1815 "%s: failed to copy MSCAN value to user buffer", __func__);
1816 ret = -EFAULT;
1817 goto exit;
1818 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001819 }
1820 else
1821 {
1822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1823 "sme_SetBatchScanReq returned failure halStatus %d",
1824 halStatus);
1825 ret = -EINVAL;
1826 goto exit;
1827 }
1828 }
1829 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1830 {
1831 eHalStatus halStatus;
1832 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1833 pInd->param = 0;
1834
1835 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1836 {
1837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1838 "%s: Batch scan feature is not supported by FW", __func__);
1839 ret = -EINVAL;
1840 goto exit;
1841 }
1842
1843 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1844 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001846 "Batch scan is not yet enabled batch scan state %d",
1847 pAdapter->batchScanState);
1848 ret = -EINVAL;
1849 goto exit;
1850 }
1851
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001852 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1853 hdd_deinit_batch_scan(pAdapter);
1854 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1855
Rajeev Kumar8b373292014-01-08 20:36:55 -08001856 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1857
1858 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1859 pAdapter->sessionId);
1860 if ( eHAL_STATUS_SUCCESS == halStatus )
1861 {
1862 ret = 0;
1863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1864 "sme_StopBatchScanInd returned success halStatus %d",
1865 halStatus);
1866 }
1867 else
1868 {
1869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1870 "sme_StopBatchScanInd returned failure halStatus %d",
1871 halStatus);
1872 ret = -EINVAL;
1873 goto exit;
1874 }
1875 }
1876 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1877 {
1878 tANI_U32 remain_len;
1879
1880 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1881 {
1882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1883 "%s: Batch scan feature is not supported by FW", __func__);
1884 ret = -EINVAL;
1885 goto exit;
1886 }
1887
1888 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1889 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001891 "Batch scan is not yet enabled could not return results"
1892 "Batch Scan state %d",
1893 pAdapter->batchScanState);
1894 ret = -EINVAL;
1895 goto exit;
1896 }
1897
1898 pPrivdata->used_len = 16;
1899 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1900 if (remain_len < pPrivdata->total_len)
1901 {
1902 /*Clear previous batch scan response data if any*/
1903 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1904 }
1905 else
1906 {
1907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1908 "Invalid total length from user space can't fetch batch"
1909 " scan response total_len %d used_len %d remain len %d",
1910 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1911 ret = -EINVAL;
1912 goto exit;
1913 }
1914 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1915 }
1916
1917exit:
1918
1919 return ret;
1920}
1921
1922
Rajeev79dbe4c2013-10-05 11:03:42 +05301923#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1924
c_hpothu92367912014-05-01 15:18:17 +05301925static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1926{
c_hpothu39eb1e32014-06-26 16:31:50 +05301927 bcnMissRateContext_t *pCBCtx;
1928
1929 if (NULL == data)
1930 {
1931 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1932 return;
1933 }
c_hpothu92367912014-05-01 15:18:17 +05301934
1935 /* there is a race condition that exists between this callback
1936 function and the caller since the caller could time out either
1937 before or while this code is executing. we use a spinlock to
1938 serialize these actions */
1939 spin_lock(&hdd_context_lock);
1940
c_hpothu39eb1e32014-06-26 16:31:50 +05301941 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301942 gbcnMissRate = -1;
1943
c_hpothu39eb1e32014-06-26 16:31:50 +05301944 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301945 {
1946 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301947 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301948 spin_unlock(&hdd_context_lock);
1949 return ;
1950 }
1951
1952 if (VOS_STATUS_SUCCESS == status)
1953 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301954 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301955 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301956 else
1957 {
1958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1959 }
1960
c_hpothu92367912014-05-01 15:18:17 +05301961 complete(&(pCBCtx->completion));
1962 spin_unlock(&hdd_context_lock);
1963
1964 return;
1965}
1966
Abhishek Singh08aa7762014-12-16 13:59:03 +05301967void hdd_FWStatisCB( VOS_STATUS status,
1968 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301969{
1970 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301971 hdd_adapter_t *pAdapter;
1972
1973 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1974
Abhishek Singh08aa7762014-12-16 13:59:03 +05301975 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301976 {
1977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1978 return;
1979 }
1980 /* there is a race condition that exists between this callback
1981 function and the caller since the caller could time out either
1982 before or while this code is executing. we use a spinlock to
1983 serialize these actions */
1984 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301985 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301986 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1987 {
1988 hddLog(VOS_TRACE_LEVEL_ERROR,
1989 FL("invalid context magic: %08x"), fwStatsCtx->magic);
1990 spin_unlock(&hdd_context_lock);
1991 return;
1992 }
1993 pAdapter = fwStatsCtx->pAdapter;
1994 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1995 {
1996 hddLog(VOS_TRACE_LEVEL_ERROR,
1997 FL("pAdapter returned is NULL or invalid"));
1998 spin_unlock(&hdd_context_lock);
1999 return;
2000 }
2001 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302002 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302003 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302004 switch( fwStatsResult->type )
2005 {
2006 case FW_UBSP_STATS:
2007 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302008 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302009 hddLog(VOS_TRACE_LEVEL_INFO,
2010 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302011 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2012 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302013 }
2014 break;
2015 default:
2016 {
2017 hddLog(VOS_TRACE_LEVEL_ERROR,
2018 FL(" No handling for stats type %d"),fwStatsResult->type);
2019 }
2020 }
2021 }
2022 complete(&(fwStatsCtx->completion));
2023 spin_unlock(&hdd_context_lock);
2024 return;
2025}
2026
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302027static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2028{
2029 int ret = 0;
2030
2031 if (!pCfg || !command || !extra || !len)
2032 {
2033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2034 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2035 ret = -EINVAL;
2036 return ret;
2037 }
2038
2039 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2040 {
2041 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2042 (int)pCfg->nActiveMaxChnTime);
2043 return ret;
2044 }
2045 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2046 {
2047 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2048 (int)pCfg->nActiveMinChnTime);
2049 return ret;
2050 }
2051 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2052 {
2053 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2054 (int)pCfg->nPassiveMaxChnTime);
2055 return ret;
2056 }
2057 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2058 {
2059 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2060 (int)pCfg->nPassiveMinChnTime);
2061 return ret;
2062 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302063 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2064 {
2065 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2066 (int)pCfg->nActiveMaxChnTime);
2067 return ret;
2068 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302069 else
2070 {
2071 ret = -EINVAL;
2072 }
2073
2074 return ret;
2075}
2076
2077static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2078{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302079 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302080 hdd_config_t *pCfg;
2081 tANI_U8 *value = command;
2082 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302083 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302084
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302085 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2086 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302087 {
2088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2089 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2090 ret = -EINVAL;
2091 return ret;
2092 }
2093
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302094 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2095 sme_GetConfigParam(hHal, &smeConfig);
2096
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302097 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2098 {
2099 value = value + 24;
2100 temp = kstrtou32(value, 10, &val);
2101 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2102 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2103 {
2104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2105 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2106 ret = -EFAULT;
2107 return ret;
2108 }
2109 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302110 smeConfig.csrConfig.nActiveMaxChnTime = val;
2111 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302112 }
2113 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2114 {
2115 value = value + 24;
2116 temp = kstrtou32(value, 10, &val);
2117 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2118 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2119 {
2120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2121 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2122 ret = -EFAULT;
2123 return ret;
2124 }
2125 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302126 smeConfig.csrConfig.nActiveMinChnTime = val;
2127 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302128 }
2129 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2130 {
2131 value = value + 25;
2132 temp = kstrtou32(value, 10, &val);
2133 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2134 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2135 {
2136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2137 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2138 ret = -EFAULT;
2139 return ret;
2140 }
2141 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302142 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2143 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302144 }
2145 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2146 {
2147 value = value + 25;
2148 temp = kstrtou32(value, 10, &val);
2149 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2150 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2151 {
2152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2153 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2154 ret = -EFAULT;
2155 return ret;
2156 }
2157 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302158 smeConfig.csrConfig.nPassiveMinChnTime = val;
2159 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302160 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302161 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2162 {
2163 value = value + 13;
2164 temp = kstrtou32(value, 10, &val);
2165 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2166 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2167 {
2168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2169 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2170 ret = -EFAULT;
2171 return ret;
2172 }
2173 pCfg->nActiveMaxChnTime = val;
2174 smeConfig.csrConfig.nActiveMaxChnTime = val;
2175 sme_UpdateConfig(hHal, &smeConfig);
2176 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302177 else
2178 {
2179 ret = -EINVAL;
2180 }
2181
2182 return ret;
2183}
2184
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002185static int hdd_driver_command(hdd_adapter_t *pAdapter,
2186 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002187{
Jeff Johnson295189b2012-06-20 16:38:30 -07002188 hdd_priv_data_t priv_data;
2189 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302190 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2191 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002192 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302193 int status;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002194 /*
2195 * Note that valid pointers are provided by caller
2196 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002197
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002198 /* copy to local struct to avoid numerous changes to legacy code */
2199 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002200
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002201 if (priv_data.total_len <= 0 ||
2202 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002203 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002204 hddLog(VOS_TRACE_LEVEL_WARN,
2205 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2206 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002207 ret = -EINVAL;
2208 goto exit;
2209 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302210 status = wlan_hdd_validate_context(pHddCtx);
2211 if (0 != status)
2212 {
2213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2214 "%s: HDD context is not valid", __func__);
2215 return status;
2216 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002217 /* Allocate +1 for '\0' */
2218 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002219 if (!command)
2220 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002221 hddLog(VOS_TRACE_LEVEL_ERROR,
2222 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002223 ret = -ENOMEM;
2224 goto exit;
2225 }
2226
2227 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2228 {
2229 ret = -EFAULT;
2230 goto exit;
2231 }
2232
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002233 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002234 command[priv_data.total_len] = '\0';
2235
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002236 /* at one time the following block of code was conditional. braces
2237 * have been retained to avoid re-indenting the legacy code
2238 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002239 {
2240 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2241
2242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002243 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002244
2245 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2246 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302247 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2248 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2249 pAdapter->sessionId, (unsigned)
2250 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2251 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2252 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2253 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002254 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2255 sizeof(tSirMacAddr)))
2256 {
2257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002258 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002259 ret = -EFAULT;
2260 }
2261 }
Amar Singhal0974e402013-02-12 14:27:46 -08002262 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002263 {
Amar Singhal0974e402013-02-12 14:27:46 -08002264 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002265
Jeff Johnson295189b2012-06-20 16:38:30 -07002266 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002267
2268 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002269 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002271 "%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 -07002272 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002273 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302274 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302275 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002276 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002277 }
Kiet Lamf040f472013-11-20 21:15:23 +05302278 else if(strncmp(command, "SETWMMPS", 8) == 0)
2279 {
2280 tANI_U8 *ptr = command;
2281 ret = hdd_wmmps_helper(pAdapter, ptr);
2282 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302283
2284 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2285 {
2286 tANI_U8 *ptr = command;
2287 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2288 }
2289
Jeff Johnson32d95a32012-09-10 13:15:23 -07002290 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2291 {
2292 char *country_code;
2293
2294 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002295
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002296 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002297 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002298#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302299 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002300#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002301 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2302 (void *)(tSmeChangeCountryCallback)
2303 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302304 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002305 if (eHAL_STATUS_SUCCESS == ret)
2306 {
2307 ret = wait_for_completion_interruptible_timeout(
2308 &pAdapter->change_country_code,
2309 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2310 if (0 >= ret)
2311 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002312 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302313 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002314 }
2315 }
2316 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002317 {
2318 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002319 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002320 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002321 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002322
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002323 }
2324 /*
2325 command should be a string having format
2326 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2327 */
Amar Singhal0974e402013-02-12 14:27:46 -08002328 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002329 {
Amar Singhal0974e402013-02-12 14:27:46 -08002330 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002331
2332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002333 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002334
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002335 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002336 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002337 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2338 {
2339 int suspend = 0;
2340 tANI_U8 *ptr = (tANI_U8*)command + 15;
2341
2342 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302343 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2344 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2345 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002346 hdd_set_wlan_suspend_mode(suspend);
2347 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002348#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2349 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2350 {
2351 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002352 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002353 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2354 eHalStatus status = eHAL_STATUS_SUCCESS;
2355
2356 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2357 value = value + 15;
2358
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002359 /* Convert the value from ascii to integer */
2360 ret = kstrtos8(value, 10, &rssi);
2361 if (ret < 0)
2362 {
2363 /* If the input value is greater than max value of datatype, then also
2364 kstrtou8 fails */
2365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2366 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002367 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002368 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2369 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2370 ret = -EINVAL;
2371 goto exit;
2372 }
2373
Srinivas Girigowdade697412013-02-14 16:31:48 -08002374 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002375
Srinivas Girigowdade697412013-02-14 16:31:48 -08002376 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2377 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2378 {
2379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2380 "Neighbor lookup threshold value %d is out of range"
2381 " (Min: %d Max: %d)", lookUpThreshold,
2382 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2383 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2384 ret = -EINVAL;
2385 goto exit;
2386 }
2387
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302388 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2389 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2390 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2392 "%s: Received Command to Set Roam trigger"
2393 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2394
2395 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2396 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2397 if (eHAL_STATUS_SUCCESS != status)
2398 {
2399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2400 "%s: Failed to set roam trigger, try again", __func__);
2401 ret = -EPERM;
2402 goto exit;
2403 }
2404
2405 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302406 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002407 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2408 }
2409 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2410 {
2411 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2412 int rssi = (-1) * lookUpThreshold;
2413 char extra[32];
2414 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302415 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2416 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2417 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002418 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002419 if (copy_to_user(priv_data.buf, &extra, len + 1))
2420 {
2421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2422 "%s: failed to copy data to user buffer", __func__);
2423 ret = -EFAULT;
2424 goto exit;
2425 }
2426 }
2427 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2428 {
2429 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002430 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002431 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002432
Srinivas Girigowdade697412013-02-14 16:31:48 -08002433 /* input refresh period is in terms of seconds */
2434 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2435 value = value + 18;
2436 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002437 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002438 if (ret < 0)
2439 {
2440 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002441 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002443 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002444 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002445 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2446 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002447 ret = -EINVAL;
2448 goto exit;
2449 }
2450
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002451 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2452 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002453 {
2454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002455 "Roam scan period value %d is out of range"
2456 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002457 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2458 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002459 ret = -EINVAL;
2460 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302461 }
2462 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2463 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2464 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002465 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002466
2467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2468 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002469 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002470
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002471 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2472 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002473 }
2474 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2475 {
2476 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2477 char extra[32];
2478 tANI_U8 len = 0;
2479
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302480 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2481 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2482 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002483 len = scnprintf(extra, sizeof(extra), "%s %d",
2484 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002485 /* Returned value is in units of seconds */
2486 if (copy_to_user(priv_data.buf, &extra, len + 1))
2487 {
2488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2489 "%s: failed to copy data to user buffer", __func__);
2490 ret = -EFAULT;
2491 goto exit;
2492 }
2493 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002494 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2495 {
2496 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002497 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002498 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002499
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002500 /* input refresh period is in terms of seconds */
2501 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2502 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002503
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002504 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002505 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002506 if (ret < 0)
2507 {
2508 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002509 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002511 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002512 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002513 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2514 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2515 ret = -EINVAL;
2516 goto exit;
2517 }
2518
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002519 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2520 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2521 {
2522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2523 "Neighbor scan results refresh period value %d is out of range"
2524 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2525 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2526 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2527 ret = -EINVAL;
2528 goto exit;
2529 }
2530 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2531
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2533 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002534 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002535
2536 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2537 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2538 }
2539 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2540 {
2541 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2542 char extra[32];
2543 tANI_U8 len = 0;
2544
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002545 len = scnprintf(extra, sizeof(extra), "%s %d",
2546 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002547 /* Returned value is in units of seconds */
2548 if (copy_to_user(priv_data.buf, &extra, len + 1))
2549 {
2550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2551 "%s: failed to copy data to user buffer", __func__);
2552 ret = -EFAULT;
2553 goto exit;
2554 }
2555 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002556#ifdef FEATURE_WLAN_LFR
2557 /* SETROAMMODE */
2558 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2559 {
2560 tANI_U8 *value = command;
2561 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2562
2563 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2564 value = value + SIZE_OF_SETROAMMODE + 1;
2565
2566 /* Convert the value from ascii to integer */
2567 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2568 if (ret < 0)
2569 {
2570 /* If the input value is greater than max value of datatype, then also
2571 kstrtou8 fails */
2572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2573 "%s: kstrtou8 failed range [%d - %d]", __func__,
2574 CFG_LFR_FEATURE_ENABLED_MIN,
2575 CFG_LFR_FEATURE_ENABLED_MAX);
2576 ret = -EINVAL;
2577 goto exit;
2578 }
2579 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2580 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2581 {
2582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2583 "Roam Mode value %d is out of range"
2584 " (Min: %d Max: %d)", roamMode,
2585 CFG_LFR_FEATURE_ENABLED_MIN,
2586 CFG_LFR_FEATURE_ENABLED_MAX);
2587 ret = -EINVAL;
2588 goto exit;
2589 }
2590
2591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2592 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2593 /*
2594 * Note that
2595 * SETROAMMODE 0 is to enable LFR while
2596 * SETROAMMODE 1 is to disable LFR, but
2597 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2598 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2599 */
2600 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2601 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2602 else
2603 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2604
2605 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2606 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2607 }
2608 /* GETROAMMODE */
2609 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2610 {
2611 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2612 char extra[32];
2613 tANI_U8 len = 0;
2614
2615 /*
2616 * roamMode value shall be inverted because the sementics is different.
2617 */
2618 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2619 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2620 else
2621 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2622
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002623 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002624 if (copy_to_user(priv_data.buf, &extra, len + 1))
2625 {
2626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2627 "%s: failed to copy data to user buffer", __func__);
2628 ret = -EFAULT;
2629 goto exit;
2630 }
2631 }
2632#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002633#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002634#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002635 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2636 {
2637 tANI_U8 *value = command;
2638 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2639
2640 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2641 value = value + 13;
2642 /* Convert the value from ascii to integer */
2643 ret = kstrtou8(value, 10, &roamRssiDiff);
2644 if (ret < 0)
2645 {
2646 /* If the input value is greater than max value of datatype, then also
2647 kstrtou8 fails */
2648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2649 "%s: kstrtou8 failed range [%d - %d]", __func__,
2650 CFG_ROAM_RSSI_DIFF_MIN,
2651 CFG_ROAM_RSSI_DIFF_MAX);
2652 ret = -EINVAL;
2653 goto exit;
2654 }
2655
2656 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2657 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2658 {
2659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2660 "Roam rssi diff value %d is out of range"
2661 " (Min: %d Max: %d)", roamRssiDiff,
2662 CFG_ROAM_RSSI_DIFF_MIN,
2663 CFG_ROAM_RSSI_DIFF_MAX);
2664 ret = -EINVAL;
2665 goto exit;
2666 }
2667
2668 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2669 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2670
2671 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2672 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2673 }
2674 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2675 {
2676 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2677 char extra[32];
2678 tANI_U8 len = 0;
2679
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302680 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2681 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2682 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002683 len = scnprintf(extra, sizeof(extra), "%s %d",
2684 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002685 if (copy_to_user(priv_data.buf, &extra, len + 1))
2686 {
2687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2688 "%s: failed to copy data to user buffer", __func__);
2689 ret = -EFAULT;
2690 goto exit;
2691 }
2692 }
2693#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002694#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002695 else if (strncmp(command, "GETBAND", 7) == 0)
2696 {
2697 int band = -1;
2698 char extra[32];
2699 tANI_U8 len = 0;
2700 hdd_getBand_helper(pHddCtx, &band);
2701
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302702 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2703 TRACE_CODE_HDD_GETBAND_IOCTL,
2704 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002705 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002706 if (copy_to_user(priv_data.buf, &extra, len + 1))
2707 {
2708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2709 "%s: failed to copy data to user buffer", __func__);
2710 ret = -EFAULT;
2711 goto exit;
2712 }
2713 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002714 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2715 {
2716 tANI_U8 *value = command;
2717 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2718 tANI_U8 numChannels = 0;
2719 eHalStatus status = eHAL_STATUS_SUCCESS;
2720
2721 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2722 if (eHAL_STATUS_SUCCESS != status)
2723 {
2724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2725 "%s: Failed to parse channel list information", __func__);
2726 ret = -EINVAL;
2727 goto exit;
2728 }
2729
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302730 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2731 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2732 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002733 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2734 {
2735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2736 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2737 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2738 ret = -EINVAL;
2739 goto exit;
2740 }
2741 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2742 numChannels);
2743 if (eHAL_STATUS_SUCCESS != status)
2744 {
2745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2746 "%s: Failed to update channel list information", __func__);
2747 ret = -EINVAL;
2748 goto exit;
2749 }
2750 }
2751 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2752 {
2753 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2754 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002755 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002756 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002757 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002758
2759 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2760 ChannelList, &numChannels ))
2761 {
2762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2763 "%s: failed to get roam scan channel list", __func__);
2764 ret = -EFAULT;
2765 goto exit;
2766 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302767 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2768 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2769 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002770 /* output channel list is of the format
2771 [Number of roam scan channels][Channel1][Channel2]... */
2772 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002773 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002774 for (j = 0; (j < numChannels); j++)
2775 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002776 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2777 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002778 }
2779
2780 if (copy_to_user(priv_data.buf, &extra, len + 1))
2781 {
2782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2783 "%s: failed to copy data to user buffer", __func__);
2784 ret = -EFAULT;
2785 goto exit;
2786 }
2787 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002788 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2789 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002790 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002791 char extra[32];
2792 tANI_U8 len = 0;
2793
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002794 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002795 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002796 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002797 hdd_is_okc_mode_enabled(pHddCtx) &&
2798 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2799 {
2800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002801 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002802 " hence this operation is not permitted!", __func__);
2803 ret = -EPERM;
2804 goto exit;
2805 }
2806
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002807 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002808 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002809 if (copy_to_user(priv_data.buf, &extra, len + 1))
2810 {
2811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2812 "%s: failed to copy data to user buffer", __func__);
2813 ret = -EFAULT;
2814 goto exit;
2815 }
2816 }
2817 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2818 {
2819 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2820 char extra[32];
2821 tANI_U8 len = 0;
2822
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002823 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002824 then this operation is not permitted (return FAILURE) */
2825 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002826 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002827 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2828 {
2829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002830 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002831 " hence this operation is not permitted!", __func__);
2832 ret = -EPERM;
2833 goto exit;
2834 }
2835
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002836 len = scnprintf(extra, sizeof(extra), "%s %d",
2837 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002838 if (copy_to_user(priv_data.buf, &extra, len + 1))
2839 {
2840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2841 "%s: failed to copy data to user buffer", __func__);
2842 ret = -EFAULT;
2843 goto exit;
2844 }
2845 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002846 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002847 {
2848 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2849 char extra[32];
2850 tANI_U8 len = 0;
2851
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002852 len = scnprintf(extra, sizeof(extra), "%s %d",
2853 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002854 if (copy_to_user(priv_data.buf, &extra, len + 1))
2855 {
2856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2857 "%s: failed to copy data to user buffer", __func__);
2858 ret = -EFAULT;
2859 goto exit;
2860 }
2861 }
2862 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2863 {
2864 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2865 char extra[32];
2866 tANI_U8 len = 0;
2867
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002868 len = scnprintf(extra, sizeof(extra), "%s %d",
2869 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002870 if (copy_to_user(priv_data.buf, &extra, len + 1))
2871 {
2872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2873 "%s: failed to copy data to user buffer", __func__);
2874 ret = -EFAULT;
2875 goto exit;
2876 }
2877 }
2878 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2879 {
2880 tANI_U8 *value = command;
2881 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2882
2883 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2884 value = value + 26;
2885 /* Convert the value from ascii to integer */
2886 ret = kstrtou8(value, 10, &minTime);
2887 if (ret < 0)
2888 {
2889 /* If the input value is greater than max value of datatype, then also
2890 kstrtou8 fails */
2891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2892 "%s: kstrtou8 failed range [%d - %d]", __func__,
2893 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2894 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2895 ret = -EINVAL;
2896 goto exit;
2897 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002898 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2899 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2900 {
2901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2902 "scan min channel time value %d is out of range"
2903 " (Min: %d Max: %d)", minTime,
2904 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2905 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2906 ret = -EINVAL;
2907 goto exit;
2908 }
2909
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302910 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2911 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2912 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2914 "%s: Received Command to change channel min time = %d", __func__, minTime);
2915
2916 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2917 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2918 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002919 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2920 {
2921 tANI_U8 *value = command;
2922 tANI_U8 channel = 0;
2923 tANI_U8 dwellTime = 0;
2924 tANI_U8 bufLen = 0;
2925 tANI_U8 *buf = NULL;
2926 tSirMacAddr targetApBssid;
2927 eHalStatus status = eHAL_STATUS_SUCCESS;
2928 struct ieee80211_channel chan;
2929 tANI_U8 finalLen = 0;
2930 tANI_U8 *finalBuf = NULL;
2931 tANI_U8 temp = 0;
2932 u64 cookie;
2933 hdd_station_ctx_t *pHddStaCtx = NULL;
2934 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2935
2936 /* if not associated, no need to send action frame */
2937 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2938 {
2939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2940 ret = -EINVAL;
2941 goto exit;
2942 }
2943
2944 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2945 &dwellTime, &buf, &bufLen);
2946 if (eHAL_STATUS_SUCCESS != status)
2947 {
2948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2949 "%s: Failed to parse send action frame data", __func__);
2950 ret = -EINVAL;
2951 goto exit;
2952 }
2953
2954 /* if the target bssid is different from currently associated AP,
2955 then no need to send action frame */
2956 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2957 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2958 {
2959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2960 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002961 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002962 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002963 goto exit;
2964 }
2965
2966 /* if the channel number is different from operating channel then
2967 no need to send action frame */
2968 if (channel != pHddStaCtx->conn_info.operationChannel)
2969 {
2970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2971 "%s: channel(%d) is different from operating channel(%d)",
2972 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2973 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002974 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002975 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002976 goto exit;
2977 }
2978 chan.center_freq = sme_ChnToFreq(channel);
2979
2980 finalLen = bufLen + 24;
2981 finalBuf = vos_mem_malloc(finalLen);
2982 if (NULL == finalBuf)
2983 {
2984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2985 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002986 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002987 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002988 goto exit;
2989 }
2990 vos_mem_zero(finalBuf, finalLen);
2991
2992 /* Fill subtype */
2993 temp = SIR_MAC_MGMT_ACTION << 4;
2994 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2995
2996 /* Fill type */
2997 temp = SIR_MAC_MGMT_FRAME;
2998 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2999
3000 /* Fill destination address (bssid of the AP) */
3001 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3002
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003003 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003004 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3005
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003006 /* Fill BSSID (AP mac address) */
3007 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003008
3009 /* Fill received buffer from 24th address */
3010 vos_mem_copy(finalBuf + 24, buf, bufLen);
3011
Jeff Johnson11c33152013-04-16 17:52:40 -07003012 /* done with the parsed buffer */
3013 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003014 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003015
DARAM SUDHA39eede62014-02-12 11:16:40 +05303016 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003017#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3018 &(pAdapter->wdev),
3019#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003020 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003021#endif
3022 &chan, 0,
3023#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3024 NL80211_CHAN_HT20, 1,
3025#endif
3026 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003027 1, &cookie );
3028 vos_mem_free(finalBuf);
3029 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003030 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3031 {
3032 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3033 char extra[32];
3034 tANI_U8 len = 0;
3035
3036 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003037 len = scnprintf(extra, sizeof(extra), "%s %d",
3038 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303039 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3040 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3041 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003042 if (copy_to_user(priv_data.buf, &extra, len + 1))
3043 {
3044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3045 "%s: failed to copy data to user buffer", __func__);
3046 ret = -EFAULT;
3047 goto exit;
3048 }
3049 }
3050 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3051 {
3052 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003053 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003054
3055 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3056 value = value + 19;
3057 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003058 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003059 if (ret < 0)
3060 {
3061 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003062 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003064 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003065 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3066 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3067 ret = -EINVAL;
3068 goto exit;
3069 }
3070
3071 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3072 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3073 {
3074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3075 "lfr mode value %d is out of range"
3076 " (Min: %d Max: %d)", maxTime,
3077 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3078 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3079 ret = -EINVAL;
3080 goto exit;
3081 }
3082
3083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3084 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3085
3086 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3087 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3088 }
3089 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3090 {
3091 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3092 char extra[32];
3093 tANI_U8 len = 0;
3094
3095 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003096 len = scnprintf(extra, sizeof(extra), "%s %d",
3097 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003098 if (copy_to_user(priv_data.buf, &extra, len + 1))
3099 {
3100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3101 "%s: failed to copy data to user buffer", __func__);
3102 ret = -EFAULT;
3103 goto exit;
3104 }
3105 }
3106 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3107 {
3108 tANI_U8 *value = command;
3109 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3110
3111 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3112 value = value + 16;
3113 /* Convert the value from ascii to integer */
3114 ret = kstrtou16(value, 10, &val);
3115 if (ret < 0)
3116 {
3117 /* If the input value is greater than max value of datatype, then also
3118 kstrtou16 fails */
3119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3120 "%s: kstrtou16 failed range [%d - %d]", __func__,
3121 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3122 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3123 ret = -EINVAL;
3124 goto exit;
3125 }
3126
3127 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3128 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3129 {
3130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3131 "scan home time value %d is out of range"
3132 " (Min: %d Max: %d)", val,
3133 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3134 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3135 ret = -EINVAL;
3136 goto exit;
3137 }
3138
3139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3140 "%s: Received Command to change scan home time = %d", __func__, val);
3141
3142 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3143 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3144 }
3145 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3146 {
3147 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3148 char extra[32];
3149 tANI_U8 len = 0;
3150
3151 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003152 len = scnprintf(extra, sizeof(extra), "%s %d",
3153 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003154 if (copy_to_user(priv_data.buf, &extra, len + 1))
3155 {
3156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3157 "%s: failed to copy data to user buffer", __func__);
3158 ret = -EFAULT;
3159 goto exit;
3160 }
3161 }
3162 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3163 {
3164 tANI_U8 *value = command;
3165 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3166
3167 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3168 value = value + 17;
3169 /* Convert the value from ascii to integer */
3170 ret = kstrtou8(value, 10, &val);
3171 if (ret < 0)
3172 {
3173 /* If the input value is greater than max value of datatype, then also
3174 kstrtou8 fails */
3175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3176 "%s: kstrtou8 failed range [%d - %d]", __func__,
3177 CFG_ROAM_INTRA_BAND_MIN,
3178 CFG_ROAM_INTRA_BAND_MAX);
3179 ret = -EINVAL;
3180 goto exit;
3181 }
3182
3183 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3184 (val > CFG_ROAM_INTRA_BAND_MAX))
3185 {
3186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3187 "intra band mode value %d is out of range"
3188 " (Min: %d Max: %d)", val,
3189 CFG_ROAM_INTRA_BAND_MIN,
3190 CFG_ROAM_INTRA_BAND_MAX);
3191 ret = -EINVAL;
3192 goto exit;
3193 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3195 "%s: Received Command to change intra band = %d", __func__, val);
3196
3197 pHddCtx->cfg_ini->nRoamIntraBand = val;
3198 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3199 }
3200 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3201 {
3202 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3203 char extra[32];
3204 tANI_U8 len = 0;
3205
3206 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003207 len = scnprintf(extra, sizeof(extra), "%s %d",
3208 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003209 if (copy_to_user(priv_data.buf, &extra, len + 1))
3210 {
3211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3212 "%s: failed to copy data to user buffer", __func__);
3213 ret = -EFAULT;
3214 goto exit;
3215 }
3216 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003217 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3218 {
3219 tANI_U8 *value = command;
3220 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3221
3222 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3223 value = value + 15;
3224 /* Convert the value from ascii to integer */
3225 ret = kstrtou8(value, 10, &nProbes);
3226 if (ret < 0)
3227 {
3228 /* If the input value is greater than max value of datatype, then also
3229 kstrtou8 fails */
3230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3231 "%s: kstrtou8 failed range [%d - %d]", __func__,
3232 CFG_ROAM_SCAN_N_PROBES_MIN,
3233 CFG_ROAM_SCAN_N_PROBES_MAX);
3234 ret = -EINVAL;
3235 goto exit;
3236 }
3237
3238 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3239 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3240 {
3241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3242 "NProbes value %d is out of range"
3243 " (Min: %d Max: %d)", nProbes,
3244 CFG_ROAM_SCAN_N_PROBES_MIN,
3245 CFG_ROAM_SCAN_N_PROBES_MAX);
3246 ret = -EINVAL;
3247 goto exit;
3248 }
3249
3250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3251 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3252
3253 pHddCtx->cfg_ini->nProbes = nProbes;
3254 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3255 }
3256 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3257 {
3258 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3259 char extra[32];
3260 tANI_U8 len = 0;
3261
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003262 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003263 if (copy_to_user(priv_data.buf, &extra, len + 1))
3264 {
3265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3266 "%s: failed to copy data to user buffer", __func__);
3267 ret = -EFAULT;
3268 goto exit;
3269 }
3270 }
3271 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3272 {
3273 tANI_U8 *value = command;
3274 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3275
3276 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3277 /* input value is in units of msec */
3278 value = value + 20;
3279 /* Convert the value from ascii to integer */
3280 ret = kstrtou16(value, 10, &homeAwayTime);
3281 if (ret < 0)
3282 {
3283 /* If the input value is greater than max value of datatype, then also
3284 kstrtou8 fails */
3285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3286 "%s: kstrtou8 failed range [%d - %d]", __func__,
3287 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3288 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3289 ret = -EINVAL;
3290 goto exit;
3291 }
3292
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003293 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3294 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3295 {
3296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3297 "homeAwayTime value %d is out of range"
3298 " (Min: %d Max: %d)", homeAwayTime,
3299 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3300 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3301 ret = -EINVAL;
3302 goto exit;
3303 }
3304
3305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3306 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003307 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3308 {
3309 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3310 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3311 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003312 }
3313 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3314 {
3315 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3316 char extra[32];
3317 tANI_U8 len = 0;
3318
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003319 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003320 if (copy_to_user(priv_data.buf, &extra, len + 1))
3321 {
3322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3323 "%s: failed to copy data to user buffer", __func__);
3324 ret = -EFAULT;
3325 goto exit;
3326 }
3327 }
3328 else if (strncmp(command, "REASSOC", 7) == 0)
3329 {
3330 tANI_U8 *value = command;
3331 tANI_U8 channel = 0;
3332 tSirMacAddr targetApBssid;
3333 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003334#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3335 tCsrHandoffRequest handoffInfo;
3336#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003337 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003338 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3339
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003340 /* if not associated, no need to proceed with reassoc */
3341 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3342 {
3343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3344 ret = -EINVAL;
3345 goto exit;
3346 }
3347
3348 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3349 if (eHAL_STATUS_SUCCESS != status)
3350 {
3351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3352 "%s: Failed to parse reassoc command data", __func__);
3353 ret = -EINVAL;
3354 goto exit;
3355 }
3356
3357 /* if the target bssid is same as currently associated AP,
3358 then no need to proceed with reassoc */
3359 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3360 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3361 {
3362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3363 ret = -EINVAL;
3364 goto exit;
3365 }
3366
3367 /* Check channel number is a valid channel number */
3368 if(VOS_STATUS_SUCCESS !=
3369 wlan_hdd_validate_operation_channel(pAdapter, channel))
3370 {
3371 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003372 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003373 return -EINVAL;
3374 }
3375
3376 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003377#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3378 handoffInfo.channel = channel;
3379 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3380 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3381#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003382 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003383 else if (strncmp(command, "SETWESMODE", 10) == 0)
3384 {
3385 tANI_U8 *value = command;
3386 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3387
3388 /* Move pointer to ahead of SETWESMODE<delimiter> */
3389 value = value + 11;
3390 /* Convert the value from ascii to integer */
3391 ret = kstrtou8(value, 10, &wesMode);
3392 if (ret < 0)
3393 {
3394 /* If the input value is greater than max value of datatype, then also
3395 kstrtou8 fails */
3396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3397 "%s: kstrtou8 failed range [%d - %d]", __func__,
3398 CFG_ENABLE_WES_MODE_NAME_MIN,
3399 CFG_ENABLE_WES_MODE_NAME_MAX);
3400 ret = -EINVAL;
3401 goto exit;
3402 }
3403
3404 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3405 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3406 {
3407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3408 "WES Mode value %d is out of range"
3409 " (Min: %d Max: %d)", wesMode,
3410 CFG_ENABLE_WES_MODE_NAME_MIN,
3411 CFG_ENABLE_WES_MODE_NAME_MAX);
3412 ret = -EINVAL;
3413 goto exit;
3414 }
3415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3416 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3417
3418 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3419 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3420 }
3421 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3422 {
3423 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3424 char extra[32];
3425 tANI_U8 len = 0;
3426
Arif Hussain826d9412013-11-12 16:44:54 -08003427 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003428 if (copy_to_user(priv_data.buf, &extra, len + 1))
3429 {
3430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3431 "%s: failed to copy data to user buffer", __func__);
3432 ret = -EFAULT;
3433 goto exit;
3434 }
3435 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003436#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003437#ifdef FEATURE_WLAN_LFR
3438 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3439 {
3440 tANI_U8 *value = command;
3441 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3442
3443 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3444 value = value + 12;
3445 /* Convert the value from ascii to integer */
3446 ret = kstrtou8(value, 10, &lfrMode);
3447 if (ret < 0)
3448 {
3449 /* If the input value is greater than max value of datatype, then also
3450 kstrtou8 fails */
3451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3452 "%s: kstrtou8 failed range [%d - %d]", __func__,
3453 CFG_LFR_FEATURE_ENABLED_MIN,
3454 CFG_LFR_FEATURE_ENABLED_MAX);
3455 ret = -EINVAL;
3456 goto exit;
3457 }
3458
3459 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3460 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3461 {
3462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3463 "lfr mode value %d is out of range"
3464 " (Min: %d Max: %d)", lfrMode,
3465 CFG_LFR_FEATURE_ENABLED_MIN,
3466 CFG_LFR_FEATURE_ENABLED_MAX);
3467 ret = -EINVAL;
3468 goto exit;
3469 }
3470
3471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3472 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3473
3474 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3475 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3476 }
3477#endif
3478#ifdef WLAN_FEATURE_VOWIFI_11R
3479 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3480 {
3481 tANI_U8 *value = command;
3482 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3483
3484 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3485 value = value + 18;
3486 /* Convert the value from ascii to integer */
3487 ret = kstrtou8(value, 10, &ft);
3488 if (ret < 0)
3489 {
3490 /* If the input value is greater than max value of datatype, then also
3491 kstrtou8 fails */
3492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3493 "%s: kstrtou8 failed range [%d - %d]", __func__,
3494 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3495 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3496 ret = -EINVAL;
3497 goto exit;
3498 }
3499
3500 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3501 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3502 {
3503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3504 "ft mode value %d is out of range"
3505 " (Min: %d Max: %d)", ft,
3506 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3507 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3508 ret = -EINVAL;
3509 goto exit;
3510 }
3511
3512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3513 "%s: Received Command to change ft mode = %d", __func__, ft);
3514
3515 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3516 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3517 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303518
3519 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3520 {
3521 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303522 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303523 tSirMacAddr targetApBssid;
3524 tANI_U8 trigger = 0;
3525 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303526 tHalHandle hHal;
3527 v_U32_t roamId = 0;
3528 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303529 hdd_station_ctx_t *pHddStaCtx = NULL;
3530 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303531 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303532
3533 /* if not associated, no need to proceed with reassoc */
3534 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3535 {
3536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3537 ret = -EINVAL;
3538 goto exit;
3539 }
3540
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303541 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303542 if (eHAL_STATUS_SUCCESS != status)
3543 {
3544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3545 "%s: Failed to parse reassoc command data", __func__);
3546 ret = -EINVAL;
3547 goto exit;
3548 }
3549
3550 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303551 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303552 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3553 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3554 {
3555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3556 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3557 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303558 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3559 &modProfileFields);
3560 sme_RoamReassoc(hHal, pAdapter->sessionId,
3561 NULL, modProfileFields, &roamId, 1);
3562 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303563 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303564
3565 /* Check channel number is a valid channel number */
3566 if(VOS_STATUS_SUCCESS !=
3567 wlan_hdd_validate_operation_channel(pAdapter, channel))
3568 {
3569 hddLog(VOS_TRACE_LEVEL_ERROR,
3570 "%s: Invalid Channel [%d]", __func__, channel);
3571 return -EINVAL;
3572 }
3573
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303574 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303575
3576 /* Proceed with scan/roam */
3577 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3578 &targetApBssid[0],
3579 (tSmeFastRoamTrigger)(trigger));
3580 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003581#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003582#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003583 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3584 {
3585 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003586 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003587
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003588 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003589 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003590 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003591 hdd_is_okc_mode_enabled(pHddCtx) &&
3592 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3593 {
3594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003595 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003596 " hence this operation is not permitted!", __func__);
3597 ret = -EPERM;
3598 goto exit;
3599 }
3600
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003601 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3602 value = value + 11;
3603 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003604 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003605 if (ret < 0)
3606 {
3607 /* If the input value is greater than max value of datatype, then also
3608 kstrtou8 fails */
3609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3610 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003611 CFG_ESE_FEATURE_ENABLED_MIN,
3612 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003613 ret = -EINVAL;
3614 goto exit;
3615 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003616 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3617 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003618 {
3619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003620 "Ese mode value %d is out of range"
3621 " (Min: %d Max: %d)", eseMode,
3622 CFG_ESE_FEATURE_ENABLED_MIN,
3623 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003624 ret = -EINVAL;
3625 goto exit;
3626 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003628 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003629
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003630 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3631 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003632 }
3633#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003634 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3635 {
3636 tANI_U8 *value = command;
3637 tANI_BOOLEAN roamScanControl = 0;
3638
3639 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3640 value = value + 19;
3641 /* Convert the value from ascii to integer */
3642 ret = kstrtou8(value, 10, &roamScanControl);
3643 if (ret < 0)
3644 {
3645 /* If the input value is greater than max value of datatype, then also
3646 kstrtou8 fails */
3647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3648 "%s: kstrtou8 failed ", __func__);
3649 ret = -EINVAL;
3650 goto exit;
3651 }
3652
3653 if (0 != roamScanControl)
3654 {
3655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3656 "roam scan control invalid value = %d",
3657 roamScanControl);
3658 ret = -EINVAL;
3659 goto exit;
3660 }
3661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3662 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3663
3664 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3665 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003666#ifdef FEATURE_WLAN_OKC
3667 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3668 {
3669 tANI_U8 *value = command;
3670 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3671
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003672 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003673 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003674 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003675 hdd_is_okc_mode_enabled(pHddCtx) &&
3676 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3677 {
3678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003679 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003680 " hence this operation is not permitted!", __func__);
3681 ret = -EPERM;
3682 goto exit;
3683 }
3684
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003685 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3686 value = value + 11;
3687 /* Convert the value from ascii to integer */
3688 ret = kstrtou8(value, 10, &okcMode);
3689 if (ret < 0)
3690 {
3691 /* If the input value is greater than max value of datatype, then also
3692 kstrtou8 fails */
3693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3694 "%s: kstrtou8 failed range [%d - %d]", __func__,
3695 CFG_OKC_FEATURE_ENABLED_MIN,
3696 CFG_OKC_FEATURE_ENABLED_MAX);
3697 ret = -EINVAL;
3698 goto exit;
3699 }
3700
3701 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3702 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3703 {
3704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3705 "Okc mode value %d is out of range"
3706 " (Min: %d Max: %d)", okcMode,
3707 CFG_OKC_FEATURE_ENABLED_MIN,
3708 CFG_OKC_FEATURE_ENABLED_MAX);
3709 ret = -EINVAL;
3710 goto exit;
3711 }
3712
3713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3714 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3715
3716 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3717 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003718#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003719 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3720 {
3721 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3722 char extra[32];
3723 tANI_U8 len = 0;
3724
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003725 len = scnprintf(extra, sizeof(extra), "%s %d",
3726 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003727 if (copy_to_user(priv_data.buf, &extra, len + 1))
3728 {
3729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3730 "%s: failed to copy data to user buffer", __func__);
3731 ret = -EFAULT;
3732 goto exit;
3733 }
3734 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303735#ifdef WLAN_FEATURE_PACKET_FILTERING
3736 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3737 {
3738 tANI_U8 filterType = 0;
3739 tANI_U8 *value = command;
3740
3741 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3742 value = value + 22;
3743
3744 /* Convert the value from ascii to integer */
3745 ret = kstrtou8(value, 10, &filterType);
3746 if (ret < 0)
3747 {
3748 /* If the input value is greater than max value of datatype,
3749 * then also kstrtou8 fails
3750 */
3751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3752 "%s: kstrtou8 failed range ", __func__);
3753 ret = -EINVAL;
3754 goto exit;
3755 }
3756
3757 if (filterType != 0 && filterType != 1)
3758 {
3759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3760 "%s: Accepted Values are 0 and 1 ", __func__);
3761 ret = -EINVAL;
3762 goto exit;
3763 }
3764 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3765 pAdapter->sessionId);
3766 }
3767#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303768 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3769 {
Kiet Lamad161252014-07-22 11:23:32 -07003770 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303771 int ret;
3772
Kiet Lamad161252014-07-22 11:23:32 -07003773 dhcpPhase = command + 11;
3774 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303775 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003777 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303778
3779 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003780
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303781 ret = wlan_hdd_scan_abort(pAdapter);
3782 if (ret < 0)
3783 {
3784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3785 FL("failed to abort existing scan %d"), ret);
3786 }
3787
Kiet Lamad161252014-07-22 11:23:32 -07003788 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3789 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303790 }
Kiet Lamad161252014-07-22 11:23:32 -07003791 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303792 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003794 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303795
3796 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003797
3798 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3799 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303800 }
3801 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003802 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3803 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3805 FL("making default scan to ACTIVE"));
3806 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003807 }
3808 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3809 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3811 FL("making default scan to PASSIVE"));
3812 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003813 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303814 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3815 {
3816 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3817 char extra[32];
3818 tANI_U8 len = 0;
3819
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303820 memset(extra, 0, sizeof(extra));
3821 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3822 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303823 {
3824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3825 "%s: failed to copy data to user buffer", __func__);
3826 ret = -EFAULT;
3827 goto exit;
3828 }
3829 ret = len;
3830 }
3831 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3832 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303833 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303834 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003835 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3836 {
3837 tANI_U8 filterType = 0;
3838 tANI_U8 *value;
3839 value = command + 9;
3840
3841 /* Convert the value from ascii to integer */
3842 ret = kstrtou8(value, 10, &filterType);
3843 if (ret < 0)
3844 {
3845 /* If the input value is greater than max value of datatype,
3846 * then also kstrtou8 fails
3847 */
3848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3849 "%s: kstrtou8 failed range ", __func__);
3850 ret = -EINVAL;
3851 goto exit;
3852 }
3853 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3854 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3855 {
3856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3857 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3858 " 2-Sink ", __func__);
3859 ret = -EINVAL;
3860 goto exit;
3861 }
3862 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3863 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303864 pScanInfo = &pHddCtx->scan_info;
3865 if (filterType && pScanInfo != NULL &&
3866 pHddCtx->scan_info.mScanPending)
3867 {
3868 /*Miracast Session started. Abort Scan */
3869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3870 "%s, Aborting Scan For Miracast",__func__);
3871 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3872 eCSR_SCAN_ABORT_DEFAULT);
3873 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003874 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303875 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003876 }
Leo Chang614d2072013-08-22 14:59:44 -07003877 else if (strncmp(command, "SETMCRATE", 9) == 0)
3878 {
Leo Chang614d2072013-08-22 14:59:44 -07003879 tANI_U8 *value = command;
3880 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003881 tSirRateUpdateInd *rateUpdate;
3882 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003883
3884 /* Only valid for SAP mode */
3885 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3886 {
3887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3888 "%s: SAP mode is not running", __func__);
3889 ret = -EFAULT;
3890 goto exit;
3891 }
3892
3893 /* Move pointer to ahead of SETMCRATE<delimiter> */
3894 /* input value is in units of hundred kbps */
3895 value = value + 10;
3896 /* Convert the value from ascii to integer, decimal base */
3897 ret = kstrtouint(value, 10, &targetRate);
3898
Leo Chang1f98cbd2013-10-17 15:03:52 -07003899 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3900 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003901 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003902 hddLog(VOS_TRACE_LEVEL_ERROR,
3903 "%s: SETMCRATE indication alloc fail", __func__);
3904 ret = -EFAULT;
3905 goto exit;
3906 }
3907 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3908
3909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3910 "MC Target rate %d", targetRate);
3911 /* Ignore unicast */
3912 rateUpdate->ucastDataRate = -1;
3913 rateUpdate->mcastDataRate24GHz = targetRate;
3914 rateUpdate->mcastDataRate5GHz = targetRate;
3915 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3916 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3917 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3918 if (eHAL_STATUS_SUCCESS != status)
3919 {
3920 hddLog(VOS_TRACE_LEVEL_ERROR,
3921 "%s: SET_MC_RATE failed", __func__);
3922 vos_mem_free(rateUpdate);
3923 ret = -EFAULT;
3924 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003925 }
3926 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303927#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003928 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303929 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003930 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303931 }
3932#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003933#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003934 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3935 {
3936 tANI_U8 *value = command;
3937 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3938 tANI_U8 numChannels = 0;
3939 eHalStatus status = eHAL_STATUS_SUCCESS;
3940
3941 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3942 if (eHAL_STATUS_SUCCESS != status)
3943 {
3944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3945 "%s: Failed to parse channel list information", __func__);
3946 ret = -EINVAL;
3947 goto exit;
3948 }
3949
3950 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3951 {
3952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3953 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3954 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3955 ret = -EINVAL;
3956 goto exit;
3957 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003958 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003959 ChannelList,
3960 numChannels);
3961 if (eHAL_STATUS_SUCCESS != status)
3962 {
3963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3964 "%s: Failed to update channel list information", __func__);
3965 ret = -EINVAL;
3966 goto exit;
3967 }
3968 }
3969 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3970 {
3971 tANI_U8 *value = command;
3972 char extra[128] = {0};
3973 int len = 0;
3974 tANI_U8 tid = 0;
3975 hdd_station_ctx_t *pHddStaCtx = NULL;
3976 tAniTrafStrmMetrics tsmMetrics;
3977 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3978
3979 /* if not associated, return error */
3980 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3981 {
3982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3983 ret = -EINVAL;
3984 goto exit;
3985 }
3986
3987 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3988 value = value + 12;
3989 /* Convert the value from ascii to integer */
3990 ret = kstrtou8(value, 10, &tid);
3991 if (ret < 0)
3992 {
3993 /* If the input value is greater than max value of datatype, then also
3994 kstrtou8 fails */
3995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3996 "%s: kstrtou8 failed range [%d - %d]", __func__,
3997 TID_MIN_VALUE,
3998 TID_MAX_VALUE);
3999 ret = -EINVAL;
4000 goto exit;
4001 }
4002
4003 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4004 {
4005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4006 "tid value %d is out of range"
4007 " (Min: %d Max: %d)", tid,
4008 TID_MIN_VALUE,
4009 TID_MAX_VALUE);
4010 ret = -EINVAL;
4011 goto exit;
4012 }
4013
4014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4015 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4016
4017 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4018 {
4019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4020 "%s: failed to get tsm stats", __func__);
4021 ret = -EFAULT;
4022 goto exit;
4023 }
4024
4025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4026 "UplinkPktQueueDly(%d)\n"
4027 "UplinkPktQueueDlyHist[0](%d)\n"
4028 "UplinkPktQueueDlyHist[1](%d)\n"
4029 "UplinkPktQueueDlyHist[2](%d)\n"
4030 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304031 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004032 "UplinkPktLoss(%d)\n"
4033 "UplinkPktCount(%d)\n"
4034 "RoamingCount(%d)\n"
4035 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4036 tsmMetrics.UplinkPktQueueDlyHist[0],
4037 tsmMetrics.UplinkPktQueueDlyHist[1],
4038 tsmMetrics.UplinkPktQueueDlyHist[2],
4039 tsmMetrics.UplinkPktQueueDlyHist[3],
4040 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4041 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4042
4043 /* Output TSM stats is of the format
4044 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4045 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004046 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004047 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4048 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4049 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4050 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4051 tsmMetrics.RoamingDly);
4052
4053 if (copy_to_user(priv_data.buf, &extra, len + 1))
4054 {
4055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4056 "%s: failed to copy data to user buffer", __func__);
4057 ret = -EFAULT;
4058 goto exit;
4059 }
4060 }
4061 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4062 {
4063 tANI_U8 *value = command;
4064 tANI_U8 *cckmIe = NULL;
4065 tANI_U8 cckmIeLen = 0;
4066 eHalStatus status = eHAL_STATUS_SUCCESS;
4067
4068 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4069 if (eHAL_STATUS_SUCCESS != status)
4070 {
4071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4072 "%s: Failed to parse cckm ie data", __func__);
4073 ret = -EINVAL;
4074 goto exit;
4075 }
4076
4077 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4078 {
4079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4080 "%s: CCKM Ie input length is more than max[%d]", __func__,
4081 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004082 vos_mem_free(cckmIe);
4083 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004084 ret = -EINVAL;
4085 goto exit;
4086 }
4087 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004088 vos_mem_free(cckmIe);
4089 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004090 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004091 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4092 {
4093 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004094 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004095 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004096
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004097 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004098 if (eHAL_STATUS_SUCCESS != status)
4099 {
4100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004101 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004102 ret = -EINVAL;
4103 goto exit;
4104 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004105 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4106 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4107 hdd_indicateEseBcnReportNoResults (pAdapter,
4108 eseBcnReq.bcnReq[0].measurementToken,
4109 0x02, //BIT(1) set for measurement done
4110 0); // no BSS
4111 goto exit;
4112 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004113
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004114 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4115 if (eHAL_STATUS_SUCCESS != status)
4116 {
4117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4118 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4119 ret = -EINVAL;
4120 goto exit;
4121 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004122 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004123#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304124 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4125 {
4126 eHalStatus status;
4127 char buf[32], len;
4128 long waitRet;
4129 bcnMissRateContext_t getBcnMissRateCtx;
4130
4131 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4132
4133 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4134 {
4135 hddLog(VOS_TRACE_LEVEL_WARN,
4136 FL("GETBCNMISSRATE: STA is not in connected state"));
4137 ret = -1;
4138 goto exit;
4139 }
4140
4141 init_completion(&(getBcnMissRateCtx.completion));
4142 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4143
4144 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4145 pAdapter->sessionId,
4146 (void *)getBcnMissRateCB,
4147 (void *)(&getBcnMissRateCtx));
4148 if( eHAL_STATUS_SUCCESS != status)
4149 {
4150 hddLog(VOS_TRACE_LEVEL_INFO,
4151 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4152 ret = -EINVAL;
4153 goto exit;
4154 }
4155
4156 waitRet = wait_for_completion_interruptible_timeout
4157 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4158 if(waitRet <= 0)
4159 {
4160 hddLog(VOS_TRACE_LEVEL_ERROR,
4161 FL("failed to wait on bcnMissRateComp %d"), ret);
4162
4163 //Make magic number to zero so that callback is not called.
4164 spin_lock(&hdd_context_lock);
4165 getBcnMissRateCtx.magic = 0x0;
4166 spin_unlock(&hdd_context_lock);
4167 ret = -EINVAL;
4168 goto exit;
4169 }
4170
4171 hddLog(VOS_TRACE_LEVEL_INFO,
4172 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4173
4174 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4175 if (copy_to_user(priv_data.buf, &buf, len + 1))
4176 {
4177 hddLog(VOS_TRACE_LEVEL_ERROR,
4178 "%s: failed to copy data to user buffer", __func__);
4179 ret = -EFAULT;
4180 goto exit;
4181 }
4182 ret = len;
4183 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304184#ifdef FEATURE_WLAN_TDLS
4185 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4186 tANI_U8 *value = command;
4187 int set_value;
4188 /* Move pointer to ahead of TDLSOFFCH*/
4189 value += 26;
4190 sscanf(value, "%d", &set_value);
4191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4192 "%s: Tdls offchannel offset:%d",
4193 __func__, set_value);
4194 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4195 if (ret < 0)
4196 {
4197 ret = -EINVAL;
4198 goto exit;
4199 }
4200
4201 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4202 tANI_U8 *value = command;
4203 int set_value;
4204 /* Move pointer to ahead of tdlsoffchnmode*/
4205 value += 18;
4206 sscanf(value, "%d", &set_value);
4207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4208 "%s: Tdls offchannel mode:%d",
4209 __func__, set_value);
4210 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4211 if (ret < 0)
4212 {
4213 ret = -EINVAL;
4214 goto exit;
4215 }
4216 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4217 tANI_U8 *value = command;
4218 int set_value;
4219 /* Move pointer to ahead of TDLSOFFCH*/
4220 value += 14;
4221 sscanf(value, "%d", &set_value);
4222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4223 "%s: Tdls offchannel num: %d",
4224 __func__, set_value);
4225 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4226 if (ret < 0)
4227 {
4228 ret = -EINVAL;
4229 goto exit;
4230 }
4231 }
4232#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304233 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4234 {
4235 eHalStatus status;
4236 char *buf = NULL;
4237 char len;
4238 long waitRet;
4239 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304240 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304241 tANI_U8 *ptr = command;
4242 int stats = *(ptr + 11) - '0';
4243
4244 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4245 if (!IS_FEATURE_FW_STATS_ENABLE)
4246 {
4247 hddLog(VOS_TRACE_LEVEL_INFO,
4248 FL("Get Firmware stats feature not supported"));
4249 ret = -EINVAL;
4250 goto exit;
4251 }
4252
4253 if (FW_STATS_MAX <= stats || 0 >= stats)
4254 {
4255 hddLog(VOS_TRACE_LEVEL_INFO,
4256 FL(" stats %d not supported"),stats);
4257 ret = -EINVAL;
4258 goto exit;
4259 }
4260
4261 init_completion(&(fwStatsCtx.completion));
4262 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4263 fwStatsCtx.pAdapter = pAdapter;
4264 fwStatsRsp->type = 0;
4265 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304266 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304267 if (eHAL_STATUS_SUCCESS != status)
4268 {
4269 hddLog(VOS_TRACE_LEVEL_ERROR,
4270 FL(" fail to post WDA cmd status = %d"), status);
4271 ret = -EINVAL;
4272 goto exit;
4273 }
4274 waitRet = wait_for_completion_timeout
4275 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4276 if (waitRet <= 0)
4277 {
4278 hddLog(VOS_TRACE_LEVEL_ERROR,
4279 FL("failed to wait on GwtFwstats"));
4280 //Make magic number to zero so that callback is not executed.
4281 spin_lock(&hdd_context_lock);
4282 fwStatsCtx.magic = 0x0;
4283 spin_unlock(&hdd_context_lock);
4284 ret = -EINVAL;
4285 goto exit;
4286 }
4287 if (fwStatsRsp->type)
4288 {
4289 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4290 if (!buf)
4291 {
4292 hddLog(VOS_TRACE_LEVEL_ERROR,
4293 FL(" failed to allocate memory"));
4294 ret = -ENOMEM;
4295 goto exit;
4296 }
4297 switch( fwStatsRsp->type )
4298 {
4299 case FW_UBSP_STATS:
4300 {
4301 len = snprintf(buf, FW_STATE_RSP_LEN,
4302 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304303 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4304 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304305 }
4306 break;
4307 default:
4308 {
4309 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4310 ret = -EFAULT;
4311 kfree(buf);
4312 goto exit;
4313 }
4314 }
4315 if (copy_to_user(priv_data.buf, buf, len + 1))
4316 {
4317 hddLog(VOS_TRACE_LEVEL_ERROR,
4318 FL(" failed to copy data to user buffer"));
4319 ret = -EFAULT;
4320 kfree(buf);
4321 goto exit;
4322 }
4323 ret = len;
4324 kfree(buf);
4325 }
4326 else
4327 {
4328 hddLog(VOS_TRACE_LEVEL_ERROR,
4329 FL("failed to fetch the stats"));
4330 ret = -EFAULT;
4331 goto exit;
4332 }
4333
4334 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004335 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304336 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4337 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4338 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304339 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4340 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004341 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004342 }
4343exit:
4344 if (command)
4345 {
4346 kfree(command);
4347 }
4348 return ret;
4349}
4350
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004351#ifdef CONFIG_COMPAT
4352static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4353{
4354 struct {
4355 compat_uptr_t buf;
4356 int used_len;
4357 int total_len;
4358 } compat_priv_data;
4359 hdd_priv_data_t priv_data;
4360 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004361
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004362 /*
4363 * Note that pAdapter and ifr have already been verified by caller,
4364 * and HDD context has also been validated
4365 */
4366 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4367 sizeof(compat_priv_data))) {
4368 ret = -EFAULT;
4369 goto exit;
4370 }
4371 priv_data.buf = compat_ptr(compat_priv_data.buf);
4372 priv_data.used_len = compat_priv_data.used_len;
4373 priv_data.total_len = compat_priv_data.total_len;
4374 ret = hdd_driver_command(pAdapter, &priv_data);
4375 exit:
4376 return ret;
4377}
4378#else /* CONFIG_COMPAT */
4379static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4380{
4381 /* will never be invoked */
4382 return 0;
4383}
4384#endif /* CONFIG_COMPAT */
4385
4386static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4387{
4388 hdd_priv_data_t priv_data;
4389 int ret = 0;
4390
4391 /*
4392 * Note that pAdapter and ifr have already been verified by caller,
4393 * and HDD context has also been validated
4394 */
4395 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4396 ret = -EFAULT;
4397 } else {
4398 ret = hdd_driver_command(pAdapter, &priv_data);
4399 }
4400 return ret;
4401}
4402
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304403int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004404{
4405 hdd_adapter_t *pAdapter;
4406 hdd_context_t *pHddCtx;
4407 int ret;
4408
4409 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4410 if (NULL == pAdapter) {
4411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4412 "%s: HDD adapter context is Null", __func__);
4413 ret = -ENODEV;
4414 goto exit;
4415 }
4416 if (dev != pAdapter->dev) {
4417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4418 "%s: HDD adapter/dev inconsistency", __func__);
4419 ret = -ENODEV;
4420 goto exit;
4421 }
4422
4423 if ((!ifr) || (!ifr->ifr_data)) {
4424 ret = -EINVAL;
4425 goto exit;
4426 }
4427
4428 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4429 ret = wlan_hdd_validate_context(pHddCtx);
4430 if (ret) {
Mahesh A Saptasagar5b16d0a2014-11-03 17:55:29 +05304431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004432 "%s: invalid context", __func__);
4433 ret = -EBUSY;
4434 goto exit;
4435 }
4436
4437 switch (cmd) {
4438 case (SIOCDEVPRIVATE + 1):
4439 if (is_compat_task())
4440 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4441 else
4442 ret = hdd_driver_ioctl(pAdapter, ifr);
4443 break;
4444 default:
4445 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4446 __func__, cmd);
4447 ret = -EINVAL;
4448 break;
4449 }
4450 exit:
4451 return ret;
4452}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004453
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304454int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4455{
4456 int ret;
4457
4458 vos_ssr_protect(__func__);
4459 ret = __hdd_ioctl(dev, ifr, cmd);
4460 vos_ssr_unprotect(__func__);
4461
4462 return ret;
4463}
4464
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004465#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004466/**---------------------------------------------------------------------------
4467
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004468 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004469
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004470 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004471 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4472 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4473 <space>Scan Mode N<space>Meas Duration N
4474 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4475 then take N.
4476 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4477 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4478 This function does not take care of removing duplicate channels from the list
4479
4480 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004481 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004482
4483 \return - 0 for success non-zero for failure
4484
4485 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004486static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4487 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004488{
4489 tANI_U8 *inPtr = pValue;
4490 int tempInt = 0;
4491 int j = 0, i = 0, v = 0;
4492 char buf[32];
4493
4494 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4495 /*no argument after the command*/
4496 if (NULL == inPtr)
4497 {
4498 return -EINVAL;
4499 }
4500 /*no space after the command*/
4501 else if (SPACE_ASCII_VALUE != *inPtr)
4502 {
4503 return -EINVAL;
4504 }
4505
4506 /*removing empty spaces*/
4507 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4508
4509 /*no argument followed by spaces*/
4510 if ('\0' == *inPtr) return -EINVAL;
4511
4512 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004513 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004514 if (1 != v) return -EINVAL;
4515
4516 v = kstrtos32(buf, 10, &tempInt);
4517 if ( v < 0) return -EINVAL;
4518
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004519 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004520
4521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004522 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004523
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004524 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004525 {
4526 for (i = 0; i < 4; i++)
4527 {
4528 /*inPtr pointing to the beginning of first space after number of ie fields*/
4529 inPtr = strpbrk( inPtr, " " );
4530 /*no ie data after the number of ie fields argument*/
4531 if (NULL == inPtr) return -EINVAL;
4532
4533 /*removing empty space*/
4534 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4535
4536 /*no ie data after the number of ie fields argument and spaces*/
4537 if ( '\0' == *inPtr ) return -EINVAL;
4538
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004539 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004540 if (1 != v) return -EINVAL;
4541
4542 v = kstrtos32(buf, 10, &tempInt);
4543 if (v < 0) return -EINVAL;
4544
4545 switch (i)
4546 {
4547 case 0: /* Measurement token */
4548 if (tempInt <= 0)
4549 {
4550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4551 "Invalid Measurement Token(%d)", tempInt);
4552 return -EINVAL;
4553 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004554 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004555 break;
4556
4557 case 1: /* Channel number */
4558 if ((tempInt <= 0) ||
4559 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4560 {
4561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4562 "Invalid Channel Number(%d)", tempInt);
4563 return -EINVAL;
4564 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004565 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004566 break;
4567
4568 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004569 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004570 {
4571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4572 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4573 return -EINVAL;
4574 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004575 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004576 break;
4577
4578 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004579 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4580 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004581 {
4582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4583 "Invalid Measurement Duration(%d)", tempInt);
4584 return -EINVAL;
4585 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004586 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004587 break;
4588 }
4589 }
4590 }
4591
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004592 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004593 {
4594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304595 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004596 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597 pEseBcnReq->bcnReq[j].measurementToken,
4598 pEseBcnReq->bcnReq[j].channel,
4599 pEseBcnReq->bcnReq[j].scanMode,
4600 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004601 }
4602
4603 return VOS_STATUS_SUCCESS;
4604}
4605
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004606static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4607{
4608 struct statsContext *pStatsContext = NULL;
4609 hdd_adapter_t *pAdapter = NULL;
4610
4611 if (NULL == pContext)
4612 {
4613 hddLog(VOS_TRACE_LEVEL_ERROR,
4614 "%s: Bad param, pContext [%p]",
4615 __func__, pContext);
4616 return;
4617 }
4618
Jeff Johnson72a40512013-12-19 10:14:15 -08004619 /* there is a race condition that exists between this callback
4620 function and the caller since the caller could time out either
4621 before or while this code is executing. we use a spinlock to
4622 serialize these actions */
4623 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004624
4625 pStatsContext = pContext;
4626 pAdapter = pStatsContext->pAdapter;
4627 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4628 {
4629 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004630 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004631 hddLog(VOS_TRACE_LEVEL_WARN,
4632 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4633 __func__, pAdapter, pStatsContext->magic);
4634 return;
4635 }
4636
Jeff Johnson72a40512013-12-19 10:14:15 -08004637 /* context is valid so caller is still waiting */
4638
4639 /* paranoia: invalidate the magic */
4640 pStatsContext->magic = 0;
4641
4642 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004643 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4644 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4645 tsmMetrics.UplinkPktQueueDlyHist,
4646 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4647 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4648 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4649 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4650 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4651 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4652 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4653
Jeff Johnson72a40512013-12-19 10:14:15 -08004654 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004655 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004656
4657 /* serialization is complete */
4658 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004659}
4660
4661
4662
4663static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4664 tAniTrafStrmMetrics* pTsmMetrics)
4665{
4666 hdd_station_ctx_t *pHddStaCtx = NULL;
4667 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004668 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004669 long lrc;
4670 struct statsContext context;
4671 hdd_context_t *pHddCtx = NULL;
4672
4673 if (NULL == pAdapter)
4674 {
4675 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4676 return VOS_STATUS_E_FAULT;
4677 }
4678
4679 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4680 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4681
4682 /* we are connected prepare our callback context */
4683 init_completion(&context.completion);
4684 context.pAdapter = pAdapter;
4685 context.magic = STATS_CONTEXT_MAGIC;
4686
4687 /* query tsm stats */
4688 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4689 pHddStaCtx->conn_info.staId[ 0 ],
4690 pHddStaCtx->conn_info.bssId,
4691 &context, pHddCtx->pvosContext, tid);
4692
4693 if (eHAL_STATUS_SUCCESS != hstatus)
4694 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4696 __func__);
4697 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004698 }
4699 else
4700 {
4701 /* request was sent -- wait for the response */
4702 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4703 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004704 if (lrc <= 0)
4705 {
4706 hddLog(VOS_TRACE_LEVEL_ERROR,
4707 "%s: SME %s while retrieving statistics",
4708 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004709 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004710 }
4711 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004712
Jeff Johnson72a40512013-12-19 10:14:15 -08004713 /* either we never sent a request, we sent a request and received a
4714 response or we sent a request and timed out. if we never sent a
4715 request or if we sent a request and got a response, we want to
4716 clear the magic out of paranoia. if we timed out there is a
4717 race condition such that the callback function could be
4718 executing at the same time we are. of primary concern is if the
4719 callback function had already verified the "magic" but had not
4720 yet set the completion variable when a timeout occurred. we
4721 serialize these activities by invalidating the magic while
4722 holding a shared spinlock which will cause us to block if the
4723 callback is currently executing */
4724 spin_lock(&hdd_context_lock);
4725 context.magic = 0;
4726 spin_unlock(&hdd_context_lock);
4727
4728 if (VOS_STATUS_SUCCESS == vstatus)
4729 {
4730 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4731 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4732 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4733 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4734 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4735 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4736 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4737 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4738 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4739 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4740 }
4741 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004742}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004743#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004744
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004745#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004746void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4747{
4748 eCsrBand band = -1;
4749 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4750 switch (band)
4751 {
4752 case eCSR_BAND_ALL:
4753 *pBand = WLAN_HDD_UI_BAND_AUTO;
4754 break;
4755
4756 case eCSR_BAND_24:
4757 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4758 break;
4759
4760 case eCSR_BAND_5G:
4761 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4762 break;
4763
4764 default:
4765 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4766 *pBand = -1;
4767 break;
4768 }
4769}
4770
4771/**---------------------------------------------------------------------------
4772
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004773 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4774
4775 This function parses the send action frame data passed in the format
4776 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4777
Srinivas Girigowda56076852013-08-20 14:00:50 -07004778 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004779 \param - pTargetApBssid Pointer to target Ap bssid
4780 \param - pChannel Pointer to the Target AP channel
4781 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4782 \param - pBuf Pointer to data
4783 \param - pBufLen Pointer to data length
4784
4785 \return - 0 for success non-zero for failure
4786
4787 --------------------------------------------------------------------------*/
4788VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4789 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4790{
4791 tANI_U8 *inPtr = pValue;
4792 tANI_U8 *dataEnd;
4793 int tempInt;
4794 int j = 0;
4795 int i = 0;
4796 int v = 0;
4797 tANI_U8 tempBuf[32];
4798 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004799 /* 12 hexa decimal digits, 5 ':' and '\0' */
4800 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004801
4802 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4803 /*no argument after the command*/
4804 if (NULL == inPtr)
4805 {
4806 return -EINVAL;
4807 }
4808
4809 /*no space after the command*/
4810 else if (SPACE_ASCII_VALUE != *inPtr)
4811 {
4812 return -EINVAL;
4813 }
4814
4815 /*removing empty spaces*/
4816 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4817
4818 /*no argument followed by spaces*/
4819 if ('\0' == *inPtr)
4820 {
4821 return -EINVAL;
4822 }
4823
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004824 v = sscanf(inPtr, "%17s", macAddress);
4825 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004826 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4828 "Invalid MAC address or All hex inputs are not read (%d)", v);
4829 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004830 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004831
4832 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4833 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4834 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4835 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4836 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4837 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004838
4839 /* point to the next argument */
4840 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4841 /*no argument after the command*/
4842 if (NULL == inPtr) return -EINVAL;
4843
4844 /*removing empty spaces*/
4845 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4846
4847 /*no argument followed by spaces*/
4848 if ('\0' == *inPtr)
4849 {
4850 return -EINVAL;
4851 }
4852
4853 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004854 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004855 if (1 != v) return -EINVAL;
4856
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004857 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304858 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304859 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004860
4861 *pChannel = tempInt;
4862
4863 /* point to the next argument */
4864 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4865 /*no argument after the command*/
4866 if (NULL == inPtr) return -EINVAL;
4867 /*removing empty spaces*/
4868 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4869
4870 /*no argument followed by spaces*/
4871 if ('\0' == *inPtr)
4872 {
4873 return -EINVAL;
4874 }
4875
4876 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004877 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004878 if (1 != v) return -EINVAL;
4879
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004880 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004881 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004882
4883 *pDwellTime = tempInt;
4884
4885 /* point to the next argument */
4886 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4887 /*no argument after the command*/
4888 if (NULL == inPtr) return -EINVAL;
4889 /*removing empty spaces*/
4890 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4891
4892 /*no argument followed by spaces*/
4893 if ('\0' == *inPtr)
4894 {
4895 return -EINVAL;
4896 }
4897
4898 /* find the length of data */
4899 dataEnd = inPtr;
4900 while(('\0' != *dataEnd) )
4901 {
4902 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004903 }
Kiet Lambe150c22013-11-21 16:30:32 +05304904 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004905 if ( *pBufLen <= 0) return -EINVAL;
4906
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004907 /* Allocate the number of bytes based on the number of input characters
4908 whether it is even or odd.
4909 if the number of input characters are even, then we need N/2 byte.
4910 if the number of input characters are odd, then we need do (N+1)/2 to
4911 compensate rounding off.
4912 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4913 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4914 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004915 if (NULL == *pBuf)
4916 {
4917 hddLog(VOS_TRACE_LEVEL_FATAL,
4918 "%s: vos_mem_alloc failed ", __func__);
4919 return -EINVAL;
4920 }
4921
4922 /* the buffer received from the upper layer is character buffer,
4923 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4924 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4925 and f0 in 3rd location */
4926 for (i = 0, j = 0; j < *pBufLen; j += 2)
4927 {
Kiet Lambe150c22013-11-21 16:30:32 +05304928 if( j+1 == *pBufLen)
4929 {
4930 tempByte = hdd_parse_hex(inPtr[j]);
4931 }
4932 else
4933 {
4934 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4935 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004936 (*pBuf)[i++] = tempByte;
4937 }
4938 *pBufLen = i;
4939 return VOS_STATUS_SUCCESS;
4940}
4941
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004942/**---------------------------------------------------------------------------
4943
Srinivas Girigowdade697412013-02-14 16:31:48 -08004944 \brief hdd_parse_channellist() - HDD Parse channel list
4945
4946 This function parses the channel list passed in the format
4947 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004948 if the Number of channels (N) does not match with the actual number of channels passed
4949 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4950 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4951 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4952 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004953
4954 \param - pValue Pointer to input channel list
4955 \param - ChannelList Pointer to local output array to record channel list
4956 \param - pNumChannels Pointer to number of roam scan channels
4957
4958 \return - 0 for success non-zero for failure
4959
4960 --------------------------------------------------------------------------*/
4961VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4962{
4963 tANI_U8 *inPtr = pValue;
4964 int tempInt;
4965 int j = 0;
4966 int v = 0;
4967 char buf[32];
4968
4969 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4970 /*no argument after the command*/
4971 if (NULL == inPtr)
4972 {
4973 return -EINVAL;
4974 }
4975
4976 /*no space after the command*/
4977 else if (SPACE_ASCII_VALUE != *inPtr)
4978 {
4979 return -EINVAL;
4980 }
4981
4982 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004983 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004984
4985 /*no argument followed by spaces*/
4986 if ('\0' == *inPtr)
4987 {
4988 return -EINVAL;
4989 }
4990
4991 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004992 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004993 if (1 != v) return -EINVAL;
4994
Srinivas Girigowdade697412013-02-14 16:31:48 -08004995 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004996 if ((v < 0) ||
4997 (tempInt <= 0) ||
4998 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4999 {
5000 return -EINVAL;
5001 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005002
5003 *pNumChannels = tempInt;
5004
5005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5006 "Number of channels are: %d", *pNumChannels);
5007
5008 for (j = 0; j < (*pNumChannels); j++)
5009 {
5010 /*inPtr pointing to the beginning of first space after number of channels*/
5011 inPtr = strpbrk( inPtr, " " );
5012 /*no channel list after the number of channels argument*/
5013 if (NULL == inPtr)
5014 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005015 if (0 != j)
5016 {
5017 *pNumChannels = j;
5018 return VOS_STATUS_SUCCESS;
5019 }
5020 else
5021 {
5022 return -EINVAL;
5023 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005024 }
5025
5026 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005027 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005028
5029 /*no channel list after the number of channels argument and spaces*/
5030 if ( '\0' == *inPtr )
5031 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005032 if (0 != j)
5033 {
5034 *pNumChannels = j;
5035 return VOS_STATUS_SUCCESS;
5036 }
5037 else
5038 {
5039 return -EINVAL;
5040 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005041 }
5042
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005043 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005044 if (1 != v) return -EINVAL;
5045
Srinivas Girigowdade697412013-02-14 16:31:48 -08005046 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005047 if ((v < 0) ||
5048 (tempInt <= 0) ||
5049 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5050 {
5051 return -EINVAL;
5052 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005053 pChannelList[j] = tempInt;
5054
5055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5056 "Channel %d added to preferred channel list",
5057 pChannelList[j] );
5058 }
5059
Srinivas Girigowdade697412013-02-14 16:31:48 -08005060 return VOS_STATUS_SUCCESS;
5061}
5062
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005063
5064/**---------------------------------------------------------------------------
5065
5066 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5067
5068 This function parses the reasoc command data passed in the format
5069 REASSOC<space><bssid><space><channel>
5070
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005071 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005072 \param - pTargetApBssid Pointer to target Ap bssid
5073 \param - pChannel Pointer to the Target AP channel
5074
5075 \return - 0 for success non-zero for failure
5076
5077 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005078VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5079 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005080{
5081 tANI_U8 *inPtr = pValue;
5082 int tempInt;
5083 int v = 0;
5084 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005085 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005086 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005087
5088 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5089 /*no argument after the command*/
5090 if (NULL == inPtr)
5091 {
5092 return -EINVAL;
5093 }
5094
5095 /*no space after the command*/
5096 else if (SPACE_ASCII_VALUE != *inPtr)
5097 {
5098 return -EINVAL;
5099 }
5100
5101 /*removing empty spaces*/
5102 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5103
5104 /*no argument followed by spaces*/
5105 if ('\0' == *inPtr)
5106 {
5107 return -EINVAL;
5108 }
5109
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005110 v = sscanf(inPtr, "%17s", macAddress);
5111 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005112 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5114 "Invalid MAC address or All hex inputs are not read (%d)", v);
5115 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005116 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005117
5118 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5119 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5120 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5121 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5122 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5123 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005124
5125 /* point to the next argument */
5126 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5127 /*no argument after the command*/
5128 if (NULL == inPtr) return -EINVAL;
5129
5130 /*removing empty spaces*/
5131 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5132
5133 /*no argument followed by spaces*/
5134 if ('\0' == *inPtr)
5135 {
5136 return -EINVAL;
5137 }
5138
5139 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005140 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005141 if (1 != v) return -EINVAL;
5142
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005143 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005144 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305145 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005146 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5147 {
5148 return -EINVAL;
5149 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005150
5151 *pChannel = tempInt;
5152 return VOS_STATUS_SUCCESS;
5153}
5154
5155#endif
5156
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005157#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005158/**---------------------------------------------------------------------------
5159
5160 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5161
5162 This function parses the SETCCKM IE command
5163 SETCCKMIE<space><ie data>
5164
5165 \param - pValue Pointer to input data
5166 \param - pCckmIe Pointer to output cckm Ie
5167 \param - pCckmIeLen Pointer to output cckm ie length
5168
5169 \return - 0 for success non-zero for failure
5170
5171 --------------------------------------------------------------------------*/
5172VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5173 tANI_U8 *pCckmIeLen)
5174{
5175 tANI_U8 *inPtr = pValue;
5176 tANI_U8 *dataEnd;
5177 int j = 0;
5178 int i = 0;
5179 tANI_U8 tempByte = 0;
5180
5181 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5182 /*no argument after the command*/
5183 if (NULL == inPtr)
5184 {
5185 return -EINVAL;
5186 }
5187
5188 /*no space after the command*/
5189 else if (SPACE_ASCII_VALUE != *inPtr)
5190 {
5191 return -EINVAL;
5192 }
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 /* find the length of data */
5204 dataEnd = inPtr;
5205 while(('\0' != *dataEnd) )
5206 {
5207 dataEnd++;
5208 ++(*pCckmIeLen);
5209 }
5210 if ( *pCckmIeLen <= 0) return -EINVAL;
5211
5212 /* Allocate the number of bytes based on the number of input characters
5213 whether it is even or odd.
5214 if the number of input characters are even, then we need N/2 byte.
5215 if the number of input characters are odd, then we need do (N+1)/2 to
5216 compensate rounding off.
5217 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5218 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5219 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5220 if (NULL == *pCckmIe)
5221 {
5222 hddLog(VOS_TRACE_LEVEL_FATAL,
5223 "%s: vos_mem_alloc failed ", __func__);
5224 return -EINVAL;
5225 }
5226 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5227 /* the buffer received from the upper layer is character buffer,
5228 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5229 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5230 and f0 in 3rd location */
5231 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5232 {
5233 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5234 (*pCckmIe)[i++] = tempByte;
5235 }
5236 *pCckmIeLen = i;
5237
5238 return VOS_STATUS_SUCCESS;
5239}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005240#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005241
Jeff Johnson295189b2012-06-20 16:38:30 -07005242/**---------------------------------------------------------------------------
5243
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005244 \brief hdd_is_valid_mac_address() - Validate MAC address
5245
5246 This function validates whether the given MAC address is valid or not
5247 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5248 where X is the hexa decimal digit character and separated by ':'
5249 This algorithm works even if MAC address is not separated by ':'
5250
5251 This code checks given input string mac contains exactly 12 hexadecimal digits.
5252 and a separator colon : appears in the input string only after
5253 an even number of hex digits.
5254
5255 \param - pMacAddr pointer to the input MAC address
5256 \return - 1 for valid and 0 for invalid
5257
5258 --------------------------------------------------------------------------*/
5259
5260v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5261{
5262 int xdigit = 0;
5263 int separator = 0;
5264 while (*pMacAddr)
5265 {
5266 if (isxdigit(*pMacAddr))
5267 {
5268 xdigit++;
5269 }
5270 else if (':' == *pMacAddr)
5271 {
5272 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5273 break;
5274
5275 ++separator;
5276 }
5277 else
5278 {
5279 separator = -1;
5280 /* Invalid MAC found */
5281 return 0;
5282 }
5283 ++pMacAddr;
5284 }
5285 return (xdigit == 12 && (separator == 5 || separator == 0));
5286}
5287
5288/**---------------------------------------------------------------------------
5289
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305290 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005291
5292 \param - dev Pointer to net_device structure
5293
5294 \return - 0 for success non-zero for failure
5295
5296 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305297int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005298{
5299 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5300 hdd_context_t *pHddCtx;
5301 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5302 VOS_STATUS status;
5303 v_BOOL_t in_standby = TRUE;
5304
5305 if (NULL == pAdapter)
5306 {
5307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305308 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 return -ENODEV;
5310 }
5311
5312 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305313 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5314 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005315 if (NULL == pHddCtx)
5316 {
5317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005318 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005319 return -ENODEV;
5320 }
5321
5322 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5323 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5324 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005325 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5326 {
5327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305328 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005329 in_standby = FALSE;
5330 break;
5331 }
5332 else
5333 {
5334 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5335 pAdapterNode = pNext;
5336 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 }
5338
5339 if (TRUE == in_standby)
5340 {
5341 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5342 {
5343 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5344 "wlan out of power save", __func__);
5345 return -EINVAL;
5346 }
5347 }
5348
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005349 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005350 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5351 {
5352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005353 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005354 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005356 netif_tx_start_all_queues(dev);
5357 }
5358
5359 return 0;
5360}
5361
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305362/**---------------------------------------------------------------------------
5363
5364 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5365
5366 This is called in response to ifconfig up
5367
5368 \param - dev Pointer to net_device structure
5369
5370 \return - 0 for success non-zero for failure
5371
5372 --------------------------------------------------------------------------*/
5373int hdd_open(struct net_device *dev)
5374{
5375 int ret;
5376
5377 vos_ssr_protect(__func__);
5378 ret = __hdd_open(dev);
5379 vos_ssr_unprotect(__func__);
5380
5381 return ret;
5382}
5383
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305384int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005385{
5386 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5387
5388 if(pAdapter == NULL) {
5389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005390 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005391 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 }
5393
5394 netif_start_queue(dev);
5395
5396 return 0;
5397}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305398
5399int hdd_mon_open (struct net_device *dev)
5400{
5401 int ret;
5402
5403 vos_ssr_protect(__func__);
5404 ret = __hdd_mon_open(dev);
5405 vos_ssr_unprotect(__func__);
5406
5407 return ret;
5408}
5409
Jeff Johnson295189b2012-06-20 16:38:30 -07005410/**---------------------------------------------------------------------------
5411
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305412 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005413
5414 \param - dev Pointer to net_device structure
5415
5416 \return - 0 for success non-zero for failure
5417
5418 --------------------------------------------------------------------------*/
5419
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305420int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005421{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305422 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5424 hdd_context_t *pHddCtx;
5425 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5426 VOS_STATUS status;
5427 v_BOOL_t enter_standby = TRUE;
5428
5429 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005430 if (NULL == pAdapter)
5431 {
5432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305433 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 return -ENODEV;
5435 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305436 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305437 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305438
5439 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5440 ret = wlan_hdd_validate_context(pHddCtx);
5441 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5444 "%s: HDD context is not valid!", __func__);
5445 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005446 }
5447
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305448 /* Nothing to be done if the interface is not opened */
5449 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5450 {
5451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5452 "%s: NETDEV Interface is not OPENED", __func__);
5453 return -ENODEV;
5454 }
5455
5456 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005457 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005458 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305459
5460 /* Disable TX on the interface, after this hard_start_xmit() will not
5461 * be called on that interface
5462 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005464 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305465
5466 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005467 netif_carrier_off(pAdapter->dev);
5468
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305469 /* The interface is marked as down for outside world (aka kernel)
5470 * But the driver is pretty much alive inside. The driver needs to
5471 * tear down the existing connection on the netdev (session)
5472 * cleanup the data pipes and wait until the control plane is stabilized
5473 * for this interface. The call also needs to wait until the above
5474 * mentioned actions are completed before returning to the caller.
5475 * Notice that the hdd_stop_adapter is requested not to close the session
5476 * That is intentional to be able to scan if it is a STA/P2P interface
5477 */
5478 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305479#ifdef FEATURE_WLAN_TDLS
5480 mutex_lock(&pHddCtx->tdls_lock);
5481#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305482 /* DeInit the adapter. This ensures datapath cleanup as well */
5483 hdd_deinit_adapter(pHddCtx, pAdapter);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305484#ifdef FEATURE_WLAN_TDLS
5485 mutex_unlock(&pHddCtx->tdls_lock);
5486#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005487 /* SoftAP ifaces should never go in power save mode
5488 making sure same here. */
5489 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5490 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005491 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005492 )
5493 {
5494 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305495 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5496 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005497 EXIT();
5498 return 0;
5499 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305500 /* Find if any iface is up. If any iface is up then can't put device to
5501 * sleep/power save mode
5502 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5504 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5505 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005506 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5507 {
5508 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305509 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005510 enter_standby = FALSE;
5511 break;
5512 }
5513 else
5514 {
5515 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5516 pAdapterNode = pNext;
5517 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 }
5519
5520 if (TRUE == enter_standby)
5521 {
5522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5523 "entering standby", __func__);
5524 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5525 {
5526 /*log and return success*/
5527 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5528 "wlan in power save", __func__);
5529 }
5530 }
5531
5532 EXIT();
5533 return 0;
5534}
5535
5536/**---------------------------------------------------------------------------
5537
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305538 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005539
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305540 This is called in response to ifconfig down
5541
5542 \param - dev Pointer to net_device structure
5543
5544 \return - 0 for success non-zero for failure
5545-----------------------------------------------------------------------------*/
5546int hdd_stop (struct net_device *dev)
5547{
5548 int ret;
5549
5550 vos_ssr_protect(__func__);
5551 ret = __hdd_stop(dev);
5552 vos_ssr_unprotect(__func__);
5553
5554 return ret;
5555}
5556
5557/**---------------------------------------------------------------------------
5558
5559 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005560
5561 \param - dev Pointer to net_device structure
5562
5563 \return - void
5564
5565 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305566static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005567{
5568 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305569 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 ENTER();
5571
5572 do
5573 {
5574 if (NULL == pAdapter)
5575 {
5576 hddLog(VOS_TRACE_LEVEL_FATAL,
5577 "%s: NULL pAdapter", __func__);
5578 break;
5579 }
5580
5581 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5582 {
5583 hddLog(VOS_TRACE_LEVEL_FATAL,
5584 "%s: Invalid magic", __func__);
5585 break;
5586 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305587 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5588 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005589 {
5590 hddLog(VOS_TRACE_LEVEL_FATAL,
5591 "%s: NULL pHddCtx", __func__);
5592 break;
5593 }
5594
5595 if (dev != pAdapter->dev)
5596 {
5597 hddLog(VOS_TRACE_LEVEL_FATAL,
5598 "%s: Invalid device reference", __func__);
5599 /* we haven't validated all cases so let this go for now */
5600 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305601#ifdef FEATURE_WLAN_TDLS
5602 mutex_lock(&pHddCtx->tdls_lock);
5603#endif
5604 hdd_deinit_adapter(pHddCtx, pAdapter);
5605#ifdef FEATURE_WLAN_TDLS
5606 mutex_unlock(&pHddCtx->tdls_lock);
5607#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005608
5609 /* after uninit our adapter structure will no longer be valid */
5610 pAdapter->dev = NULL;
5611 pAdapter->magic = 0;
5612 } while (0);
5613
5614 EXIT();
5615}
5616
5617/**---------------------------------------------------------------------------
5618
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305619 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5620
5621 This is called during the netdev unregister to uninitialize all data
5622associated with the device
5623
5624 \param - dev Pointer to net_device structure
5625
5626 \return - void
5627
5628 --------------------------------------------------------------------------*/
5629static void hdd_uninit (struct net_device *dev)
5630{
5631 vos_ssr_protect(__func__);
5632 __hdd_uninit(dev);
5633 vos_ssr_unprotect(__func__);
5634}
5635
5636/**---------------------------------------------------------------------------
5637
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 \brief hdd_release_firmware() -
5639
5640 This function calls the release firmware API to free the firmware buffer.
5641
5642 \param - pFileName Pointer to the File Name.
5643 pCtx - Pointer to the adapter .
5644
5645
5646 \return - 0 for success, non zero for failure
5647
5648 --------------------------------------------------------------------------*/
5649
5650VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5651{
5652 VOS_STATUS status = VOS_STATUS_SUCCESS;
5653 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5654 ENTER();
5655
5656
5657 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5658
5659 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5660
5661 if(pHddCtx->fw) {
5662 release_firmware(pHddCtx->fw);
5663 pHddCtx->fw = NULL;
5664 }
5665 else
5666 status = VOS_STATUS_E_FAILURE;
5667 }
5668 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5669 if(pHddCtx->nv) {
5670 release_firmware(pHddCtx->nv);
5671 pHddCtx->nv = NULL;
5672 }
5673 else
5674 status = VOS_STATUS_E_FAILURE;
5675
5676 }
5677
5678 EXIT();
5679 return status;
5680}
5681
5682/**---------------------------------------------------------------------------
5683
5684 \brief hdd_request_firmware() -
5685
5686 This function reads the firmware file using the request firmware
5687 API and returns the the firmware data and the firmware file size.
5688
5689 \param - pfileName - Pointer to the file name.
5690 - pCtx - Pointer to the adapter .
5691 - ppfw_data - Pointer to the pointer of the firmware data.
5692 - pSize - Pointer to the file size.
5693
5694 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5695
5696 --------------------------------------------------------------------------*/
5697
5698
5699VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5700{
5701 int status;
5702 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5703 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5704 ENTER();
5705
5706 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5707
5708 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5709
5710 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5711 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5712 __func__, pfileName);
5713 retval = VOS_STATUS_E_FAILURE;
5714 }
5715
5716 else {
5717 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5718 *pSize = pHddCtx->fw->size;
5719 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5720 __func__, *pSize);
5721 }
5722 }
5723 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5724
5725 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5726
5727 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5728 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5729 __func__, pfileName);
5730 retval = VOS_STATUS_E_FAILURE;
5731 }
5732
5733 else {
5734 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5735 *pSize = pHddCtx->nv->size;
5736 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5737 __func__, *pSize);
5738 }
5739 }
5740
5741 EXIT();
5742 return retval;
5743}
5744/**---------------------------------------------------------------------------
5745 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5746
5747 This is the function invoked by SME to inform the result of a full power
5748 request issued by HDD
5749
5750 \param - callbackcontext - Pointer to cookie
5751 status - result of request
5752
5753 \return - None
5754
5755--------------------------------------------------------------------------*/
5756void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5757{
5758 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5759
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005760 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005761 if(&pHddCtx->full_pwr_comp_var)
5762 {
5763 complete(&pHddCtx->full_pwr_comp_var);
5764 }
5765}
5766
5767/**---------------------------------------------------------------------------
5768
5769 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5770
5771 This is the function invoked by SME to inform the result of BMPS
5772 request issued by HDD
5773
5774 \param - callbackcontext - Pointer to cookie
5775 status - result of request
5776
5777 \return - None
5778
5779--------------------------------------------------------------------------*/
5780void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5781{
5782
5783 struct completion *completion_var = (struct completion*) callbackContext;
5784
Arif Hussain6d2a3322013-11-17 19:50:10 -08005785 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005786 if(completion_var != NULL)
5787 {
5788 complete(completion_var);
5789 }
5790}
5791
5792/**---------------------------------------------------------------------------
5793
5794 \brief hdd_get_cfg_file_size() -
5795
5796 This function reads the configuration file using the request firmware
5797 API and returns the configuration file size.
5798
5799 \param - pCtx - Pointer to the adapter .
5800 - pFileName - Pointer to the file name.
5801 - pBufSize - Pointer to the buffer size.
5802
5803 \return - 0 for success, non zero for failure
5804
5805 --------------------------------------------------------------------------*/
5806
5807VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5808{
5809 int status;
5810 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5811
5812 ENTER();
5813
5814 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5815
5816 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5817 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5818 status = VOS_STATUS_E_FAILURE;
5819 }
5820 else {
5821 *pBufSize = pHddCtx->fw->size;
5822 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5823 release_firmware(pHddCtx->fw);
5824 pHddCtx->fw = NULL;
5825 }
5826
5827 EXIT();
5828 return VOS_STATUS_SUCCESS;
5829}
5830
5831/**---------------------------------------------------------------------------
5832
5833 \brief hdd_read_cfg_file() -
5834
5835 This function reads the configuration file using the request firmware
5836 API and returns the cfg data and the buffer size of the configuration file.
5837
5838 \param - pCtx - Pointer to the adapter .
5839 - pFileName - Pointer to the file name.
5840 - pBuffer - Pointer to the data buffer.
5841 - pBufSize - Pointer to the buffer size.
5842
5843 \return - 0 for success, non zero for failure
5844
5845 --------------------------------------------------------------------------*/
5846
5847VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5848 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5849{
5850 int status;
5851 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5852
5853 ENTER();
5854
5855 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5856
5857 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5858 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5859 return VOS_STATUS_E_FAILURE;
5860 }
5861 else {
5862 if(*pBufSize != pHddCtx->fw->size) {
5863 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5864 "file size", __func__);
5865 release_firmware(pHddCtx->fw);
5866 pHddCtx->fw = NULL;
5867 return VOS_STATUS_E_FAILURE;
5868 }
5869 else {
5870 if(pBuffer) {
5871 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5872 }
5873 release_firmware(pHddCtx->fw);
5874 pHddCtx->fw = NULL;
5875 }
5876 }
5877
5878 EXIT();
5879
5880 return VOS_STATUS_SUCCESS;
5881}
5882
5883/**---------------------------------------------------------------------------
5884
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305885 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005886
5887 This function sets the user specified mac address using
5888 the command ifconfig wlanX hw ether <mac adress>.
5889
5890 \param - dev - Pointer to the net device.
5891 - addr - Pointer to the sockaddr.
5892 \return - 0 for success, non zero for failure
5893
5894 --------------------------------------------------------------------------*/
5895
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305896static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005897{
5898 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5899 struct sockaddr *psta_mac_addr = addr;
5900 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5901
5902 ENTER();
5903
5904 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5906
5907 EXIT();
5908 return halStatus;
5909}
5910
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305911/**---------------------------------------------------------------------------
5912
5913 \brief hdd_set_mac_address() -
5914
5915 Wrapper function to protect __hdd_set_mac_address() function from ssr
5916
5917 \param - dev - Pointer to the net device.
5918 - addr - Pointer to the sockaddr.
5919 \return - 0 for success, non zero for failure
5920
5921 --------------------------------------------------------------------------*/
5922static int hdd_set_mac_address(struct net_device *dev, void *addr)
5923{
5924 int ret;
5925
5926 vos_ssr_protect(__func__);
5927 ret = __hdd_set_mac_address(dev, addr);
5928 vos_ssr_unprotect(__func__);
5929
5930 return ret;
5931}
5932
Jeff Johnson295189b2012-06-20 16:38:30 -07005933tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5934{
5935 int i;
5936 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5937 {
Abhishek Singheb183782014-02-06 13:37:21 +05305938 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005939 break;
5940 }
5941
5942 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5943 return NULL;
5944
5945 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5946 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5947}
5948
5949void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5950{
5951 int i;
5952 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5953 {
5954 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5955 {
5956 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5957 break;
5958 }
5959 }
5960 return;
5961}
5962
5963#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5964 static struct net_device_ops wlan_drv_ops = {
5965 .ndo_open = hdd_open,
5966 .ndo_stop = hdd_stop,
5967 .ndo_uninit = hdd_uninit,
5968 .ndo_start_xmit = hdd_hard_start_xmit,
5969 .ndo_tx_timeout = hdd_tx_timeout,
5970 .ndo_get_stats = hdd_stats,
5971 .ndo_do_ioctl = hdd_ioctl,
5972 .ndo_set_mac_address = hdd_set_mac_address,
5973 .ndo_select_queue = hdd_select_queue,
5974#ifdef WLAN_FEATURE_PACKET_FILTERING
5975#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5976 .ndo_set_rx_mode = hdd_set_multicast_list,
5977#else
5978 .ndo_set_multicast_list = hdd_set_multicast_list,
5979#endif //LINUX_VERSION_CODE
5980#endif
5981 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 static struct net_device_ops wlan_mon_drv_ops = {
5983 .ndo_open = hdd_mon_open,
5984 .ndo_stop = hdd_stop,
5985 .ndo_uninit = hdd_uninit,
5986 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5987 .ndo_tx_timeout = hdd_tx_timeout,
5988 .ndo_get_stats = hdd_stats,
5989 .ndo_do_ioctl = hdd_ioctl,
5990 .ndo_set_mac_address = hdd_set_mac_address,
5991 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005992
5993#endif
5994
5995void hdd_set_station_ops( struct net_device *pWlanDev )
5996{
5997#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005998 pWlanDev->netdev_ops = &wlan_drv_ops;
5999#else
6000 pWlanDev->open = hdd_open;
6001 pWlanDev->stop = hdd_stop;
6002 pWlanDev->uninit = hdd_uninit;
6003 pWlanDev->hard_start_xmit = NULL;
6004 pWlanDev->tx_timeout = hdd_tx_timeout;
6005 pWlanDev->get_stats = hdd_stats;
6006 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 pWlanDev->set_mac_address = hdd_set_mac_address;
6008#endif
6009}
6010
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006011static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006012{
6013 struct net_device *pWlanDev = NULL;
6014 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 /*
6016 * cfg80211 initialization and registration....
6017 */
6018 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6019
Jeff Johnson295189b2012-06-20 16:38:30 -07006020 if(pWlanDev != NULL)
6021 {
6022
6023 //Save the pointer to the net_device in the HDD adapter
6024 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6025
Jeff Johnson295189b2012-06-20 16:38:30 -07006026 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6027
6028 pAdapter->dev = pWlanDev;
6029 pAdapter->pHddCtx = pHddCtx;
6030 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306031 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006032
6033 init_completion(&pAdapter->session_open_comp_var);
6034 init_completion(&pAdapter->session_close_comp_var);
6035 init_completion(&pAdapter->disconnect_comp_var);
6036 init_completion(&pAdapter->linkup_event_var);
6037 init_completion(&pAdapter->cancel_rem_on_chan_var);
6038 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306039 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006040#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6041 init_completion(&pAdapter->offchannel_tx_event);
6042#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006043 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006044#ifdef FEATURE_WLAN_TDLS
6045 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006046 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006047 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306048 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006049#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 init_completion(&pHddCtx->mc_sus_event_var);
6051 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306052 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006053 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006054 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006055
Rajeev79dbe4c2013-10-05 11:03:42 +05306056#ifdef FEATURE_WLAN_BATCH_SCAN
6057 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6058 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6059 pAdapter->pBatchScanRsp = NULL;
6060 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006061 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006062 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306063 mutex_init(&pAdapter->hdd_batch_scan_lock);
6064#endif
6065
Jeff Johnson295189b2012-06-20 16:38:30 -07006066 pAdapter->isLinkUpSvcNeeded = FALSE;
6067 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6068 //Init the net_device structure
6069 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6070
6071 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6072 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6073 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6074 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6075
6076 hdd_set_station_ops( pAdapter->dev );
6077
6078 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6080 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6081 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006082 /* set pWlanDev's parent to underlying device */
6083 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006084
6085 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006086 }
6087
6088 return pAdapter;
6089}
6090
6091VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6092{
6093 struct net_device *pWlanDev = pAdapter->dev;
6094 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6095 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6096 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6097
6098 if( rtnl_lock_held )
6099 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006100 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006101 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6102 {
6103 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6104 return VOS_STATUS_E_FAILURE;
6105 }
6106 }
6107 if (register_netdevice(pWlanDev))
6108 {
6109 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6110 return VOS_STATUS_E_FAILURE;
6111 }
6112 }
6113 else
6114 {
6115 if(register_netdev(pWlanDev))
6116 {
6117 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6118 return VOS_STATUS_E_FAILURE;
6119 }
6120 }
6121 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6122
6123 return VOS_STATUS_SUCCESS;
6124}
6125
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006126static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006127{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006128 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006129
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006130 if (NULL == pAdapter)
6131 {
6132 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6133 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006134 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006135
6136 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6137 {
6138 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6139 return eHAL_STATUS_NOT_INITIALIZED;
6140 }
6141
6142 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6143
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006144#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006145 /* need to make sure all of our scheduled work has completed.
6146 * This callback is called from MC thread context, so it is safe to
6147 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006148 *
6149 * Even though this is called from MC thread context, if there is a faulty
6150 * work item in the system, that can hang this call forever. So flushing
6151 * this global work queue is not safe; and now we make sure that
6152 * individual work queues are stopped correctly. But the cancel work queue
6153 * is a GPL only API, so the proprietary version of the driver would still
6154 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006155 */
6156 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006157#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006158
6159 /* We can be blocked while waiting for scheduled work to be
6160 * flushed, and the adapter structure can potentially be freed, in
6161 * which case the magic will have been reset. So make sure the
6162 * magic is still good, and hence the adapter structure is still
6163 * valid, before signaling completion */
6164 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6165 {
6166 complete(&pAdapter->session_close_comp_var);
6167 }
6168
Jeff Johnson295189b2012-06-20 16:38:30 -07006169 return eHAL_STATUS_SUCCESS;
6170}
6171
6172VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6173{
6174 struct net_device *pWlanDev = pAdapter->dev;
6175 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6176 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6177 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6178 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306179 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006180
6181 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006182 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 //Open a SME session for future operation
6184 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006185 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006186 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6187 {
6188 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006189 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006190 halStatus, halStatus );
6191 status = VOS_STATUS_E_FAILURE;
6192 goto error_sme_open;
6193 }
6194
6195 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306196 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006197 &pAdapter->session_open_comp_var,
6198 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306199 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006200 {
6201 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306202 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 status = VOS_STATUS_E_FAILURE;
6204 goto error_sme_open;
6205 }
6206
6207 // Register wireless extensions
6208 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6209 {
6210 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006211 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 halStatus, halStatus );
6213 status = VOS_STATUS_E_FAILURE;
6214 goto error_register_wext;
6215 }
6216 //Safe to register the hard_start_xmit function again
6217#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6218 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6219#else
6220 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6221#endif
6222
6223 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306224 hddLog(VOS_TRACE_LEVEL_INFO,
6225 "%s: Set HDD connState to eConnectionState_NotConnected",
6226 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6228
6229 //Set the default operation channel
6230 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6231
6232 /* Make the default Auth Type as OPEN*/
6233 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6234
6235 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6236 {
6237 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006238 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006239 status, status );
6240 goto error_init_txrx;
6241 }
6242
6243 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6244
6245 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6246 {
6247 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006248 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006249 status, status );
6250 goto error_wmm_init;
6251 }
6252
6253 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6254
6255 return VOS_STATUS_SUCCESS;
6256
6257error_wmm_init:
6258 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6259 hdd_deinit_tx_rx(pAdapter);
6260error_init_txrx:
6261 hdd_UnregisterWext(pWlanDev);
6262error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006263 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006264 {
6265 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006266 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006267 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006268 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006269 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306270 unsigned long rc;
6271
Jeff Johnson295189b2012-06-20 16:38:30 -07006272 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306273 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006274 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006275 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306276 if (rc <= 0)
6277 hddLog(VOS_TRACE_LEVEL_ERROR,
6278 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 }
6280}
6281error_sme_open:
6282 return status;
6283}
6284
Jeff Johnson295189b2012-06-20 16:38:30 -07006285void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6286{
6287 hdd_cfg80211_state_t *cfgState;
6288
6289 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6290
6291 if( NULL != cfgState->buf )
6292 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306293 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006294 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6295 rc = wait_for_completion_interruptible_timeout(
6296 &pAdapter->tx_action_cnf_event,
6297 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306298 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006299 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306301 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6302 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 }
6304 }
6305 return;
6306}
Jeff Johnson295189b2012-06-20 16:38:30 -07006307
6308void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6309{
6310 ENTER();
6311 switch ( pAdapter->device_mode )
6312 {
6313 case WLAN_HDD_INFRA_STATION:
6314 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006315 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 {
6317 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6318 {
6319 hdd_deinit_tx_rx( pAdapter );
6320 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6321 }
6322
6323 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6324 {
6325 hdd_wmm_adapter_close( pAdapter );
6326 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6327 }
6328
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 break;
6331 }
6332
6333 case WLAN_HDD_SOFTAP:
6334 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006335 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306336
6337 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6338 {
6339 hdd_wmm_adapter_close( pAdapter );
6340 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6341 }
6342
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006344
6345 hdd_unregister_hostapd(pAdapter);
6346 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006347 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 break;
6349 }
6350
6351 case WLAN_HDD_MONITOR:
6352 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6355 {
6356 hdd_deinit_tx_rx( pAdapter );
6357 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6358 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 if(NULL != pAdapterforTx)
6360 {
6361 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6362 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 break;
6364 }
6365
6366
6367 default:
6368 break;
6369 }
6370
6371 EXIT();
6372}
6373
6374void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6375{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006376 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306377
6378 ENTER();
6379 if (NULL == pAdapter)
6380 {
6381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6382 "%s: HDD adapter is Null", __func__);
6383 return;
6384 }
6385
6386 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006387
Rajeev79dbe4c2013-10-05 11:03:42 +05306388#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306389 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6390 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006391 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306392 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6393 )
6394 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006395 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306396 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006397 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6398 {
6399 hdd_deinit_batch_scan(pAdapter);
6400 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306401 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006402 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306403#endif
6404
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6406 if( rtnl_held )
6407 {
6408 unregister_netdevice(pWlanDev);
6409 }
6410 else
6411 {
6412 unregister_netdev(pWlanDev);
6413 }
6414 // note that the pAdapter is no longer valid at this point
6415 // since the memory has been reclaimed
6416 }
6417
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306418 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006419}
6420
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006421void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6422{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306423 VOS_STATUS status;
6424 hdd_adapter_t *pAdapter = NULL;
6425 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006426
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306427 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006428
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306429 /*loop through all adapters.*/
6430 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006431 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306432 pAdapter = pAdapterNode->pAdapter;
6433 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6434 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006435
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306436 { // we skip this registration for modes other than STA and P2P client modes.
6437 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6438 pAdapterNode = pNext;
6439 continue;
6440 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006441
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306442 //Apply Dynamic DTIM For P2P
6443 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6444 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6445 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6446 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6447 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6448 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6449 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6450 (eConnectionState_Associated ==
6451 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6452 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6453 {
6454 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006455
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306456 powerRequest.uIgnoreDTIM = 1;
6457 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6458
6459 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6460 {
6461 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6462 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6463 }
6464 else
6465 {
6466 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6467 }
6468
6469 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6470 * specified during Enter/Exit BMPS when LCD off*/
6471 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6472 NULL, eANI_BOOLEAN_FALSE);
6473 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6474 NULL, eANI_BOOLEAN_FALSE);
6475
6476 /* switch to the DTIM specified in cfg.ini */
6477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6478 "Switch to DTIM %d", powerRequest.uListenInterval);
6479 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6480 break;
6481
6482 }
6483
6484 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6485 pAdapterNode = pNext;
6486 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006487}
6488
6489void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6490{
6491 /*Switch back to DTIM 1*/
6492 tSirSetPowerParamsReq powerRequest = { 0 };
6493
6494 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6495 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006496 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006497
6498 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6499 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6500 NULL, eANI_BOOLEAN_FALSE);
6501 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6502 NULL, eANI_BOOLEAN_FALSE);
6503
6504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6505 "Switch to DTIM%d",powerRequest.uListenInterval);
6506 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6507
6508}
6509
Jeff Johnson295189b2012-06-20 16:38:30 -07006510VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6511{
6512 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306513 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6514 {
6515 hddLog( LOGE, FL("Wlan Unload in progress"));
6516 return VOS_STATUS_E_PERM;
6517 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6519 {
6520 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6521 }
6522
6523 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6524 {
6525 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6526 }
6527
6528 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6529 {
6530 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6531 }
6532
6533 return status;
6534}
6535
6536VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6537{
6538 hdd_adapter_t *pAdapter = NULL;
6539 eHalStatus halStatus;
6540 VOS_STATUS status = VOS_STATUS_E_INVAL;
6541 v_BOOL_t disableBmps = FALSE;
6542 v_BOOL_t disableImps = FALSE;
6543
6544 switch(session_type)
6545 {
6546 case WLAN_HDD_INFRA_STATION:
6547 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006548 case WLAN_HDD_P2P_CLIENT:
6549 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 //Exit BMPS -> Is Sta/P2P Client is already connected
6551 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6552 if((NULL != pAdapter)&&
6553 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6554 {
6555 disableBmps = TRUE;
6556 }
6557
6558 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6559 if((NULL != pAdapter)&&
6560 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6561 {
6562 disableBmps = TRUE;
6563 }
6564
6565 //Exit both Bmps and Imps incase of Go/SAP Mode
6566 if((WLAN_HDD_SOFTAP == session_type) ||
6567 (WLAN_HDD_P2P_GO == session_type))
6568 {
6569 disableBmps = TRUE;
6570 disableImps = TRUE;
6571 }
6572
6573 if(TRUE == disableImps)
6574 {
6575 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6576 {
6577 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6578 }
6579 }
6580
6581 if(TRUE == disableBmps)
6582 {
6583 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6584 {
6585 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6586
6587 if(eHAL_STATUS_SUCCESS != halStatus)
6588 {
6589 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006590 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006591 VOS_ASSERT(0);
6592 return status;
6593 }
6594 }
6595
6596 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6597 {
6598 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6599
6600 if(eHAL_STATUS_SUCCESS != halStatus)
6601 {
6602 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006603 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006604 VOS_ASSERT(0);
6605 return status;
6606 }
6607 }
6608 }
6609
6610 if((TRUE == disableBmps) ||
6611 (TRUE == disableImps))
6612 {
6613 /* Now, get the chip into Full Power now */
6614 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6615 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6616 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6617
6618 if(halStatus != eHAL_STATUS_SUCCESS)
6619 {
6620 if(halStatus == eHAL_STATUS_PMC_PENDING)
6621 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306622 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006623 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306624 ret = wait_for_completion_interruptible_timeout(
6625 &pHddCtx->full_pwr_comp_var,
6626 msecs_to_jiffies(1000));
6627 if (ret <= 0)
6628 {
6629 hddLog(VOS_TRACE_LEVEL_ERROR,
6630 "%s: wait on full_pwr_comp_var failed %ld",
6631 __func__, ret);
6632 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006633 }
6634 else
6635 {
6636 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006637 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006638 VOS_ASSERT(0);
6639 return status;
6640 }
6641 }
6642
6643 status = VOS_STATUS_SUCCESS;
6644 }
6645
6646 break;
6647 }
6648 return status;
6649}
6650
6651hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006652 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006653 tANI_U8 rtnl_held )
6654{
6655 hdd_adapter_t *pAdapter = NULL;
6656 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6657 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6658 VOS_STATUS exitbmpsStatus;
6659
Arif Hussain6d2a3322013-11-17 19:50:10 -08006660 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006661
Nirav Shah436658f2014-02-28 17:05:45 +05306662 if(macAddr == NULL)
6663 {
6664 /* Not received valid macAddr */
6665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6666 "%s:Unable to add virtual intf: Not able to get"
6667 "valid mac address",__func__);
6668 return NULL;
6669 }
6670
Jeff Johnson295189b2012-06-20 16:38:30 -07006671 //Disable BMPS incase of Concurrency
6672 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6673
6674 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6675 {
6676 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306677 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006678 VOS_ASSERT(0);
6679 return NULL;
6680 }
6681
6682 switch(session_type)
6683 {
6684 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006685 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006686 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006687 {
6688 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6689
6690 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306691 {
6692 hddLog(VOS_TRACE_LEVEL_FATAL,
6693 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006694 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306695 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006696
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306697#ifdef FEATURE_WLAN_TDLS
6698 /* A Mutex Lock is introduced while changing/initializing the mode to
6699 * protect the concurrent access for the Adapters by TDLS module.
6700 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306701 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306702#endif
6703
Jeff Johnsone7245742012-09-05 17:12:55 -07006704 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6705 NL80211_IFTYPE_P2P_CLIENT:
6706 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006707
Jeff Johnson295189b2012-06-20 16:38:30 -07006708 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306709#ifdef FEATURE_WLAN_TDLS
6710 mutex_unlock(&pHddCtx->tdls_lock);
6711#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306712
6713 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006714 if( VOS_STATUS_SUCCESS != status )
6715 goto err_free_netdev;
6716
6717 status = hdd_register_interface( pAdapter, rtnl_held );
6718 if( VOS_STATUS_SUCCESS != status )
6719 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306720#ifdef FEATURE_WLAN_TDLS
6721 mutex_lock(&pHddCtx->tdls_lock);
6722#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006723 hdd_deinit_adapter(pHddCtx, pAdapter);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306724#ifdef FEATURE_WLAN_TDLS
6725 mutex_unlock(&pHddCtx->tdls_lock);
6726#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006727 goto err_free_netdev;
6728 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306729
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306730 // Workqueue which gets scheduled in IPv4 notification callback.
6731 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6732
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306733#ifdef WLAN_NS_OFFLOAD
6734 // Workqueue which gets scheduled in IPv6 notification callback.
6735 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6736#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306738 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006739 netif_tx_disable(pAdapter->dev);
6740 //netif_tx_disable(pWlanDev);
6741 netif_carrier_off(pAdapter->dev);
6742
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306743 if (WLAN_HDD_P2P_CLIENT == session_type ||
6744 WLAN_HDD_P2P_DEVICE == session_type)
6745 {
6746 /* Initialize the work queue to defer the
6747 * back to back RoC request */
6748 INIT_DELAYED_WORK(&pAdapter->roc_work,
6749 hdd_p2p_roc_work_queue);
6750 }
6751
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 break;
6753 }
6754
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006756 case WLAN_HDD_SOFTAP:
6757 {
6758 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6759 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306760 {
6761 hddLog(VOS_TRACE_LEVEL_FATAL,
6762 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306764 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006765
Jeff Johnson295189b2012-06-20 16:38:30 -07006766 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6767 NL80211_IFTYPE_AP:
6768 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 pAdapter->device_mode = session_type;
6770
6771 status = hdd_init_ap_mode(pAdapter);
6772 if( VOS_STATUS_SUCCESS != status )
6773 goto err_free_netdev;
6774
6775 status = hdd_register_hostapd( pAdapter, rtnl_held );
6776 if( VOS_STATUS_SUCCESS != status )
6777 {
6778 hdd_deinit_adapter(pHddCtx, pAdapter);
6779 goto err_free_netdev;
6780 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306781 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 netif_tx_disable(pAdapter->dev);
6783 netif_carrier_off(pAdapter->dev);
6784
6785 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306786
6787 if (WLAN_HDD_P2P_GO == session_type)
6788 {
6789 /* Initialize the work queue to
6790 * defer the back to back RoC request */
6791 INIT_DELAYED_WORK(&pAdapter->roc_work,
6792 hdd_p2p_roc_work_queue);
6793 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 break;
6795 }
6796 case WLAN_HDD_MONITOR:
6797 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6799 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306800 {
6801 hddLog(VOS_TRACE_LEVEL_FATAL,
6802 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306804 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006805
6806 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6807 pAdapter->device_mode = session_type;
6808 status = hdd_register_interface( pAdapter, rtnl_held );
6809#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6810 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6811#else
6812 pAdapter->dev->open = hdd_mon_open;
6813 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6814#endif
6815 hdd_init_tx_rx( pAdapter );
6816 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6817 //Set adapter to be used for data tx. It will use either GO or softap.
6818 pAdapter->sessionCtx.monitor.pAdapterForTx =
6819 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006820 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6821 {
6822 pAdapter->sessionCtx.monitor.pAdapterForTx =
6823 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 /* This workqueue will be used to transmit management packet over
6826 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006827 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6828 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6829 return NULL;
6830 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006831
Jeff Johnson295189b2012-06-20 16:38:30 -07006832 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6833 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006834 }
6835 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006836 case WLAN_HDD_FTM:
6837 {
6838 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6839
6840 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306841 {
6842 hddLog(VOS_TRACE_LEVEL_FATAL,
6843 FL("failed to allocate adapter for session %d"), session_type);
6844 return NULL;
6845 }
6846
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6848 * message while loading driver in FTM mode. */
6849 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6850 pAdapter->device_mode = session_type;
6851 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306852
6853 hdd_init_tx_rx( pAdapter );
6854
6855 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306856 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306857 netif_tx_disable(pAdapter->dev);
6858 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 }
6860 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006861 default:
6862 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306863 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6864 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 VOS_ASSERT(0);
6866 return NULL;
6867 }
6868 }
6869
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 if( VOS_STATUS_SUCCESS == status )
6871 {
6872 //Add it to the hdd's session list.
6873 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6874 if( NULL == pHddAdapterNode )
6875 {
6876 status = VOS_STATUS_E_NOMEM;
6877 }
6878 else
6879 {
6880 pHddAdapterNode->pAdapter = pAdapter;
6881 status = hdd_add_adapter_back ( pHddCtx,
6882 pHddAdapterNode );
6883 }
6884 }
6885
6886 if( VOS_STATUS_SUCCESS != status )
6887 {
6888 if( NULL != pAdapter )
6889 {
6890 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6891 pAdapter = NULL;
6892 }
6893 if( NULL != pHddAdapterNode )
6894 {
6895 vos_mem_free( pHddAdapterNode );
6896 }
6897
6898 goto resume_bmps;
6899 }
6900
6901 if(VOS_STATUS_SUCCESS == status)
6902 {
6903 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6904
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006905 //Initialize the WoWL service
6906 if(!hdd_init_wowl(pAdapter))
6907 {
6908 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6909 goto err_free_netdev;
6910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006911 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 return pAdapter;
6913
6914err_free_netdev:
6915 free_netdev(pAdapter->dev);
6916 wlan_hdd_release_intf_addr( pHddCtx,
6917 pAdapter->macAddressCurrent.bytes );
6918
6919resume_bmps:
6920 //If bmps disabled enable it
6921 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6922 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306923 if (pHddCtx->hdd_wlan_suspended)
6924 {
6925 hdd_set_pwrparams(pHddCtx);
6926 }
6927 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006928 }
6929 return NULL;
6930}
6931
6932VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6933 tANI_U8 rtnl_held )
6934{
6935 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6936 VOS_STATUS status;
6937
6938 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6939 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306940 {
6941 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6942 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006943 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306944 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006945
6946 while ( pCurrent->pAdapter != pAdapter )
6947 {
6948 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6949 if( VOS_STATUS_SUCCESS != status )
6950 break;
6951
6952 pCurrent = pNext;
6953 }
6954 pAdapterNode = pCurrent;
6955 if( VOS_STATUS_SUCCESS == status )
6956 {
6957 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6958 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306959
6960#ifdef FEATURE_WLAN_TDLS
6961
6962 /* A Mutex Lock is introduced while changing/initializing the mode to
6963 * protect the concurrent access for the Adapters by TDLS module.
6964 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306965 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306966#endif
6967
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 hdd_remove_adapter( pHddCtx, pAdapterNode );
6969 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006970 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006971
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306972#ifdef FEATURE_WLAN_TDLS
6973 mutex_unlock(&pHddCtx->tdls_lock);
6974#endif
6975
Jeff Johnson295189b2012-06-20 16:38:30 -07006976
6977 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306978 if ((!vos_concurrent_open_sessions_running()) &&
6979 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6980 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306982 if (pHddCtx->hdd_wlan_suspended)
6983 {
6984 hdd_set_pwrparams(pHddCtx);
6985 }
6986 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 }
6988
6989 return VOS_STATUS_SUCCESS;
6990 }
6991
6992 return VOS_STATUS_E_FAILURE;
6993}
6994
6995VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6996{
6997 hdd_adapter_list_node_t *pHddAdapterNode;
6998 VOS_STATUS status;
6999
7000 ENTER();
7001
7002 do
7003 {
7004 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7005 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7006 {
7007 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7008 vos_mem_free( pHddAdapterNode );
7009 }
7010 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7011
7012 EXIT();
7013
7014 return VOS_STATUS_SUCCESS;
7015}
7016
7017void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7018{
7019 v_U8_t addIE[1] = {0};
7020
7021 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7022 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7023 eANI_BOOLEAN_FALSE) )
7024 {
7025 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007026 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007027 }
7028
7029 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7030 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7031 eANI_BOOLEAN_FALSE) )
7032 {
7033 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007034 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 }
7036
7037 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7038 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7039 eANI_BOOLEAN_FALSE) )
7040 {
7041 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007042 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 }
7044}
7045
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307046VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7047 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007048{
7049 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7050 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307051 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007052 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307053 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307054 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007055
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307056 if (pHddCtx->isLogpInProgress) {
7057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7058 "%s:LOGP in Progress. Ignore!!!",__func__);
7059 return VOS_STATUS_E_FAILURE;
7060 }
7061
Jeff Johnson295189b2012-06-20 16:38:30 -07007062 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307063
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307064 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 switch(pAdapter->device_mode)
7066 {
7067 case WLAN_HDD_INFRA_STATION:
7068 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007069 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307070 {
7071 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7072 if( hdd_connIsConnected(pstation) ||
7073 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007074 {
7075 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7076 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7077 pAdapter->sessionId,
7078 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7079 else
7080 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7081 pAdapter->sessionId,
7082 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7083 //success implies disconnect command got queued up successfully
7084 if(halStatus == eHAL_STATUS_SUCCESS)
7085 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307086 ret = wait_for_completion_interruptible_timeout(
7087 &pAdapter->disconnect_comp_var,
7088 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7089 if (ret <= 0)
7090 {
7091 hddLog(VOS_TRACE_LEVEL_ERROR,
7092 "%s: wait on disconnect_comp_var failed %ld",
7093 __func__, ret);
7094 }
7095 }
7096 else
7097 {
7098 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7099 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007100 }
7101 memset(&wrqu, '\0', sizeof(wrqu));
7102 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7103 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7104 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7105 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307106 else if(pstation->conn_info.connState ==
7107 eConnectionState_Disconnecting)
7108 {
7109 ret = wait_for_completion_interruptible_timeout(
7110 &pAdapter->disconnect_comp_var,
7111 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7112 if (ret <= 0)
7113 {
7114 hddLog(VOS_TRACE_LEVEL_ERROR,
7115 FL("wait on disconnect_comp_var failed %ld"), ret);
7116 }
7117 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307118 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307120 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307121 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007122 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307123 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7124 {
7125 while (pAdapter->is_roc_inprogress)
7126 {
7127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7128 "%s: ROC in progress for session %d!!!",
7129 __func__, pAdapter->sessionId);
7130 // waiting for ROC to expire
7131 msleep(500);
7132 /* In GO present case , if retry exceeds 3,
7133 it means something went wrong. */
7134 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7135 {
7136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7137 "%s: ROC completion is not received.!!!", __func__);
7138 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
7139 pAdapter->sessionId);
7140 wait_for_completion_interruptible_timeout(
7141 &pAdapter->cancel_rem_on_chan_var,
7142 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7143 break;
7144 }
7145 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307146#ifdef WLAN_OPEN_SOURCE
7147 cancel_delayed_work_sync(&pAdapter->roc_work);
7148#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307149 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307150#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307151#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307152 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7153#endif
7154#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307155
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307156#ifdef WLAN_OPEN_SOURCE
7157 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7158#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307159
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307160 /* It is possible that the caller of this function does not
7161 * wish to close the session
7162 */
7163 if (VOS_TRUE == bCloseSession &&
7164 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007165 {
7166 INIT_COMPLETION(pAdapter->session_close_comp_var);
7167 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307168 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7169 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007170 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307171 unsigned long ret;
7172
Jeff Johnson295189b2012-06-20 16:38:30 -07007173 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307174 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307175 &pAdapter->session_close_comp_var,
7176 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307177 if ( 0 >= ret)
7178 {
7179 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307180 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307181 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007182 }
7183 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307184 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007185 break;
7186
7187 case WLAN_HDD_SOFTAP:
7188 case WLAN_HDD_P2P_GO:
7189 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307190 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7191 while (pAdapter->is_roc_inprogress) {
7192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7193 "%s: ROC in progress for session %d!!!",
7194 __func__, pAdapter->sessionId);
7195 msleep(500);
7196 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7198 "%s: ROC completion is not received.!!!", __func__);
7199 WLANSAP_CancelRemainOnChannel(
7200 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7201 wait_for_completion_interruptible_timeout(
7202 &pAdapter->cancel_rem_on_chan_var,
7203 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7204 break;
7205 }
7206 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307207
7208#ifdef WLAN_OPEN_SOURCE
7209 cancel_delayed_work_sync(&pAdapter->roc_work);
7210#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307211 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007212 mutex_lock(&pHddCtx->sap_lock);
7213 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7214 {
7215 VOS_STATUS status;
7216 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7217
7218 //Stop Bss.
7219 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7220 if (VOS_IS_STATUS_SUCCESS(status))
7221 {
7222 hdd_hostapd_state_t *pHostapdState =
7223 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7224
7225 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7226
7227 if (!VOS_IS_STATUS_SUCCESS(status))
7228 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307229 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7230 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 }
7232 }
7233 else
7234 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007235 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007236 }
7237 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307238 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007239
7240 if (eHAL_STATUS_FAILURE ==
7241 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7242 0, NULL, eANI_BOOLEAN_FALSE))
7243 {
7244 hddLog(LOGE,
7245 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007246 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007247 }
7248
7249 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7250 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7251 eANI_BOOLEAN_FALSE) )
7252 {
7253 hddLog(LOGE,
7254 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7255 }
7256
7257 // Reset WNI_CFG_PROBE_RSP Flags
7258 wlan_hdd_reset_prob_rspies(pAdapter);
7259 kfree(pAdapter->sessionCtx.ap.beacon);
7260 pAdapter->sessionCtx.ap.beacon = NULL;
7261 }
7262 mutex_unlock(&pHddCtx->sap_lock);
7263 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007264
Jeff Johnson295189b2012-06-20 16:38:30 -07007265 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007266#ifdef WLAN_OPEN_SOURCE
7267 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7268#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007269 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007270
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 default:
7272 break;
7273 }
7274
7275 EXIT();
7276 return VOS_STATUS_SUCCESS;
7277}
7278
7279VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7280{
7281 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7282 VOS_STATUS status;
7283 hdd_adapter_t *pAdapter;
7284
7285 ENTER();
7286
7287 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7288
7289 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7290 {
7291 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007292
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307293 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007294
7295 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7296 pAdapterNode = pNext;
7297 }
7298
7299 EXIT();
7300
7301 return VOS_STATUS_SUCCESS;
7302}
7303
Rajeev Kumarf999e582014-01-09 17:33:29 -08007304
7305#ifdef FEATURE_WLAN_BATCH_SCAN
7306/**---------------------------------------------------------------------------
7307
7308 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7309 structures
7310
7311 \param - pAdapter Pointer to HDD adapter
7312
7313 \return - None
7314
7315 --------------------------------------------------------------------------*/
7316void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7317{
7318 tHddBatchScanRsp *pNode;
7319 tHddBatchScanRsp *pPrev;
7320
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307321 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007322 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307323 hddLog(VOS_TRACE_LEVEL_ERROR,
7324 "%s: Adapter context is Null", __func__);
7325 return;
7326 }
7327
7328 pNode = pAdapter->pBatchScanRsp;
7329 while (pNode)
7330 {
7331 pPrev = pNode;
7332 pNode = pNode->pNext;
7333 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007334 }
7335
7336 pAdapter->pBatchScanRsp = NULL;
7337 pAdapter->numScanList = 0;
7338 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7339 pAdapter->prev_batch_id = 0;
7340
7341 return;
7342}
7343#endif
7344
7345
Jeff Johnson295189b2012-06-20 16:38:30 -07007346VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7347{
7348 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7349 VOS_STATUS status;
7350 hdd_adapter_t *pAdapter;
7351
7352 ENTER();
7353
7354 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7355
7356 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7357 {
7358 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307359 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007360 netif_tx_disable(pAdapter->dev);
7361 netif_carrier_off(pAdapter->dev);
7362
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007363 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7364
Jeff Johnson295189b2012-06-20 16:38:30 -07007365 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307366
7367 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7368
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307369 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7370 {
7371 hdd_wmm_adapter_close( pAdapter );
7372 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7373 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007374
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307375 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7376 {
7377 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7378 }
7379
Rajeev Kumarf999e582014-01-09 17:33:29 -08007380#ifdef FEATURE_WLAN_BATCH_SCAN
7381 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7382 {
7383 hdd_deinit_batch_scan(pAdapter);
7384 }
7385#endif
7386
Jeff Johnson295189b2012-06-20 16:38:30 -07007387 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7388 pAdapterNode = pNext;
7389 }
7390
7391 EXIT();
7392
7393 return VOS_STATUS_SUCCESS;
7394}
7395
7396VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7397{
7398 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7399 VOS_STATUS status;
7400 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307401 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007402
7403 ENTER();
7404
7405 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7406
7407 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7408 {
7409 pAdapter = pAdapterNode->pAdapter;
7410
Kumar Anand82c009f2014-05-29 00:29:42 -07007411 hdd_wmm_init( pAdapter );
7412
Jeff Johnson295189b2012-06-20 16:38:30 -07007413 switch(pAdapter->device_mode)
7414 {
7415 case WLAN_HDD_INFRA_STATION:
7416 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007417 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307418
7419 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7420
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 hdd_init_station_mode(pAdapter);
7422 /* Open the gates for HDD to receive Wext commands */
7423 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007424 pHddCtx->scan_info.mScanPending = FALSE;
7425 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007426
7427 //Trigger the initial scan
7428 hdd_wlan_initial_scan(pAdapter);
7429
7430 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307431 if (eConnectionState_Associated == connState ||
7432 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007433 {
7434 union iwreq_data wrqu;
7435 memset(&wrqu, '\0', sizeof(wrqu));
7436 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7437 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7438 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007439 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007440
Jeff Johnson295189b2012-06-20 16:38:30 -07007441 /* indicate disconnected event to nl80211 */
7442 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7443 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007444 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307445 else if (eConnectionState_Connecting == connState)
7446 {
7447 /*
7448 * Indicate connect failure to supplicant if we were in the
7449 * process of connecting
7450 */
7451 cfg80211_connect_result(pAdapter->dev, NULL,
7452 NULL, 0, NULL, 0,
7453 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7454 GFP_KERNEL);
7455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007456 break;
7457
7458 case WLAN_HDD_SOFTAP:
7459 /* softAP can handle SSR */
7460 break;
7461
7462 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007465 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 break;
7467
7468 case WLAN_HDD_MONITOR:
7469 /* monitor interface start */
7470 break;
7471 default:
7472 break;
7473 }
7474
7475 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7476 pAdapterNode = pNext;
7477 }
7478
7479 EXIT();
7480
7481 return VOS_STATUS_SUCCESS;
7482}
7483
7484VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7485{
7486 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7487 hdd_adapter_t *pAdapter;
7488 VOS_STATUS status;
7489 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307490 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007491
7492 ENTER();
7493
7494 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7495
7496 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7497 {
7498 pAdapter = pAdapterNode->pAdapter;
7499
7500 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7501 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7502 {
7503 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7504 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7505
Abhishek Singhf4669da2014-05-26 15:07:49 +05307506 hddLog(VOS_TRACE_LEVEL_INFO,
7507 "%s: Set HDD connState to eConnectionState_NotConnected",
7508 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007509 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7510 init_completion(&pAdapter->disconnect_comp_var);
7511 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7512 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7513
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307514 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007515 &pAdapter->disconnect_comp_var,
7516 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307517 if (0 >= ret)
7518 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7519 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007520
7521 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7522 pHddCtx->isAmpAllowed = VOS_FALSE;
7523 sme_RoamConnect(pHddCtx->hHal,
7524 pAdapter->sessionId, &(pWextState->roamProfile),
7525 &roamId);
7526 }
7527
7528 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7529 pAdapterNode = pNext;
7530 }
7531
7532 EXIT();
7533
7534 return VOS_STATUS_SUCCESS;
7535}
7536
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007537void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7538{
7539 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7540 VOS_STATUS status;
7541 hdd_adapter_t *pAdapter;
7542 hdd_station_ctx_t *pHddStaCtx;
7543 hdd_ap_ctx_t *pHddApCtx;
7544 hdd_hostapd_state_t * pHostapdState;
7545 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7546 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7547 const char *p2pMode = "DEV";
7548 const char *ccMode = "Standalone";
7549 int n;
7550
7551 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7552 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7553 {
7554 pAdapter = pAdapterNode->pAdapter;
7555 switch (pAdapter->device_mode) {
7556 case WLAN_HDD_INFRA_STATION:
7557 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7558 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7559 staChannel = pHddStaCtx->conn_info.operationChannel;
7560 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7561 }
7562 break;
7563 case WLAN_HDD_P2P_CLIENT:
7564 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7565 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7566 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7567 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7568 p2pMode = "CLI";
7569 }
7570 break;
7571 case WLAN_HDD_P2P_GO:
7572 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7573 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7574 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7575 p2pChannel = pHddApCtx->operatingChannel;
7576 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7577 }
7578 p2pMode = "GO";
7579 break;
7580 case WLAN_HDD_SOFTAP:
7581 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7582 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7583 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7584 apChannel = pHddApCtx->operatingChannel;
7585 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7586 }
7587 break;
7588 default:
7589 break;
7590 }
7591 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7592 pAdapterNode = pNext;
7593 }
7594 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7595 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7596 }
7597 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7598 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7599 if (p2pChannel > 0) {
7600 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7601 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7602 }
7603 if (apChannel > 0) {
7604 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7605 apChannel, MAC_ADDR_ARRAY(apBssid));
7606 }
7607
7608 if (p2pChannel > 0 && apChannel > 0) {
7609 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7610 }
7611}
7612
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007613bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007614{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007615 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007616}
7617
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007618/* Once SSR is disabled then it cannot be set. */
7619void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007620{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007621 if (HDD_SSR_DISABLED == isSsrRequired)
7622 return;
7623
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 isSsrRequired = value;
7625}
7626
7627VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7628 hdd_adapter_list_node_t** ppAdapterNode)
7629{
7630 VOS_STATUS status;
7631 spin_lock(&pHddCtx->hddAdapters.lock);
7632 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7633 (hdd_list_node_t**) ppAdapterNode );
7634 spin_unlock(&pHddCtx->hddAdapters.lock);
7635 return status;
7636}
7637
7638VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7639 hdd_adapter_list_node_t* pAdapterNode,
7640 hdd_adapter_list_node_t** pNextAdapterNode)
7641{
7642 VOS_STATUS status;
7643 spin_lock(&pHddCtx->hddAdapters.lock);
7644 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7645 (hdd_list_node_t*) pAdapterNode,
7646 (hdd_list_node_t**)pNextAdapterNode );
7647
7648 spin_unlock(&pHddCtx->hddAdapters.lock);
7649 return status;
7650}
7651
7652VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7653 hdd_adapter_list_node_t* pAdapterNode)
7654{
7655 VOS_STATUS status;
7656 spin_lock(&pHddCtx->hddAdapters.lock);
7657 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7658 &pAdapterNode->node );
7659 spin_unlock(&pHddCtx->hddAdapters.lock);
7660 return status;
7661}
7662
7663VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7664 hdd_adapter_list_node_t** ppAdapterNode)
7665{
7666 VOS_STATUS status;
7667 spin_lock(&pHddCtx->hddAdapters.lock);
7668 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7669 (hdd_list_node_t**) ppAdapterNode );
7670 spin_unlock(&pHddCtx->hddAdapters.lock);
7671 return status;
7672}
7673
7674VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7675 hdd_adapter_list_node_t* pAdapterNode)
7676{
7677 VOS_STATUS status;
7678 spin_lock(&pHddCtx->hddAdapters.lock);
7679 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7680 (hdd_list_node_t*) pAdapterNode );
7681 spin_unlock(&pHddCtx->hddAdapters.lock);
7682 return status;
7683}
7684
7685VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7686 hdd_adapter_list_node_t* pAdapterNode)
7687{
7688 VOS_STATUS status;
7689 spin_lock(&pHddCtx->hddAdapters.lock);
7690 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7691 (hdd_list_node_t*) pAdapterNode );
7692 spin_unlock(&pHddCtx->hddAdapters.lock);
7693 return status;
7694}
7695
7696hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7697 tSirMacAddr macAddr )
7698{
7699 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7700 hdd_adapter_t *pAdapter;
7701 VOS_STATUS status;
7702
7703 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7704
7705 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7706 {
7707 pAdapter = pAdapterNode->pAdapter;
7708
7709 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7710 macAddr, sizeof(tSirMacAddr) ) )
7711 {
7712 return pAdapter;
7713 }
7714 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7715 pAdapterNode = pNext;
7716 }
7717
7718 return NULL;
7719
7720}
7721
7722hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7723{
7724 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7725 hdd_adapter_t *pAdapter;
7726 VOS_STATUS status;
7727
7728 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7729
7730 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7731 {
7732 pAdapter = pAdapterNode->pAdapter;
7733
7734 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7735 IFNAMSIZ ) )
7736 {
7737 return pAdapter;
7738 }
7739 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7740 pAdapterNode = pNext;
7741 }
7742
7743 return NULL;
7744
7745}
7746
7747hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7748{
7749 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7750 hdd_adapter_t *pAdapter;
7751 VOS_STATUS status;
7752
7753 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7754
7755 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7756 {
7757 pAdapter = pAdapterNode->pAdapter;
7758
7759 if( pAdapter && (mode == pAdapter->device_mode) )
7760 {
7761 return pAdapter;
7762 }
7763 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7764 pAdapterNode = pNext;
7765 }
7766
7767 return NULL;
7768
7769}
7770
7771//Remove this function later
7772hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7773{
7774 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7775 hdd_adapter_t *pAdapter;
7776 VOS_STATUS status;
7777
7778 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7779
7780 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7781 {
7782 pAdapter = pAdapterNode->pAdapter;
7783
7784 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7785 {
7786 return pAdapter;
7787 }
7788
7789 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7790 pAdapterNode = pNext;
7791 }
7792
7793 return NULL;
7794
7795}
7796
Jeff Johnson295189b2012-06-20 16:38:30 -07007797/**---------------------------------------------------------------------------
7798
7799 \brief hdd_set_monitor_tx_adapter() -
7800
7801 This API initializes the adapter to be used while transmitting on monitor
7802 adapter.
7803
7804 \param - pHddCtx - Pointer to the HDD context.
7805 pAdapter - Adapter that will used for TX. This can be NULL.
7806 \return - None.
7807 --------------------------------------------------------------------------*/
7808void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7809{
7810 hdd_adapter_t *pMonAdapter;
7811
7812 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7813
7814 if( NULL != pMonAdapter )
7815 {
7816 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7817 }
7818}
Jeff Johnson295189b2012-06-20 16:38:30 -07007819/**---------------------------------------------------------------------------
7820
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307821 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007822
7823 This API returns the operating channel of the requested device mode
7824
7825 \param - pHddCtx - Pointer to the HDD context.
7826 - mode - Device mode for which operating channel is required
7827 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7828 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7829 \return - channel number. "0" id the requested device is not found OR it is not connected.
7830 --------------------------------------------------------------------------*/
7831v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7832{
7833 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7834 VOS_STATUS status;
7835 hdd_adapter_t *pAdapter;
7836 v_U8_t operatingChannel = 0;
7837
7838 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7839
7840 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7841 {
7842 pAdapter = pAdapterNode->pAdapter;
7843
7844 if( mode == pAdapter->device_mode )
7845 {
7846 switch(pAdapter->device_mode)
7847 {
7848 case WLAN_HDD_INFRA_STATION:
7849 case WLAN_HDD_P2P_CLIENT:
7850 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7851 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7852 break;
7853 case WLAN_HDD_SOFTAP:
7854 case WLAN_HDD_P2P_GO:
7855 /*softap connection info */
7856 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7857 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7858 break;
7859 default:
7860 break;
7861 }
7862
7863 break; //Found the device of interest. break the loop
7864 }
7865
7866 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7867 pAdapterNode = pNext;
7868 }
7869 return operatingChannel;
7870}
7871
7872#ifdef WLAN_FEATURE_PACKET_FILTERING
7873/**---------------------------------------------------------------------------
7874
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307875 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007876
7877 This used to set the multicast address list.
7878
7879 \param - dev - Pointer to the WLAN device.
7880 - skb - Pointer to OS packet (sk_buff).
7881 \return - success/fail
7882
7883 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307884static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007885{
7886 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007887 int mc_count;
7888 int i = 0;
7889 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307890
7891 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007892 {
7893 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307894 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007895 return;
7896 }
7897
7898 if (dev->flags & IFF_ALLMULTI)
7899 {
7900 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007901 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307902 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007903 }
7904 else
7905 {
7906 mc_count = netdev_mc_count(dev);
7907 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007908 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007909 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7910 {
7911 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007912 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307913 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007914 return;
7915 }
7916
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307917 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007918
7919 netdev_for_each_mc_addr(ha, dev) {
7920 if (i == mc_count)
7921 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307922 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7923 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007924 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007925 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307926 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007927 i++;
7928 }
7929 }
7930 return;
7931}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307932
7933static void hdd_set_multicast_list(struct net_device *dev)
7934{
7935 vos_ssr_protect(__func__);
7936 __hdd_set_multicast_list(dev);
7937 vos_ssr_unprotect(__func__);
7938}
Jeff Johnson295189b2012-06-20 16:38:30 -07007939#endif
7940
7941/**---------------------------------------------------------------------------
7942
7943 \brief hdd_select_queue() -
7944
7945 This function is registered with the Linux OS for network
7946 core to decide which queue to use first.
7947
7948 \param - dev - Pointer to the WLAN device.
7949 - skb - Pointer to OS packet (sk_buff).
7950 \return - ac, Queue Index/access category corresponding to UP in IP header
7951
7952 --------------------------------------------------------------------------*/
7953v_U16_t hdd_select_queue(struct net_device *dev,
7954 struct sk_buff *skb)
7955{
7956 return hdd_wmm_select_queue(dev, skb);
7957}
7958
7959
7960/**---------------------------------------------------------------------------
7961
7962 \brief hdd_wlan_initial_scan() -
7963
7964 This function triggers the initial scan
7965
7966 \param - pAdapter - Pointer to the HDD adapter.
7967
7968 --------------------------------------------------------------------------*/
7969void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7970{
7971 tCsrScanRequest scanReq;
7972 tCsrChannelInfo channelInfo;
7973 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007974 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7976
7977 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7978 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7979 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7980
7981 if(sme_Is11dSupported(pHddCtx->hHal))
7982 {
7983 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7984 if ( HAL_STATUS_SUCCESS( halStatus ) )
7985 {
7986 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7987 if( !scanReq.ChannelInfo.ChannelList )
7988 {
7989 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7990 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007991 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007992 return;
7993 }
7994 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7995 channelInfo.numOfChannels);
7996 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7997 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007998 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007999 }
8000
8001 scanReq.scanType = eSIR_PASSIVE_SCAN;
8002 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8003 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8004 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8005 }
8006 else
8007 {
8008 scanReq.scanType = eSIR_ACTIVE_SCAN;
8009 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8010 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8011 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8012 }
8013
8014 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8015 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8016 {
8017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8018 __func__, halStatus );
8019 }
8020
8021 if(sme_Is11dSupported(pHddCtx->hHal))
8022 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8023}
8024
Jeff Johnson295189b2012-06-20 16:38:30 -07008025/**---------------------------------------------------------------------------
8026
8027 \brief hdd_full_power_callback() - HDD full power callback function
8028
8029 This is the function invoked by SME to inform the result of a full power
8030 request issued by HDD
8031
8032 \param - callbackcontext - Pointer to cookie
8033 \param - status - result of request
8034
8035 \return - None
8036
8037 --------------------------------------------------------------------------*/
8038static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8039{
Jeff Johnson72a40512013-12-19 10:14:15 -08008040 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008041
8042 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308043 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008044
8045 if (NULL == callbackContext)
8046 {
8047 hddLog(VOS_TRACE_LEVEL_ERROR,
8048 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008049 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 return;
8051 }
8052
Jeff Johnson72a40512013-12-19 10:14:15 -08008053 /* there is a race condition that exists between this callback
8054 function and the caller since the caller could time out either
8055 before or while this code is executing. we use a spinlock to
8056 serialize these actions */
8057 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008058
8059 if (POWER_CONTEXT_MAGIC != pContext->magic)
8060 {
8061 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008062 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 hddLog(VOS_TRACE_LEVEL_WARN,
8064 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008065 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008066 return;
8067 }
8068
Jeff Johnson72a40512013-12-19 10:14:15 -08008069 /* context is valid so caller is still waiting */
8070
8071 /* paranoia: invalidate the magic */
8072 pContext->magic = 0;
8073
8074 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008075 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008076
8077 /* serialization is complete */
8078 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008079}
8080
8081/**---------------------------------------------------------------------------
8082
8083 \brief hdd_wlan_exit() - HDD WLAN exit function
8084
8085 This is the driver exit point (invoked during rmmod)
8086
8087 \param - pHddCtx - Pointer to the HDD Context
8088
8089 \return - None
8090
8091 --------------------------------------------------------------------------*/
8092void hdd_wlan_exit(hdd_context_t *pHddCtx)
8093{
8094 eHalStatus halStatus;
8095 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8096 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308097 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008098 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008099 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308101 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008102
8103 ENTER();
8104
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308105#ifdef WLAN_NS_OFFLOAD
8106 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8107 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8108#endif
8109 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8110 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8111
Jeff Johnson88ba7742013-02-27 14:36:02 -08008112 if (VOS_FTM_MODE != hdd_get_conparam())
8113 {
8114 // Unloading, restart logic is no more required.
8115 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008116
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308117#ifdef FEATURE_WLAN_TDLS
8118 /* At the time of driver unloading; if tdls connection is present;
8119 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8120 * wlan_hdd_tdls_find_peer always checks for valid context;
8121 * as load/unload in progress there can be a race condition.
8122 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8123 * when tdls state is enabled.
8124 * As soon as driver set load/unload flag; tdls flag also needs
8125 * to be disabled so that hdd_rx_packet_cbk won't call
8126 * wlan_hdd_tdls_find_peer.
8127 */
8128 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8129#endif
8130
c_hpothu5ab05e92014-06-13 17:34:05 +05308131 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8132 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008133 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308134 pAdapter = pAdapterNode->pAdapter;
8135 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 {
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308137 /* Disable TX on the interface, after this hard_start_xmit() will
8138 * not be called on that interface
8139 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308140 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308141 netif_tx_disable(pAdapter->dev);
8142
8143 /* Mark the interface status as "down" for outside world */
8144 netif_carrier_off(pAdapter->dev);
8145
8146 /* DeInit the adapter. This ensures that all data packets
8147 * are freed.
8148 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308149#ifdef FEATURE_WLAN_TDLS
8150 mutex_lock(&pHddCtx->tdls_lock);
8151#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308152 hdd_deinit_adapter(pHddCtx, pAdapter);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308153#ifdef FEATURE_WLAN_TDLS
8154 mutex_unlock(&pHddCtx->tdls_lock);
8155#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308156
c_hpothu5ab05e92014-06-13 17:34:05 +05308157 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8158 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8159 {
8160 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8161 hdd_UnregisterWext(pAdapter->dev);
8162 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308163
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308165 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8166 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008167 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308168 // Cancel any outstanding scan requests. We are about to close all
8169 // of our adapters, but an adapter structure is what SME passes back
8170 // to our callback function. Hence if there are any outstanding scan
8171 // requests then there is a race condition between when the adapter
8172 // is closed and when the callback is invoked.We try to resolve that
8173 // race condition here by canceling any outstanding scans before we
8174 // close the adapters.
8175 // Note that the scans may be cancelled in an asynchronous manner,
8176 // so ideally there needs to be some kind of synchronization. Rather
8177 // than introduce a new synchronization here, we will utilize the
8178 // fact that we are about to Request Full Power, and since that is
8179 // synchronized, the expectation is that by the time Request Full
8180 // Power has completed all scans will be cancelled.
8181 if (pHddCtx->scan_info.mScanPending)
8182 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308183 if(NULL != pAdapter)
8184 {
8185 hddLog(VOS_TRACE_LEVEL_INFO,
8186 FL("abort scan mode: %d sessionId: %d"),
8187 pAdapter->device_mode,
8188 pAdapter->sessionId);
8189 }
8190 hdd_abort_mac_scan(pHddCtx,
8191 pHddCtx->scan_info.sessionId,
8192 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308193 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008194 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308195 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008196 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308197 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08008198 wlan_hdd_ftm_close(pHddCtx);
8199 goto free_hdd_ctx;
8200 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308201
Jeff Johnson295189b2012-06-20 16:38:30 -07008202 /* DeRegister with platform driver as client for Suspend/Resume */
8203 vosStatus = hddDeregisterPmOps(pHddCtx);
8204 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8205 {
8206 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8207 VOS_ASSERT(0);
8208 }
8209
8210 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8211 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8212 {
8213 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8214 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008215
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008216 //Stop the traffic monitor timer
8217 if ( VOS_TIMER_STATE_RUNNING ==
8218 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8219 {
8220 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8221 }
8222
8223 // Destroy the traffic monitor timer
8224 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8225 &pHddCtx->tx_rx_trafficTmr)))
8226 {
8227 hddLog(VOS_TRACE_LEVEL_ERROR,
8228 "%s: Cannot deallocate Traffic monitor timer", __func__);
8229 }
8230
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 //Disable IMPS/BMPS as we do not want the device to enter any power
8232 //save mode during shutdown
8233 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8234 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8235 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8236
8237 //Ensure that device is in full power as we will touch H/W during vos_Stop
8238 init_completion(&powerContext.completion);
8239 powerContext.magic = POWER_CONTEXT_MAGIC;
8240
8241 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8242 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8243
8244 if (eHAL_STATUS_SUCCESS != halStatus)
8245 {
8246 if (eHAL_STATUS_PMC_PENDING == halStatus)
8247 {
8248 /* request was sent -- wait for the response */
8249 lrc = wait_for_completion_interruptible_timeout(
8250 &powerContext.completion,
8251 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 if (lrc <= 0)
8253 {
8254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008255 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008256 }
8257 }
8258 else
8259 {
8260 hddLog(VOS_TRACE_LEVEL_ERROR,
8261 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008262 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008263 /* continue -- need to clean up as much as possible */
8264 }
8265 }
8266
Jeff Johnson72a40512013-12-19 10:14:15 -08008267 /* either we never sent a request, we sent a request and received a
8268 response or we sent a request and timed out. if we never sent a
8269 request or if we sent a request and got a response, we want to
8270 clear the magic out of paranoia. if we timed out there is a
8271 race condition such that the callback function could be
8272 executing at the same time we are. of primary concern is if the
8273 callback function had already verified the "magic" but had not
8274 yet set the completion variable when a timeout occurred. we
8275 serialize these activities by invalidating the magic while
8276 holding a shared spinlock which will cause us to block if the
8277 callback is currently executing */
8278 spin_lock(&hdd_context_lock);
8279 powerContext.magic = 0;
8280 spin_unlock(&hdd_context_lock);
8281
Yue Ma0d4891e2013-08-06 17:01:45 -07008282 hdd_debugfs_exit(pHddCtx);
8283
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 // Unregister the Net Device Notifier
8285 unregister_netdevice_notifier(&hdd_netdev_notifier);
8286
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 hdd_stop_all_adapters( pHddCtx );
8288
Jeff Johnson295189b2012-06-20 16:38:30 -07008289#ifdef WLAN_BTAMP_FEATURE
8290 vosStatus = WLANBAP_Stop(pVosContext);
8291 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8292 {
8293 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8294 "%s: Failed to stop BAP",__func__);
8295 }
8296#endif //WLAN_BTAMP_FEATURE
8297
8298 //Stop all the modules
8299 vosStatus = vos_stop( pVosContext );
8300 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8301 {
8302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8303 "%s: Failed to stop VOSS",__func__);
8304 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8305 }
8306
Jeff Johnson295189b2012-06-20 16:38:30 -07008307 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008308 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008309
8310 //Close the scheduler before calling vos_close to make sure no thread is
8311 // scheduled after the each module close is called i.e after all the data
8312 // structures are freed.
8313 vosStatus = vos_sched_close( pVosContext );
8314 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8315 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8316 "%s: Failed to close VOSS Scheduler",__func__);
8317 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8318 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008319#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008320#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8321 /* Destroy the wake lock */
8322 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8323#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008324 /* Destroy the wake lock */
8325 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008326#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008327
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308328#ifdef CONFIG_ENABLE_LINUX_REG
8329 vosStatus = vos_nv_close();
8330 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8331 {
8332 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8333 "%s: Failed to close NV", __func__);
8334 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8335 }
8336#endif
8337
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 //Close VOSS
8339 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8340 vos_close(pVosContext);
8341
Jeff Johnson295189b2012-06-20 16:38:30 -07008342 //Close Watchdog
8343 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8344 vos_watchdog_close(pVosContext);
8345
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308346 //Clean up HDD Nlink Service
8347 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308348
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308349#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308350 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308351 {
8352 wlan_logging_sock_deactivate_svc();
8353 }
8354#endif
8355
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308356#ifdef WLAN_KD_READY_NOTIFIER
8357 nl_srv_exit(pHddCtx->ptt_pid);
8358#else
8359 nl_srv_exit();
8360#endif /* WLAN_KD_READY_NOTIFIER */
8361
8362
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 hdd_close_all_adapters( pHddCtx );
8364
Jeff Johnson295189b2012-06-20 16:38:30 -07008365 /* free the power on lock from platform driver */
8366 if (free_riva_power_on_lock("wlan"))
8367 {
8368 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8369 __func__);
8370 }
8371
Jeff Johnson88ba7742013-02-27 14:36:02 -08008372free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308373
8374 //Free up dynamically allocated members inside HDD Adapter
8375 if (pHddCtx->cfg_ini)
8376 {
8377 kfree(pHddCtx->cfg_ini);
8378 pHddCtx->cfg_ini= NULL;
8379 }
8380
Leo Changf04ddad2013-09-18 13:46:38 -07008381 /* FTM mode, WIPHY did not registered
8382 If un-register here, system crash will happen */
8383 if (VOS_FTM_MODE != hdd_get_conparam())
8384 {
8385 wiphy_unregister(wiphy) ;
8386 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008388 if (hdd_is_ssr_required())
8389 {
8390 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008391 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 msleep(5000);
8393 }
8394 hdd_set_ssr_required (VOS_FALSE);
8395}
8396
8397
8398/**---------------------------------------------------------------------------
8399
8400 \brief hdd_update_config_from_nv() - Function to update the contents of
8401 the running configuration with parameters taken from NV storage
8402
8403 \param - pHddCtx - Pointer to the HDD global context
8404
8405 \return - VOS_STATUS_SUCCESS if successful
8406
8407 --------------------------------------------------------------------------*/
8408static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8409{
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 v_BOOL_t itemIsValid = VOS_FALSE;
8411 VOS_STATUS status;
8412 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8413 v_U8_t macLoop;
8414
8415 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8416 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8417 if(status != VOS_STATUS_SUCCESS)
8418 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008419 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008420 return VOS_STATUS_E_FAILURE;
8421 }
8422
8423 if (itemIsValid == VOS_TRUE)
8424 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008425 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8427 VOS_MAX_CONCURRENCY_PERSONA);
8428 if(status != VOS_STATUS_SUCCESS)
8429 {
8430 /* Get MAC from NV fail, not update CFG info
8431 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008432 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 return VOS_STATUS_E_FAILURE;
8434 }
8435
8436 /* If first MAC is not valid, treat all others are not valid
8437 * Then all MACs will be got from ini file */
8438 if(vos_is_macaddr_zero(&macFromNV[0]))
8439 {
8440 /* MAC address in NV file is not configured yet */
8441 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8442 return VOS_STATUS_E_INVAL;
8443 }
8444
8445 /* Get MAC address from NV, update CFG info */
8446 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8447 {
8448 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8449 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308450 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 /* This MAC is not valid, skip it
8452 * This MAC will be got from ini file */
8453 }
8454 else
8455 {
8456 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8457 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8458 VOS_MAC_ADDR_SIZE);
8459 }
8460 }
8461 }
8462 else
8463 {
8464 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8465 return VOS_STATUS_E_FAILURE;
8466 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008467
Jeff Johnson295189b2012-06-20 16:38:30 -07008468
8469 return VOS_STATUS_SUCCESS;
8470}
8471
8472/**---------------------------------------------------------------------------
8473
8474 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8475
8476 \param - pAdapter - Pointer to the HDD
8477
8478 \return - None
8479
8480 --------------------------------------------------------------------------*/
8481VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8482{
8483 eHalStatus halStatus;
8484 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308485 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008486
Jeff Johnson295189b2012-06-20 16:38:30 -07008487
8488 // Send ready indication to the HDD. This will kick off the MAC
8489 // into a 'running' state and should kick off an initial scan.
8490 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8491 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8492 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308493 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008494 "code %08d [x%08x]",__func__, halStatus, halStatus );
8495 return VOS_STATUS_E_FAILURE;
8496 }
8497
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308498 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8500 // And RIVA will crash
8501 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8502 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308503 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8504 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8505
8506
Jeff Johnson295189b2012-06-20 16:38:30 -07008507 return VOS_STATUS_SUCCESS;
8508}
8509
Jeff Johnson295189b2012-06-20 16:38:30 -07008510/* wake lock APIs for HDD */
8511void hdd_prevent_suspend(void)
8512{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008513#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008514 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008515#else
8516 wcnss_prevent_suspend();
8517#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008518}
8519
8520void hdd_allow_suspend(void)
8521{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008522#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008523 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008524#else
8525 wcnss_allow_suspend();
8526#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008527}
8528
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308529void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008530{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008531#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008532 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008533#else
8534 /* Do nothing as there is no API in wcnss for timeout*/
8535#endif
8536}
8537
Jeff Johnson295189b2012-06-20 16:38:30 -07008538/**---------------------------------------------------------------------------
8539
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008540 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8541 information between Host and Riva
8542
8543 This function gets reported version of FW
8544 It also finds the version of Riva headers used to compile the host
8545 It compares the above two and prints a warning if they are different
8546 It gets the SW and HW version string
8547 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8548 indicating the features they support through a bitmap
8549
8550 \param - pHddCtx - Pointer to HDD context
8551
8552 \return - void
8553
8554 --------------------------------------------------------------------------*/
8555
8556void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8557{
8558
8559 tSirVersionType versionCompiled;
8560 tSirVersionType versionReported;
8561 tSirVersionString versionString;
8562 tANI_U8 fwFeatCapsMsgSupported = 0;
8563 VOS_STATUS vstatus;
8564
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008565 memset(&versionCompiled, 0, sizeof(versionCompiled));
8566 memset(&versionReported, 0, sizeof(versionReported));
8567
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008568 /* retrieve and display WCNSS version information */
8569 do {
8570
8571 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8572 &versionCompiled);
8573 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8574 {
8575 hddLog(VOS_TRACE_LEVEL_FATAL,
8576 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008577 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008578 break;
8579 }
8580
8581 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8582 &versionReported);
8583 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8584 {
8585 hddLog(VOS_TRACE_LEVEL_FATAL,
8586 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008587 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008588 break;
8589 }
8590
8591 if ((versionCompiled.major != versionReported.major) ||
8592 (versionCompiled.minor != versionReported.minor) ||
8593 (versionCompiled.version != versionReported.version) ||
8594 (versionCompiled.revision != versionReported.revision))
8595 {
8596 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8597 "Host expected %u.%u.%u.%u\n",
8598 WLAN_MODULE_NAME,
8599 (int)versionReported.major,
8600 (int)versionReported.minor,
8601 (int)versionReported.version,
8602 (int)versionReported.revision,
8603 (int)versionCompiled.major,
8604 (int)versionCompiled.minor,
8605 (int)versionCompiled.version,
8606 (int)versionCompiled.revision);
8607 }
8608 else
8609 {
8610 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8611 WLAN_MODULE_NAME,
8612 (int)versionReported.major,
8613 (int)versionReported.minor,
8614 (int)versionReported.version,
8615 (int)versionReported.revision);
8616 }
8617
8618 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8619 versionString,
8620 sizeof(versionString));
8621 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8622 {
8623 hddLog(VOS_TRACE_LEVEL_FATAL,
8624 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008625 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008626 break;
8627 }
8628
8629 pr_info("%s: WCNSS software version %s\n",
8630 WLAN_MODULE_NAME, versionString);
8631
8632 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8633 versionString,
8634 sizeof(versionString));
8635 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8636 {
8637 hddLog(VOS_TRACE_LEVEL_FATAL,
8638 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008639 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008640 break;
8641 }
8642
8643 pr_info("%s: WCNSS hardware version %s\n",
8644 WLAN_MODULE_NAME, versionString);
8645
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008646 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8647 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008648 send the message only if it the riva is 1.1
8649 minor numbers for different riva branches:
8650 0 -> (1.0)Mainline Build
8651 1 -> (1.1)Mainline Build
8652 2->(1.04) Stability Build
8653 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008654 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008655 ((versionReported.minor>=1) && (versionReported.version>=1)))
8656 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8657 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008658
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008659 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008660 {
8661#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8662 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8663 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8664#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008665 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8666 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8667 {
8668 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8669 }
8670
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008671 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008672 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008673
8674 } while (0);
8675
8676}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308677void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8678{
8679 struct sk_buff *skb;
8680 struct nlmsghdr *nlh;
8681 tAniMsgHdr *ani_hdr;
8682
8683 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8684
8685 if(skb == NULL) {
8686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8687 "%s: alloc_skb failed", __func__);
8688 return;
8689 }
8690
8691 nlh = (struct nlmsghdr *)skb->data;
8692 nlh->nlmsg_pid = 0; /* from kernel */
8693 nlh->nlmsg_flags = 0;
8694 nlh->nlmsg_seq = 0;
8695 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8696
8697 ani_hdr = NLMSG_DATA(nlh);
8698 ani_hdr->type = type;
8699
8700 switch(type) {
8701 case WLAN_SVC_SAP_RESTART_IND:
8702 ani_hdr->length = 0;
8703 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8704 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8705 break;
8706 default:
8707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8708 "Attempt to send unknown nlink message %d", type);
8709 kfree_skb(skb);
8710 return;
8711 }
8712
8713 nl_srv_bcast(skb);
8714
8715 return;
8716}
8717
8718
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008719
8720/**---------------------------------------------------------------------------
8721
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308722 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8723
8724 \param - pHddCtx - Pointer to the hdd context
8725
8726 \return - true if hardware supports 5GHz
8727
8728 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308729boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308730{
8731 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8732 * then hardware support 5Ghz.
8733 */
8734 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8735 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308737 return true;
8738 }
8739 else
8740 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308742 __func__);
8743 return false;
8744 }
8745}
8746
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308747/**---------------------------------------------------------------------------
8748
8749 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8750 generate function
8751
8752 This is generate the random mac address for WLAN interface
8753
8754 \param - pHddCtx - Pointer to HDD context
8755 idx - Start interface index to get auto
8756 generated mac addr.
8757 mac_addr - Mac address
8758
8759 \return - 0 for success, < 0 for failure
8760
8761 --------------------------------------------------------------------------*/
8762
8763static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8764 int idx, v_MACADDR_t mac_addr)
8765{
8766 int i;
8767 unsigned int serialno;
8768 serialno = wcnss_get_serial_number();
8769
8770 if (0 != serialno)
8771 {
8772 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8773 bytes of the serial number that can be used to generate
8774 the other 3 bytes of the MAC address. Mask off all but
8775 the lower 3 bytes (this will also make sure we don't
8776 overflow in the next step) */
8777 serialno &= 0x00FFFFFF;
8778
8779 /* we need a unique address for each session */
8780 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8781
8782 /* autogen other Mac addresses */
8783 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8784 {
8785 /* start with the entire default address */
8786 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8787 /* then replace the lower 3 bytes */
8788 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8789 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8790 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8791
8792 serialno++;
8793 hddLog(VOS_TRACE_LEVEL_ERROR,
8794 "%s: Derived Mac Addr: "
8795 MAC_ADDRESS_STR, __func__,
8796 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8797 }
8798
8799 }
8800 else
8801 {
8802 hddLog(LOGE, FL("Failed to Get Serial NO"));
8803 return -1;
8804 }
8805 return 0;
8806}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308807
8808/**---------------------------------------------------------------------------
8809
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308810 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8811 completed to flush out the scan results
8812
8813 11d scan is done during driver load and is a passive scan on all
8814 channels supported by the device, 11d scans may find some APs on
8815 frequencies which are forbidden to be used in the regulatory domain
8816 the device is operating in. If these APs are notified to the supplicant
8817 it may try to connect to these APs, thus flush out all the scan results
8818 which are present in SME after 11d scan is done.
8819
8820 \return - eHalStatus
8821
8822 --------------------------------------------------------------------------*/
8823static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8824 tANI_U32 scanId, eCsrScanStatus status)
8825{
8826 ENTER();
8827
8828 sme_ScanFlushResult(halHandle, 0);
8829
8830 EXIT();
8831
8832 return eHAL_STATUS_SUCCESS;
8833}
8834
8835/**---------------------------------------------------------------------------
8836
Jeff Johnson295189b2012-06-20 16:38:30 -07008837 \brief hdd_wlan_startup() - HDD init function
8838
8839 This is the driver startup code executed once a WLAN device has been detected
8840
8841 \param - dev - Pointer to the underlying device
8842
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008843 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008844
8845 --------------------------------------------------------------------------*/
8846
8847int hdd_wlan_startup(struct device *dev )
8848{
8849 VOS_STATUS status;
8850 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008851 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008852 hdd_context_t *pHddCtx = NULL;
8853 v_CONTEXT_t pVosContext= NULL;
8854#ifdef WLAN_BTAMP_FEATURE
8855 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8856 WLANBAP_ConfigType btAmpConfig;
8857 hdd_config_t *pConfig;
8858#endif
8859 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008860 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308861 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008862
8863 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008864 /*
8865 * cfg80211: wiphy allocation
8866 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308867 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008868
8869 if(wiphy == NULL)
8870 {
8871 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008872 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008873 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008874 pHddCtx = wiphy_priv(wiphy);
8875
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 //Initialize the adapter context to zeros.
8877 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8878
Jeff Johnson295189b2012-06-20 16:38:30 -07008879 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308881 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008882
8883 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8884
8885 /*Get vos context here bcoz vos_open requires it*/
8886 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8887
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008888 if(pVosContext == NULL)
8889 {
8890 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8891 goto err_free_hdd_context;
8892 }
8893
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 //Save the Global VOSS context in adapter context for future.
8895 pHddCtx->pvosContext = pVosContext;
8896
8897 //Save the adapter context in global context for future.
8898 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8899
Jeff Johnson295189b2012-06-20 16:38:30 -07008900 pHddCtx->parent_dev = dev;
8901
8902 init_completion(&pHddCtx->full_pwr_comp_var);
8903 init_completion(&pHddCtx->standby_comp_var);
8904 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008905 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008906 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308907 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308908 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008909
8910#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008911 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008912#else
8913 init_completion(&pHddCtx->driver_crda_req);
8914#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008915
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308916 spin_lock_init(&pHddCtx->schedScan_lock);
8917
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8919
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308920#ifdef FEATURE_WLAN_TDLS
8921 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8922 * invoked by other instances also) to protect the concurrent
8923 * access for the Adapters by TDLS module.
8924 */
8925 mutex_init(&pHddCtx->tdls_lock);
8926#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05308927 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Agarwal Ashish1f422872014-07-22 00:11:55 +05308928 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308929
Agarwal Ashish1f422872014-07-22 00:11:55 +05308930 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 // Load all config first as TL config is needed during vos_open
8932 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8933 if(pHddCtx->cfg_ini == NULL)
8934 {
8935 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8936 goto err_free_hdd_context;
8937 }
8938
8939 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8940
8941 // Read and parse the qcom_cfg.ini file
8942 status = hdd_parse_config_ini( pHddCtx );
8943 if ( VOS_STATUS_SUCCESS != status )
8944 {
8945 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8946 __func__, WLAN_INI_FILE);
8947 goto err_config;
8948 }
Arif Hussaind5218912013-12-05 01:10:55 -08008949#ifdef MEMORY_DEBUG
8950 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8951 vos_mem_init();
8952
8953 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8954 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8955#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008956
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308957 /* INI has been read, initialise the configuredMcastBcastFilter with
8958 * INI value as this will serve as the default value
8959 */
8960 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8961 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8962 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308963
8964 if (false == hdd_is_5g_supported(pHddCtx))
8965 {
8966 //5Ghz is not supported.
8967 if (1 != pHddCtx->cfg_ini->nBandCapability)
8968 {
8969 hddLog(VOS_TRACE_LEVEL_INFO,
8970 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8971 pHddCtx->cfg_ini->nBandCapability = 1;
8972 }
8973 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308974
8975 /* If SNR Monitoring is enabled, FW has to parse all beacons
8976 * for calcaluting and storing the average SNR, so set Nth beacon
8977 * filter to 1 to enable FW to parse all the beaocons
8978 */
8979 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8980 {
8981 /* The log level is deliberately set to WARN as overriding
8982 * nthBeaconFilter to 1 will increase power cosumption and this
8983 * might just prove helpful to detect the power issue.
8984 */
8985 hddLog(VOS_TRACE_LEVEL_WARN,
8986 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8987 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8988 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308990 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008992 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008993 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008994 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8995 {
8996 hddLog(VOS_TRACE_LEVEL_FATAL,
8997 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8998 goto err_config;
8999 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009001
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009002 // Update VOS trace levels based upon the cfg.ini
9003 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9004 pHddCtx->cfg_ini->vosTraceEnableBAP);
9005 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9006 pHddCtx->cfg_ini->vosTraceEnableTL);
9007 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9008 pHddCtx->cfg_ini->vosTraceEnableWDI);
9009 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9010 pHddCtx->cfg_ini->vosTraceEnableHDD);
9011 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9012 pHddCtx->cfg_ini->vosTraceEnableSME);
9013 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9014 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309015 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9016 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009017 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9018 pHddCtx->cfg_ini->vosTraceEnableWDA);
9019 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9020 pHddCtx->cfg_ini->vosTraceEnableSYS);
9021 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9022 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009023 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9024 pHddCtx->cfg_ini->vosTraceEnableSAP);
9025 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9026 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009027
Jeff Johnson295189b2012-06-20 16:38:30 -07009028 // Update WDI trace levels based upon the cfg.ini
9029 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9030 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9031 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9032 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9033 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9034 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9035 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9036 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009037
Jeff Johnson88ba7742013-02-27 14:36:02 -08009038 if (VOS_FTM_MODE == hdd_get_conparam())
9039 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9041 {
9042 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9043 goto err_free_hdd_context;
9044 }
9045 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05309046
9047 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009049 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009050
Jeff Johnson88ba7742013-02-27 14:36:02 -08009051 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9053 {
9054 status = vos_watchdog_open(pVosContext,
9055 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9056
9057 if(!VOS_IS_STATUS_SUCCESS( status ))
9058 {
9059 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309060 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 }
9062 }
9063
9064 pHddCtx->isLogpInProgress = FALSE;
9065 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9066
Amar Singhala49cbc52013-10-08 18:37:44 -07009067#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009068 /* initialize the NV module. This is required so that
9069 we can initialize the channel information in wiphy
9070 from the NV.bin data. The channel information in
9071 wiphy needs to be initialized before wiphy registration */
9072
9073 status = vos_nv_open();
9074 if (!VOS_IS_STATUS_SUCCESS(status))
9075 {
9076 /* NV module cannot be initialized */
9077 hddLog( VOS_TRACE_LEVEL_FATAL,
9078 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309079 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009080 }
9081
9082 status = vos_init_wiphy_from_nv_bin();
9083 if (!VOS_IS_STATUS_SUCCESS(status))
9084 {
9085 /* NV module cannot be initialized */
9086 hddLog( VOS_TRACE_LEVEL_FATAL,
9087 "%s: vos_init_wiphy failed", __func__);
9088 goto err_vos_nv_close;
9089 }
9090
Amar Singhala49cbc52013-10-08 18:37:44 -07009091#endif
9092
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309093 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009094 if ( !VOS_IS_STATUS_SUCCESS( status ))
9095 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009096 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309097 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009098 }
9099
Jeff Johnson295189b2012-06-20 16:38:30 -07009100 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9101
9102 if ( NULL == pHddCtx->hHal )
9103 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009104 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009105 goto err_vosclose;
9106 }
9107
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009108 status = vos_preStart( pHddCtx->pvosContext );
9109 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9110 {
9111 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309112 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009113 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009114
Arif Hussaineaf68602013-12-30 23:10:44 -08009115 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9116 {
9117 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9118 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9119 __func__, enable_dfs_chan_scan);
9120 }
9121 if (0 == enable_11d || 1 == enable_11d)
9122 {
9123 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9124 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9125 __func__, enable_11d);
9126 }
9127
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009128 /* Note that the vos_preStart() sequence triggers the cfg download.
9129 The cfg download must occur before we update the SME config
9130 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 status = hdd_set_sme_config( pHddCtx );
9132
9133 if ( VOS_STATUS_SUCCESS != status )
9134 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009135 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309136 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009137 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009138
Jeff Johnson295189b2012-06-20 16:38:30 -07009139 /* In the integrated architecture we update the configuration from
9140 the INI file and from NV before vOSS has been started so that
9141 the final contents are available to send down to the cCPU */
9142
9143 // Apply the cfg.ini to cfg.dat
9144 if (FALSE == hdd_update_config_dat(pHddCtx))
9145 {
9146 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309147 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009148 }
9149
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309150 // Get mac addr from platform driver
9151 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9152
9153 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309155 /* Store the mac addr for first interface */
9156 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9157
9158 hddLog(VOS_TRACE_LEVEL_ERROR,
9159 "%s: WLAN Mac Addr: "
9160 MAC_ADDRESS_STR, __func__,
9161 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9162
9163 /* Here, passing Arg2 as 1 because we do not want to change the
9164 last 3 bytes (means non OUI bytes) of first interface mac
9165 addr.
9166 */
9167 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9168 {
9169 hddLog(VOS_TRACE_LEVEL_ERROR,
9170 "%s: Failed to generate wlan interface mac addr "
9171 "using MAC from ini file ", __func__);
9172 }
9173 }
9174 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9175 {
9176 // Apply the NV to cfg.dat
9177 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009178#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9179 /* There was not a valid set of MAC Addresses in NV. See if the
9180 default addresses were modified by the cfg.ini settings. If so,
9181 we'll use them, but if not, we'll autogenerate a set of MAC
9182 addresses based upon the device serial number */
9183
9184 static const v_MACADDR_t default_address =
9185 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009186
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309187 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9188 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 {
9190 /* cfg.ini has the default address, invoke autogen logic */
9191
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309192 /* Here, passing Arg2 as 0 because we want to change the
9193 last 3 bytes (means non OUI bytes) of all the interfaces
9194 mac addr.
9195 */
9196 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9197 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309199 hddLog(VOS_TRACE_LEVEL_ERROR,
9200 "%s: Failed to generate wlan interface mac addr "
9201 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9202 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 }
9205 else
9206#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9207 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009208 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 "%s: Invalid MAC address in NV, using MAC from ini file "
9210 MAC_ADDRESS_STR, __func__,
9211 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9212 }
9213 }
9214 {
9215 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309216
9217 /* Set the MAC Address Currently this is used by HAL to
9218 * add self sta. Remove this once self sta is added as
9219 * part of session open.
9220 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009221 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9222 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9223 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309224
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 if (!HAL_STATUS_SUCCESS( halStatus ))
9226 {
9227 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9228 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309229 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009230 }
9231 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009232
9233 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9234 Note: Firmware image will be read and downloaded inside vos_start API */
9235 status = vos_start( pHddCtx->pvosContext );
9236 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9237 {
9238 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309239 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 }
9241
Leo Chang6cec3e22014-01-21 15:33:49 -08009242#ifdef FEATURE_WLAN_CH_AVOID
9243 /* Plug in avoid channel notification callback
9244 * This should happen before ADD_SELF_STA
9245 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309246
9247 /* check the Channel Avoidance is enabled */
9248 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9249 {
9250 sme_AddChAvoidCallback(pHddCtx->hHal,
9251 hdd_hostapd_ch_avoid_cb);
9252 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009253#endif /* FEATURE_WLAN_CH_AVOID */
9254
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009255 /* Exchange capability info between Host and FW and also get versioning info from FW */
9256 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009257
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309258#ifdef CONFIG_ENABLE_LINUX_REG
9259 status = wlan_hdd_init_channels(pHddCtx);
9260 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9261 {
9262 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9263 __func__);
9264 goto err_vosstop;
9265 }
9266#endif
9267
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 status = hdd_post_voss_start_config( pHddCtx );
9269 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9270 {
9271 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9272 __func__);
9273 goto err_vosstop;
9274 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009275
9276#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309277 wlan_hdd_cfg80211_update_reg_info( wiphy );
9278
9279 /* registration of wiphy dev with cfg80211 */
9280 if (0 > wlan_hdd_cfg80211_register(wiphy))
9281 {
9282 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9283 goto err_vosstop;
9284 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009285#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009286
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309287#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309288 /* registration of wiphy dev with cfg80211 */
9289 if (0 > wlan_hdd_cfg80211_register(wiphy))
9290 {
9291 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9292 goto err_vosstop;
9293 }
9294
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309295 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309296 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9297 {
9298 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9299 __func__);
9300 goto err_unregister_wiphy;
9301 }
9302#endif
9303
c_hpothu4a298be2014-12-22 21:12:51 +05309304 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9305
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9307 {
9308 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9309 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9310 }
9311 else
9312 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9314 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9315 if (pAdapter != NULL)
9316 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309317 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309319 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9320 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9321 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009322
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309323 /* Generate the P2P Device Address. This consists of the device's
9324 * primary MAC address with the locally administered bit set.
9325 */
9326 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009327 }
9328 else
9329 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309330 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9331 if (p2p_dev_addr != NULL)
9332 {
9333 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9334 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9335 }
9336 else
9337 {
9338 hddLog(VOS_TRACE_LEVEL_FATAL,
9339 "%s: Failed to allocate mac_address for p2p_device",
9340 __func__);
9341 goto err_close_adapter;
9342 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009344
9345 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9346 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9347 if ( NULL == pP2pAdapter )
9348 {
9349 hddLog(VOS_TRACE_LEVEL_FATAL,
9350 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009351 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009352 goto err_close_adapter;
9353 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009354 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009355 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009356
9357 if( pAdapter == NULL )
9358 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009359 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9360 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009362
Arif Hussain66559122013-11-21 10:11:40 -08009363 if (country_code)
9364 {
9365 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009366 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009367 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9368#ifndef CONFIG_ENABLE_LINUX_REG
9369 hdd_checkandupdate_phymode(pAdapter, country_code);
9370#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009371 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9372 (void *)(tSmeChangeCountryCallback)
9373 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009374 country_code,
9375 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309376 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009377 if (eHAL_STATUS_SUCCESS == ret)
9378 {
Arif Hussaincb607082013-12-20 11:57:42 -08009379 ret = wait_for_completion_interruptible_timeout(
9380 &pAdapter->change_country_code,
9381 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9382
9383 if (0 >= ret)
9384 {
9385 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9386 "%s: SME while setting country code timed out", __func__);
9387 }
Arif Hussain66559122013-11-21 10:11:40 -08009388 }
9389 else
9390 {
Arif Hussaincb607082013-12-20 11:57:42 -08009391 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9392 "%s: SME Change Country code from module param fail ret=%d",
9393 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009394 }
9395 }
9396
Jeff Johnson295189b2012-06-20 16:38:30 -07009397#ifdef WLAN_BTAMP_FEATURE
9398 vStatus = WLANBAP_Open(pVosContext);
9399 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9400 {
9401 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9402 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009403 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009404 }
9405
9406 vStatus = BSL_Init(pVosContext);
9407 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9408 {
9409 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9410 "%s: Failed to Init BSL",__func__);
9411 goto err_bap_close;
9412 }
9413 vStatus = WLANBAP_Start(pVosContext);
9414 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9415 {
9416 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9417 "%s: Failed to start TL",__func__);
9418 goto err_bap_close;
9419 }
9420
9421 pConfig = pHddCtx->cfg_ini;
9422 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9423 status = WLANBAP_SetConfig(&btAmpConfig);
9424
9425#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009426
Mihir Shete9c238772014-10-15 14:35:16 +05309427 /*
9428 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9429 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9430 * which is greater than 0xf. So the below check is safe to make
9431 * sure that there is no entry for UapsdMask in the ini
9432 */
9433 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9434 {
9435 if(IS_DYNAMIC_WMM_PS_ENABLED)
9436 {
9437 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9438 __func__);
9439 pHddCtx->cfg_ini->UapsdMask =
9440 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9441 }
9442 else
9443 {
9444 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9445 __func__);
9446 pHddCtx->cfg_ini->UapsdMask =
9447 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9448 }
9449 }
9450
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009451#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9452 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9453 {
9454 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9455 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9456 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9457 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9458 }
9459#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009460
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309461 wlan_hdd_tdls_init(pHddCtx);
9462
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309463 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9464
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 /* Register with platform driver as client for Suspend/Resume */
9466 status = hddRegisterPmOps(pHddCtx);
9467 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9468 {
9469 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9470#ifdef WLAN_BTAMP_FEATURE
9471 goto err_bap_stop;
9472#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009473 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009474#endif //WLAN_BTAMP_FEATURE
9475 }
9476
Yue Ma0d4891e2013-08-06 17:01:45 -07009477 /* Open debugfs interface */
9478 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9479 {
9480 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9481 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009482 }
9483
Jeff Johnson295189b2012-06-20 16:38:30 -07009484 /* Register TM level change handler function to the platform */
9485 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9486 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9487 {
9488 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9489 goto err_unregister_pmops;
9490 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009491
9492 /* register for riva power on lock to platform driver */
9493 if (req_riva_power_on_lock("wlan"))
9494 {
9495 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9496 __func__);
9497 goto err_unregister_pmops;
9498 }
9499
Jeff Johnson295189b2012-06-20 16:38:30 -07009500 // register net device notifier for device change notification
9501 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9502
9503 if(ret < 0)
9504 {
9505 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9506 goto err_free_power_on_lock;
9507 }
9508
9509 //Initialize the nlink service
9510 if(nl_srv_init() != 0)
9511 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309512 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 goto err_reg_netdev;
9514 }
9515
Leo Chang4ce1cc52013-10-21 18:27:15 -07009516#ifdef WLAN_KD_READY_NOTIFIER
9517 pHddCtx->kd_nl_init = 1;
9518#endif /* WLAN_KD_READY_NOTIFIER */
9519
Jeff Johnson295189b2012-06-20 16:38:30 -07009520 //Initialize the BTC service
9521 if(btc_activate_service(pHddCtx) != 0)
9522 {
9523 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9524 goto err_nl_srv;
9525 }
9526
9527#ifdef PTT_SOCK_SVC_ENABLE
9528 //Initialize the PTT service
9529 if(ptt_sock_activate_svc(pHddCtx) != 0)
9530 {
9531 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9532 goto err_nl_srv;
9533 }
9534#endif
9535
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309536#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9537 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9538 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309539 if(wlan_logging_sock_activate_svc(
9540 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9541 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9542 {
9543 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9544 " failed", __func__);
9545 goto err_nl_srv;
9546 }
9547 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9548 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309549 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9550 pHddCtx->cfg_ini->gEnableDebugLog =
9551 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309552 }
9553#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009555 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009557 /* Action frame registered in one adapter which will
9558 * applicable to all interfaces
9559 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309560 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009562
9563 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309564 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009565
Jeff Johnson295189b2012-06-20 16:38:30 -07009566
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009567#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009568#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9569 /* Initialize the wake lcok */
9570 wake_lock_init(&pHddCtx->rx_wake_lock,
9571 WAKE_LOCK_SUSPEND,
9572 "qcom_rx_wakelock");
9573#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009574 /* Initialize the wake lcok */
9575 wake_lock_init(&pHddCtx->sap_wake_lock,
9576 WAKE_LOCK_SUSPEND,
9577 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009578#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009579
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009580 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9581 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009582
Katya Nigam5c306ea2014-06-19 15:39:54 +05309583 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9585 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309586
9587#ifdef FEATURE_WLAN_SCAN_PNO
9588 /*SME must send channel update configuration to RIVA*/
9589 sme_UpdateChannelConfig(pHddCtx->hHal);
9590#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309591 /* Send the update default channel list to the FW*/
9592 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309593#ifndef CONFIG_ENABLE_LINUX_REG
9594 /*updating wiphy so that regulatory user hints can be processed*/
9595 if (wiphy)
9596 {
9597 regulatory_hint(wiphy, "00");
9598 }
9599#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009600 // Initialize the restart logic
9601 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309602
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009603 //Register the traffic monitor timer now
9604 if ( pHddCtx->cfg_ini->dynSplitscan)
9605 {
9606 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9607 VOS_TIMER_TYPE_SW,
9608 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9609 (void *)pHddCtx);
9610 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309611#ifdef WLAN_FEATURE_EXTSCAN
9612 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9613 wlan_hdd_cfg80211_extscan_callback,
9614 pHddCtx);
9615#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309616
9617#ifdef WLAN_NS_OFFLOAD
9618 // Register IPv6 notifier to notify if any change in IP
9619 // So that we can reconfigure the offload parameters
9620 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
9621 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
9622 if (ret)
9623 {
9624 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
9625 }
9626 else
9627 {
9628 hddLog(LOGE, FL("Registered IPv6 notifier"));
9629 }
9630#endif
9631
9632 // Register IPv4 notifier to notify if any change in IP
9633 // So that we can reconfigure the offload parameters
9634 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
9635 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
9636 if (ret)
9637 {
9638 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
9639 }
9640 else
9641 {
9642 hddLog(LOGE, FL("Registered IPv4 notifier"));
9643 }
9644
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 goto success;
9646
9647err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009648#ifdef WLAN_KD_READY_NOTIFIER
9649 nl_srv_exit(pHddCtx->ptt_pid);
9650#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009652#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009653err_reg_netdev:
9654 unregister_netdevice_notifier(&hdd_netdev_notifier);
9655
9656err_free_power_on_lock:
9657 free_riva_power_on_lock("wlan");
9658
9659err_unregister_pmops:
9660 hddDevTmUnregisterNotifyCallback(pHddCtx);
9661 hddDeregisterPmOps(pHddCtx);
9662
Yue Ma0d4891e2013-08-06 17:01:45 -07009663 hdd_debugfs_exit(pHddCtx);
9664
Jeff Johnson295189b2012-06-20 16:38:30 -07009665#ifdef WLAN_BTAMP_FEATURE
9666err_bap_stop:
9667 WLANBAP_Stop(pVosContext);
9668#endif
9669
9670#ifdef WLAN_BTAMP_FEATURE
9671err_bap_close:
9672 WLANBAP_Close(pVosContext);
9673#endif
9674
Jeff Johnson295189b2012-06-20 16:38:30 -07009675err_close_adapter:
9676 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309677#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309678err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309679#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309680 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009681err_vosstop:
9682 vos_stop(pVosContext);
9683
Amar Singhala49cbc52013-10-08 18:37:44 -07009684err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009685 status = vos_sched_close( pVosContext );
9686 if (!VOS_IS_STATUS_SUCCESS(status)) {
9687 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9688 "%s: Failed to close VOSS Scheduler", __func__);
9689 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9690 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009691 vos_close(pVosContext );
9692
Amar Singhal0a402232013-10-11 20:57:16 -07009693err_vos_nv_close:
9694
c_hpothue6a36282014-03-19 12:27:38 +05309695#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009696 vos_nv_close();
9697
c_hpothu70f8d812014-03-22 22:59:23 +05309698#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009699
9700err_wdclose:
9701 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9702 vos_watchdog_close(pVosContext);
9703
Jeff Johnson295189b2012-06-20 16:38:30 -07009704err_config:
9705 kfree(pHddCtx->cfg_ini);
9706 pHddCtx->cfg_ini= NULL;
9707
9708err_free_hdd_context:
9709 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 wiphy_free(wiphy) ;
9711 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 VOS_BUG(1);
9713
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009714 if (hdd_is_ssr_required())
9715 {
9716 /* WDI timeout had happened during load, so SSR is needed here */
9717 subsystem_restart("wcnss");
9718 msleep(5000);
9719 }
9720 hdd_set_ssr_required (VOS_FALSE);
9721
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009722 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009723
9724success:
9725 EXIT();
9726 return 0;
9727}
9728
9729/**---------------------------------------------------------------------------
9730
Jeff Johnson32d95a32012-09-10 13:15:23 -07009731 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009732
Jeff Johnson32d95a32012-09-10 13:15:23 -07009733 This is the driver entry point - called in different timeline depending
9734 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009735
9736 \param - None
9737
9738 \return - 0 for success, non zero for failure
9739
9740 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009741static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009742{
9743 VOS_STATUS status;
9744 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 struct device *dev = NULL;
9746 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009747#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9748 int max_retries = 0;
9749#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009750
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309751#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9752 wlan_logging_sock_init_svc();
9753#endif
9754
Jeff Johnson295189b2012-06-20 16:38:30 -07009755 ENTER();
9756
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009757#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009759#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009760
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309761 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9763 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9764
Jeff Johnson295189b2012-06-20 16:38:30 -07009765#ifdef ANI_BUS_TYPE_PCI
9766
9767 dev = wcnss_wlan_get_device();
9768
9769#endif // ANI_BUS_TYPE_PCI
9770
9771#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009772
9773#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9774 /* wait until WCNSS driver downloads NV */
9775 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9776 msleep(1000);
9777 }
9778 if (max_retries >= 5) {
9779 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309780#ifdef WLAN_OPEN_SOURCE
9781 wake_lock_destroy(&wlan_wake_lock);
9782#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309783
9784#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9785 wlan_logging_sock_deinit_svc();
9786#endif
9787
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009788 return -ENODEV;
9789 }
9790#endif
9791
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 dev = wcnss_wlan_get_device();
9793#endif // ANI_BUS_TYPE_PLATFORM
9794
9795
9796 do {
9797 if (NULL == dev) {
9798 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9799 ret_status = -1;
9800 break;
9801 }
9802
Jeff Johnson295189b2012-06-20 16:38:30 -07009803#ifdef TIMER_MANAGER
9804 vos_timer_manager_init();
9805#endif
9806
9807 /* Preopen VOSS so that it is ready to start at least SAL */
9808 status = vos_preOpen(&pVosContext);
9809
9810 if (!VOS_IS_STATUS_SUCCESS(status))
9811 {
9812 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9813 ret_status = -1;
9814 break;
9815 }
9816
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009817#ifndef MODULE
9818 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9819 */
9820 hdd_set_conparam((v_UINT_t)con_mode);
9821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009822
9823 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009824 if (hdd_wlan_startup(dev))
9825 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009827 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 vos_preClose( &pVosContext );
9829 ret_status = -1;
9830 break;
9831 }
9832
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 } while (0);
9834
9835 if (0 != ret_status)
9836 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009837#ifdef TIMER_MANAGER
9838 vos_timer_exit();
9839#endif
9840#ifdef MEMORY_DEBUG
9841 vos_mem_exit();
9842#endif
9843
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009844#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009846#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309847
9848#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9849 wlan_logging_sock_deinit_svc();
9850#endif
9851
Jeff Johnson295189b2012-06-20 16:38:30 -07009852 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9853 }
9854 else
9855 {
9856 //Send WLAN UP indication to Nlink Service
9857 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9858
9859 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 }
9861
9862 EXIT();
9863
9864 return ret_status;
9865}
9866
Jeff Johnson32d95a32012-09-10 13:15:23 -07009867/**---------------------------------------------------------------------------
9868
9869 \brief hdd_module_init() - Init Function
9870
9871 This is the driver entry point (invoked when module is loaded using insmod)
9872
9873 \param - None
9874
9875 \return - 0 for success, non zero for failure
9876
9877 --------------------------------------------------------------------------*/
9878#ifdef MODULE
9879static int __init hdd_module_init ( void)
9880{
9881 return hdd_driver_init();
9882}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009883#else /* #ifdef MODULE */
9884static int __init hdd_module_init ( void)
9885{
9886 /* Driver initialization is delayed to fwpath_changed_handler */
9887 return 0;
9888}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009889#endif /* #ifdef MODULE */
9890
Jeff Johnson295189b2012-06-20 16:38:30 -07009891
9892/**---------------------------------------------------------------------------
9893
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009894 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009895
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009896 This is the driver exit point (invoked when module is unloaded using rmmod
9897 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009898
9899 \param - None
9900
9901 \return - None
9902
9903 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009904static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009905{
9906 hdd_context_t *pHddCtx = NULL;
9907 v_CONTEXT_t pVosContext = NULL;
Siddharth Bhala204f572015-01-17 02:03:36 +05309908 pVosWatchdogContext pVosWDCtx = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309909 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309910 unsigned long rc = 0;
Siddharth Bhala204f572015-01-17 02:03:36 +05309911 unsigned long flags;
Jeff Johnson295189b2012-06-20 16:38:30 -07009912
9913 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9914
9915 //Get the global vos context
9916 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9917
9918 if(!pVosContext)
9919 {
9920 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9921 goto done;
9922 }
9923
9924 //Get the HDD context.
9925 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9926
9927 if(!pHddCtx)
9928 {
9929 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9930 }
9931 else
9932 {
Siddharth Bhala204f572015-01-17 02:03:36 +05309933 pVosWDCtx = get_vos_watchdog_ctxt();
9934 if(pVosWDCtx == NULL)
9935 {
9936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("WD context is invalid"));
9937 goto done;
9938 }
9939 spin_lock_irqsave(&pVosWDCtx->wdLock, flags);
9940 if (!pHddCtx->isLogpInProgress || (TRUE ==
9941 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
9942 {
9943 //SSR isn't in progress OR last wlan reinit wasn't successful
9944 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
9945 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9946 spin_unlock_irqrestore(&pVosWDCtx->wdLock, flags);
9947 }
9948 else
9949 {
9950 INIT_COMPLETION(pHddCtx->ssr_comp_var);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309951
Siddharth Bhala204f572015-01-17 02:03:36 +05309952 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
9953 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9954 spin_unlock_irqrestore(&pVosWDCtx->wdLock, flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07009955
Siddharth Bhala204f572015-01-17 02:03:36 +05309956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9957 "%s:SSR is in Progress; block rmmod !!!", __func__);
9958 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9959 msecs_to_jiffies(30000));
9960 if(!rc)
9961 {
9962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9963 "%s:SSR timedout, fatal error", __func__);
9964 VOS_BUG(0);
9965 }
9966 }
9967
9968 /* We wait for active entry threads to exit from driver
9969 * by waiting until rtnl_lock is available.
9970 */
9971 rtnl_lock();
9972 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -07009973
c_hpothu8adb97b2014-12-08 19:38:20 +05309974 /* Driver Need to send country code 00 in below condition
9975 * 1) If gCountryCodePriority is set to 1; and last country
9976 * code set is through 11d. This needs to be done in case
9977 * when NV country code is 00.
9978 * This Needs to be done as when kernel store last country
9979 * code and if stored country code is not through 11d,
9980 * in sme_HandleChangeCountryCodeByUser we will disable 11d
9981 * in next load/unload as soon as we get any country through
9982 * 11d. In sme_HandleChangeCountryCodeByUser
9983 * pMsg->countryCode will be last countryCode and
9984 * pMac->scan.countryCode11d will be country through 11d so
9985 * due to mismatch driver will disable 11d.
9986 *
9987 */
Agarwal Ashish8db39882014-07-30 21:56:07 +05309988
c_hpothu8adb97b2014-12-08 19:38:20 +05309989 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309990 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +05309991 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +05309992 {
9993 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309994 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +05309995 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9996 }
Agarwal Ashish5e414792014-06-08 15:25:23 +05309997
c_hpothu8adb97b2014-12-08 19:38:20 +05309998 //Do all the cleanup before deregistering the driver
9999 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010000 }
10001
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 vos_preClose( &pVosContext );
10003
10004#ifdef TIMER_MANAGER
10005 vos_timer_exit();
10006#endif
10007#ifdef MEMORY_DEBUG
10008 vos_mem_exit();
10009#endif
10010
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010011#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10012 wlan_logging_sock_deinit_svc();
10013#endif
10014
Jeff Johnson295189b2012-06-20 16:38:30 -070010015done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010016#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010018#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010019
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10021}
10022
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010023/**---------------------------------------------------------------------------
10024
10025 \brief hdd_module_exit() - Exit function
10026
10027 This is the driver exit point (invoked when module is unloaded using rmmod)
10028
10029 \param - None
10030
10031 \return - None
10032
10033 --------------------------------------------------------------------------*/
10034static void __exit hdd_module_exit(void)
10035{
10036 hdd_driver_exit();
10037}
10038
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010039#ifdef MODULE
10040static int fwpath_changed_handler(const char *kmessage,
10041 struct kernel_param *kp)
10042{
Jeff Johnson76052702013-04-16 13:55:05 -070010043 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010044}
10045
10046static int con_mode_handler(const char *kmessage,
10047 struct kernel_param *kp)
10048{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010049 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010050}
10051#else /* #ifdef MODULE */
10052/**---------------------------------------------------------------------------
10053
Jeff Johnson76052702013-04-16 13:55:05 -070010054 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010055
Jeff Johnson76052702013-04-16 13:55:05 -070010056 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010057 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010058 - invoked when module parameter fwpath is modified from userspace to signal
10059 initializing the WLAN driver or when con_mode is modified from userspace
10060 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010061
10062 \return - 0 for success, non zero for failure
10063
10064 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010065static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010066{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010067 int ret_status;
10068
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010069 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010070 ret_status = hdd_driver_init();
10071 wlan_hdd_inited = ret_status ? 0 : 1;
10072 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010073 }
10074
10075 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010076
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010077 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010078
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010079 ret_status = hdd_driver_init();
10080 wlan_hdd_inited = ret_status ? 0 : 1;
10081 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010082}
10083
Jeff Johnson295189b2012-06-20 16:38:30 -070010084/**---------------------------------------------------------------------------
10085
Jeff Johnson76052702013-04-16 13:55:05 -070010086 \brief fwpath_changed_handler() - Handler Function
10087
10088 Handle changes to the fwpath parameter
10089
10090 \return - 0 for success, non zero for failure
10091
10092 --------------------------------------------------------------------------*/
10093static int fwpath_changed_handler(const char *kmessage,
10094 struct kernel_param *kp)
10095{
10096 int ret;
10097
10098 ret = param_set_copystring(kmessage, kp);
10099 if (0 == ret)
10100 ret = kickstart_driver();
10101 return ret;
10102}
10103
10104/**---------------------------------------------------------------------------
10105
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010106 \brief con_mode_handler() -
10107
10108 Handler function for module param con_mode when it is changed by userspace
10109 Dynamically linked - do nothing
10110 Statically linked - exit and init driver, as in rmmod and insmod
10111
Jeff Johnson76052702013-04-16 13:55:05 -070010112 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010113
Jeff Johnson76052702013-04-16 13:55:05 -070010114 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010115
10116 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010117static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010118{
Jeff Johnson76052702013-04-16 13:55:05 -070010119 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010120
Jeff Johnson76052702013-04-16 13:55:05 -070010121 ret = param_set_int(kmessage, kp);
10122 if (0 == ret)
10123 ret = kickstart_driver();
10124 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010125}
10126#endif /* #ifdef MODULE */
10127
10128/**---------------------------------------------------------------------------
10129
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 \brief hdd_get_conparam() -
10131
10132 This is the driver exit point (invoked when module is unloaded using rmmod)
10133
10134 \param - None
10135
10136 \return - tVOS_CON_MODE
10137
10138 --------------------------------------------------------------------------*/
10139tVOS_CON_MODE hdd_get_conparam ( void )
10140{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010141#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010143#else
10144 return (tVOS_CON_MODE)curr_con_mode;
10145#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010146}
10147void hdd_set_conparam ( v_UINT_t newParam )
10148{
10149 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010150#ifndef MODULE
10151 curr_con_mode = con_mode;
10152#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010153}
10154/**---------------------------------------------------------------------------
10155
10156 \brief hdd_softap_sta_deauth() - function
10157
10158 This to take counter measure to handle deauth req from HDD
10159
10160 \param - pAdapter - Pointer to the HDD
10161
10162 \param - enable - boolean value
10163
10164 \return - None
10165
10166 --------------------------------------------------------------------------*/
10167
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010168VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10169 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010170{
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010172 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010173
10174 ENTER();
10175
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010176 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10177 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010178
10179 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010180 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010181 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010182
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010183 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010184
10185 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010186 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010187}
10188
10189/**---------------------------------------------------------------------------
10190
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010191 \brief hdd_del_all_sta() - function
10192
10193 This function removes all the stations associated on stopping AP/P2P GO.
10194
10195 \param - pAdapter - Pointer to the HDD
10196
10197 \return - None
10198
10199 --------------------------------------------------------------------------*/
10200
10201int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10202{
10203 v_U16_t i;
10204 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010205 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10206 ptSapContext pSapCtx = NULL;
10207 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10208 if(pSapCtx == NULL){
10209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10210 FL("psapCtx is NULL"));
10211 return 1;
10212 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010213 ENTER();
10214
10215 hddLog(VOS_TRACE_LEVEL_INFO,
10216 "%s: Delete all STAs associated.",__func__);
10217 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10218 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10219 )
10220 {
10221 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10222 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010223 if ((pSapCtx->aStaInfo[i].isUsed) &&
10224 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010225 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010226 struct tagCsrDelStaParams delStaParams;
10227
10228 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010229 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010230 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10231 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010232 &delStaParams);
10233 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010234 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010235 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010236 }
10237 }
10238 }
10239
10240 EXIT();
10241 return 0;
10242}
10243
10244/**---------------------------------------------------------------------------
10245
Jeff Johnson295189b2012-06-20 16:38:30 -070010246 \brief hdd_softap_sta_disassoc() - function
10247
10248 This to take counter measure to handle deauth req from HDD
10249
10250 \param - pAdapter - Pointer to the HDD
10251
10252 \param - enable - boolean value
10253
10254 \return - None
10255
10256 --------------------------------------------------------------------------*/
10257
10258void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10259{
10260 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10261
10262 ENTER();
10263
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010264 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010265
10266 //Ignore request to disassoc bcmc station
10267 if( pDestMacAddress[0] & 0x1 )
10268 return;
10269
10270 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10271}
10272
10273void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10274{
10275 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10276
10277 ENTER();
10278
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010279 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010280
10281 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10282}
10283
Jeff Johnson295189b2012-06-20 16:38:30 -070010284/**---------------------------------------------------------------------------
10285 *
10286 * \brief hdd_get__concurrency_mode() -
10287 *
10288 *
10289 * \param - None
10290 *
10291 * \return - CONCURRENCY MODE
10292 *
10293 * --------------------------------------------------------------------------*/
10294tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10295{
10296 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10297 hdd_context_t *pHddCtx;
10298
10299 if (NULL != pVosContext)
10300 {
10301 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10302 if (NULL != pHddCtx)
10303 {
10304 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10305 }
10306 }
10307
10308 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010309 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010310 return VOS_STA;
10311}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010312v_BOOL_t
10313wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10314{
10315 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010316
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010317 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10318 if (pAdapter == NULL)
10319 {
10320 hddLog(VOS_TRACE_LEVEL_INFO,
10321 FL("GO doesn't exist"));
10322 return TRUE;
10323 }
10324 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10325 {
10326 hddLog(VOS_TRACE_LEVEL_INFO,
10327 FL("GO started"));
10328 return TRUE;
10329 }
10330 else
10331 /* wait till GO changes its interface to p2p device */
10332 hddLog(VOS_TRACE_LEVEL_INFO,
10333 FL("Del_bss called, avoid apps suspend"));
10334 return FALSE;
10335
10336}
Jeff Johnson295189b2012-06-20 16:38:30 -070010337/* Decide whether to allow/not the apps power collapse.
10338 * Allow apps power collapse if we are in connected state.
10339 * if not, allow only if we are in IMPS */
10340v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10341{
10342 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010343 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010344 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010345 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10346 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10347 hdd_adapter_t *pAdapter = NULL;
10348 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010349 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010350
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10352 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010353
Yathish9f22e662012-12-10 14:21:35 -080010354 concurrent_state = hdd_get_concurrency_mode();
10355
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010356 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10357 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10358 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010359#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010360
Yathish9f22e662012-12-10 14:21:35 -080010361 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010362 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010363 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10364 return TRUE;
10365#endif
10366
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 /*loop through all adapters. TBD fix for Concurrency */
10368 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10369 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10370 {
10371 pAdapter = pAdapterNode->pAdapter;
10372 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10373 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10374 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010375 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010376 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010377 && pmcState != STOPPED && pmcState != STANDBY &&
10378 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010379 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10380 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010381 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010382 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010383 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10384 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010385 return FALSE;
10386 }
10387 }
10388 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10389 pAdapterNode = pNext;
10390 }
10391 return TRUE;
10392}
10393
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010394/* Decides whether to send suspend notification to Riva
10395 * if any adapter is in BMPS; then it is required */
10396v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10397{
10398 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10399 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10400
10401 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10402 {
10403 return TRUE;
10404 }
10405 return FALSE;
10406}
10407
Jeff Johnson295189b2012-06-20 16:38:30 -070010408void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10409{
10410 switch(mode)
10411 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010412 case VOS_STA_MODE:
10413 case VOS_P2P_CLIENT_MODE:
10414 case VOS_P2P_GO_MODE:
10415 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010416 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010417 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010418 break;
10419 default:
10420 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010421 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010422 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10423 "Number of open sessions for mode %d = %d"),
10424 pHddCtx->concurrency_mode, mode,
10425 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010426}
10427
10428
10429void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10430{
10431 switch(mode)
10432 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010433 case VOS_STA_MODE:
10434 case VOS_P2P_CLIENT_MODE:
10435 case VOS_P2P_GO_MODE:
10436 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010437 pHddCtx->no_of_open_sessions[mode]--;
10438 if (!(pHddCtx->no_of_open_sessions[mode]))
10439 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 break;
10441 default:
10442 break;
10443 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010444 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10445 "Number of open sessions for mode %d = %d"),
10446 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10447
10448}
10449/**---------------------------------------------------------------------------
10450 *
10451 * \brief wlan_hdd_incr_active_session()
10452 *
10453 * This function increments the number of active sessions
10454 * maintained per device mode
10455 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10456 * Incase of SAP/P2P GO upon bss start it is incremented
10457 *
10458 * \param pHddCtx - HDD Context
10459 * \param mode - device mode
10460 *
10461 * \return - None
10462 *
10463 * --------------------------------------------------------------------------*/
10464void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10465{
10466 switch (mode) {
10467 case VOS_STA_MODE:
10468 case VOS_P2P_CLIENT_MODE:
10469 case VOS_P2P_GO_MODE:
10470 case VOS_STA_SAP_MODE:
10471 pHddCtx->no_of_active_sessions[mode]++;
10472 break;
10473 default:
10474 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10475 break;
10476 }
10477 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10478 mode,
10479 pHddCtx->no_of_active_sessions[mode]);
10480}
10481
10482/**---------------------------------------------------------------------------
10483 *
10484 * \brief wlan_hdd_decr_active_session()
10485 *
10486 * This function decrements the number of active sessions
10487 * maintained per device mode
10488 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10489 * Incase of SAP/P2P GO upon bss stop it is decremented
10490 *
10491 * \param pHddCtx - HDD Context
10492 * \param mode - device mode
10493 *
10494 * \return - None
10495 *
10496 * --------------------------------------------------------------------------*/
10497void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10498{
10499 switch (mode) {
10500 case VOS_STA_MODE:
10501 case VOS_P2P_CLIENT_MODE:
10502 case VOS_P2P_GO_MODE:
10503 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010504 if (pHddCtx->no_of_active_sessions[mode] > 0)
10505 pHddCtx->no_of_active_sessions[mode]--;
10506 else
10507 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10508 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010509 break;
10510 default:
10511 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10512 break;
10513 }
10514 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10515 mode,
10516 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010517}
10518
Jeff Johnsone7245742012-09-05 17:12:55 -070010519/**---------------------------------------------------------------------------
10520 *
10521 * \brief wlan_hdd_restart_init
10522 *
10523 * This function initalizes restart timer/flag. An internal function.
10524 *
10525 * \param - pHddCtx
10526 *
10527 * \return - None
10528 *
10529 * --------------------------------------------------------------------------*/
10530
10531static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10532{
10533 /* Initialize */
10534 pHddCtx->hdd_restart_retries = 0;
10535 atomic_set(&pHddCtx->isRestartInProgress, 0);
10536 vos_timer_init(&pHddCtx->hdd_restart_timer,
10537 VOS_TIMER_TYPE_SW,
10538 wlan_hdd_restart_timer_cb,
10539 pHddCtx);
10540}
10541/**---------------------------------------------------------------------------
10542 *
10543 * \brief wlan_hdd_restart_deinit
10544 *
10545 * This function cleans up the resources used. An internal function.
10546 *
10547 * \param - pHddCtx
10548 *
10549 * \return - None
10550 *
10551 * --------------------------------------------------------------------------*/
10552
10553static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10554{
10555
10556 VOS_STATUS vos_status;
10557 /* Block any further calls */
10558 atomic_set(&pHddCtx->isRestartInProgress, 1);
10559 /* Cleanup */
10560 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10561 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010562 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010563 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10564 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010565 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010566
10567}
10568
10569/**---------------------------------------------------------------------------
10570 *
10571 * \brief wlan_hdd_framework_restart
10572 *
10573 * This function uses a cfg80211 API to start a framework initiated WLAN
10574 * driver module unload/load.
10575 *
10576 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10577 *
10578 *
10579 * \param - pHddCtx
10580 *
10581 * \return - VOS_STATUS_SUCCESS: Success
10582 * VOS_STATUS_E_EMPTY: Adapter is Empty
10583 * VOS_STATUS_E_NOMEM: No memory
10584
10585 * --------------------------------------------------------------------------*/
10586
10587static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10588{
10589 VOS_STATUS status = VOS_STATUS_SUCCESS;
10590 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010591 int len = (sizeof (struct ieee80211_mgmt));
10592 struct ieee80211_mgmt *mgmt = NULL;
10593
10594 /* Prepare the DEAUTH managment frame with reason code */
10595 mgmt = kzalloc(len, GFP_KERNEL);
10596 if(mgmt == NULL)
10597 {
10598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10599 "%s: memory allocation failed (%d bytes)", __func__, len);
10600 return VOS_STATUS_E_NOMEM;
10601 }
10602 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010603
10604 /* Iterate over all adapters/devices */
10605 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10606 do
10607 {
10608 if( (status == VOS_STATUS_SUCCESS) &&
10609 pAdapterNode &&
10610 pAdapterNode->pAdapter)
10611 {
10612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10613 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10614 pAdapterNode->pAdapter->dev->name,
10615 pAdapterNode->pAdapter->device_mode,
10616 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010617 /*
10618 * CFG80211 event to restart the driver
10619 *
10620 * 'cfg80211_send_unprot_deauth' sends a
10621 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10622 * of SME(Linux Kernel) state machine.
10623 *
10624 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10625 * the driver.
10626 *
10627 */
10628
10629 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010630 }
10631 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10632 pAdapterNode = pNext;
10633 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10634
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010635
10636 /* Free the allocated management frame */
10637 kfree(mgmt);
10638
Jeff Johnsone7245742012-09-05 17:12:55 -070010639 /* Retry until we unload or reach max count */
10640 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10641 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10642
10643 return status;
10644
10645}
10646/**---------------------------------------------------------------------------
10647 *
10648 * \brief wlan_hdd_restart_timer_cb
10649 *
10650 * Restart timer callback. An internal function.
10651 *
10652 * \param - User data:
10653 *
10654 * \return - None
10655 *
10656 * --------------------------------------------------------------------------*/
10657
10658void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10659{
10660 hdd_context_t *pHddCtx = usrDataForCallback;
10661 wlan_hdd_framework_restart(pHddCtx);
10662 return;
10663
10664}
10665
10666
10667/**---------------------------------------------------------------------------
10668 *
10669 * \brief wlan_hdd_restart_driver
10670 *
10671 * This function sends an event to supplicant to restart the WLAN driver.
10672 *
10673 * This function is called from vos_wlanRestart.
10674 *
10675 * \param - pHddCtx
10676 *
10677 * \return - VOS_STATUS_SUCCESS: Success
10678 * VOS_STATUS_E_EMPTY: Adapter is Empty
10679 * VOS_STATUS_E_ALREADY: Request already in progress
10680
10681 * --------------------------------------------------------------------------*/
10682VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10683{
10684 VOS_STATUS status = VOS_STATUS_SUCCESS;
10685
10686 /* A tight check to make sure reentrancy */
10687 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10688 {
Mihir Shetefd528652014-06-23 19:07:50 +053010689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010690 "%s: WLAN restart is already in progress", __func__);
10691
10692 return VOS_STATUS_E_ALREADY;
10693 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010694 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010695#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010696 wcnss_reset_intr();
10697#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010698
Jeff Johnsone7245742012-09-05 17:12:55 -070010699 return status;
10700}
10701
Mihir Shetee1093ba2014-01-21 20:13:32 +053010702/**---------------------------------------------------------------------------
10703 *
10704 * \brief wlan_hdd_init_channels
10705 *
10706 * This function is used to initialize the channel list in CSR
10707 *
10708 * This function is called from hdd_wlan_startup
10709 *
10710 * \param - pHddCtx: HDD context
10711 *
10712 * \return - VOS_STATUS_SUCCESS: Success
10713 * VOS_STATUS_E_FAULT: Failure reported by SME
10714
10715 * --------------------------------------------------------------------------*/
10716static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10717{
10718 eHalStatus status;
10719
10720 status = sme_InitChannels(pHddCtx->hHal);
10721 if (HAL_STATUS_SUCCESS(status))
10722 {
10723 return VOS_STATUS_SUCCESS;
10724 }
10725 else
10726 {
10727 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10728 __func__, status);
10729 return VOS_STATUS_E_FAULT;
10730 }
10731}
10732
Mihir Shete04206452014-11-20 17:50:58 +053010733#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010734VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010735{
10736 eHalStatus status;
10737
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010738 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010739 if (HAL_STATUS_SUCCESS(status))
10740 {
10741 return VOS_STATUS_SUCCESS;
10742 }
10743 else
10744 {
10745 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10746 __func__, status);
10747 return VOS_STATUS_E_FAULT;
10748 }
10749}
Mihir Shete04206452014-11-20 17:50:58 +053010750#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010751/*
10752 * API to find if there is any STA or P2P-Client is connected
10753 */
10754VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10755{
10756 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10757}
Jeff Johnsone7245742012-09-05 17:12:55 -070010758
Agarwal Ashish57e84372014-12-05 18:26:53 +053010759/*
10760 * API to find if there is any session connected
10761 */
10762VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
10763{
10764 return sme_is_any_session_connected(pHddCtx->hHal);
10765}
10766
10767
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010768int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10769{
10770 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10771 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010772 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053010773 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010774
10775 pScanInfo = &pHddCtx->scan_info;
10776 if (pScanInfo->mScanPending)
10777 {
c_hpothua3d45d52015-01-05 14:11:17 +053010778 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
10779 eCSR_SCAN_ABORT_DEFAULT);
10780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10781 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010782
c_hpothua3d45d52015-01-05 14:11:17 +053010783 /* If there is active scan command lets wait for the completion else
10784 * there is no need to wait as scan command might be in the SME pending
10785 * command list.
10786 */
10787 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
10788 {
10789 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10790 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010791 &pScanInfo->abortscan_event_var,
10792 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053010793 if (0 >= status)
10794 {
10795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010796 "%s: Timeout or Interrupt occurred while waiting for abort"
10797 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053010798 return -ETIMEDOUT;
10799 }
10800 }
10801 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
10802 {
10803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10804 FL("hdd_abort_mac_scan failed"));
10805 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010806 }
10807 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010808 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010809}
10810
c_hpothu225aa7c2014-10-22 17:45:13 +053010811VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10812{
10813 hdd_adapter_t *pAdapter;
10814 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10815 VOS_STATUS vosStatus;
10816
10817 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10818 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10819 {
10820 pAdapter = pAdapterNode->pAdapter;
10821 if (NULL != pAdapter)
10822 {
10823 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10824 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10825 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10826 {
10827 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10828 pAdapter->device_mode);
10829 if (VOS_STATUS_SUCCESS !=
10830 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10831 {
10832 hddLog(LOGE, FL("failed to abort ROC"));
10833 return VOS_STATUS_E_FAILURE;
10834 }
10835 }
10836 }
10837 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10838 pAdapterNode = pNext;
10839 }
10840 return VOS_STATUS_SUCCESS;
10841}
Jeff Johnson295189b2012-06-20 16:38:30 -070010842//Register the module init/exit functions
10843module_init(hdd_module_init);
10844module_exit(hdd_module_exit);
10845
10846MODULE_LICENSE("Dual BSD/GPL");
10847MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10848MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10849
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010850module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10851 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010852
Jeff Johnson76052702013-04-16 13:55:05 -070010853module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010854 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010855
10856module_param(enable_dfs_chan_scan, int,
10857 S_IRUSR | S_IRGRP | S_IROTH);
10858
10859module_param(enable_11d, int,
10860 S_IRUSR | S_IRGRP | S_IROTH);
10861
10862module_param(country_code, charp,
10863 S_IRUSR | S_IRGRP | S_IROTH);