blob: 73bd3aa4ff797d4f974e34af5f98102433e94290 [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 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002283 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2284 {
2285 char *country_code;
2286
2287 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002288
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002289 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002290 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002291#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302292 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002293#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002294 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2295 (void *)(tSmeChangeCountryCallback)
2296 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302297 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002298 if (eHAL_STATUS_SUCCESS == ret)
2299 {
2300 ret = wait_for_completion_interruptible_timeout(
2301 &pAdapter->change_country_code,
2302 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2303 if (0 >= ret)
2304 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002305 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302306 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002307 }
2308 }
2309 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002310 {
2311 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002312 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002313 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002314 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002315
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002316 }
2317 /*
2318 command should be a string having format
2319 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2320 */
Amar Singhal0974e402013-02-12 14:27:46 -08002321 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002322 {
Amar Singhal0974e402013-02-12 14:27:46 -08002323 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002324
2325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002326 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002327
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002328 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002329 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002330 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2331 {
2332 int suspend = 0;
2333 tANI_U8 *ptr = (tANI_U8*)command + 15;
2334
2335 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302336 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2337 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2338 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002339 hdd_set_wlan_suspend_mode(suspend);
2340 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002341#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2342 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2343 {
2344 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002345 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002346 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2347 eHalStatus status = eHAL_STATUS_SUCCESS;
2348
2349 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2350 value = value + 15;
2351
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002352 /* Convert the value from ascii to integer */
2353 ret = kstrtos8(value, 10, &rssi);
2354 if (ret < 0)
2355 {
2356 /* If the input value is greater than max value of datatype, then also
2357 kstrtou8 fails */
2358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2359 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002360 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002361 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2362 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2363 ret = -EINVAL;
2364 goto exit;
2365 }
2366
Srinivas Girigowdade697412013-02-14 16:31:48 -08002367 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002368
Srinivas Girigowdade697412013-02-14 16:31:48 -08002369 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2370 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2371 {
2372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2373 "Neighbor lookup threshold value %d is out of range"
2374 " (Min: %d Max: %d)", lookUpThreshold,
2375 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2376 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2377 ret = -EINVAL;
2378 goto exit;
2379 }
2380
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302381 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2382 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2383 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2385 "%s: Received Command to Set Roam trigger"
2386 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2387
2388 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2389 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2390 if (eHAL_STATUS_SUCCESS != status)
2391 {
2392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2393 "%s: Failed to set roam trigger, try again", __func__);
2394 ret = -EPERM;
2395 goto exit;
2396 }
2397
2398 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302399 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002400 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2401 }
2402 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2403 {
2404 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2405 int rssi = (-1) * lookUpThreshold;
2406 char extra[32];
2407 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302408 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2409 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2410 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002411 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002412 if (copy_to_user(priv_data.buf, &extra, len + 1))
2413 {
2414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2415 "%s: failed to copy data to user buffer", __func__);
2416 ret = -EFAULT;
2417 goto exit;
2418 }
2419 }
2420 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2421 {
2422 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002423 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002424 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002425
Srinivas Girigowdade697412013-02-14 16:31:48 -08002426 /* input refresh period is in terms of seconds */
2427 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2428 value = value + 18;
2429 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002430 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002431 if (ret < 0)
2432 {
2433 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002434 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002436 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002437 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002438 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2439 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002440 ret = -EINVAL;
2441 goto exit;
2442 }
2443
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002444 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2445 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002446 {
2447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002448 "Roam scan period value %d is out of range"
2449 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002450 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2451 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002452 ret = -EINVAL;
2453 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302454 }
2455 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2456 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2457 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002458 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002459
2460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2461 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002462 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002463
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002464 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2465 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002466 }
2467 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2468 {
2469 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2470 char extra[32];
2471 tANI_U8 len = 0;
2472
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302473 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2474 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2475 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002476 len = scnprintf(extra, sizeof(extra), "%s %d",
2477 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478 /* Returned value is in units of seconds */
2479 if (copy_to_user(priv_data.buf, &extra, len + 1))
2480 {
2481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2482 "%s: failed to copy data to user buffer", __func__);
2483 ret = -EFAULT;
2484 goto exit;
2485 }
2486 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002487 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2488 {
2489 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002490 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002491 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002492
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002493 /* input refresh period is in terms of seconds */
2494 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2495 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002497 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002498 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002499 if (ret < 0)
2500 {
2501 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002502 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002504 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002505 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002506 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2507 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2508 ret = -EINVAL;
2509 goto exit;
2510 }
2511
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002512 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2513 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2514 {
2515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2516 "Neighbor scan results refresh period value %d is out of range"
2517 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2518 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2519 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2520 ret = -EINVAL;
2521 goto exit;
2522 }
2523 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2524
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2526 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002527 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002528
2529 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2530 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2531 }
2532 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2533 {
2534 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2535 char extra[32];
2536 tANI_U8 len = 0;
2537
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002538 len = scnprintf(extra, sizeof(extra), "%s %d",
2539 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002540 /* Returned value is in units of seconds */
2541 if (copy_to_user(priv_data.buf, &extra, len + 1))
2542 {
2543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2544 "%s: failed to copy data to user buffer", __func__);
2545 ret = -EFAULT;
2546 goto exit;
2547 }
2548 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002549#ifdef FEATURE_WLAN_LFR
2550 /* SETROAMMODE */
2551 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2552 {
2553 tANI_U8 *value = command;
2554 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2555
2556 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2557 value = value + SIZE_OF_SETROAMMODE + 1;
2558
2559 /* Convert the value from ascii to integer */
2560 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2561 if (ret < 0)
2562 {
2563 /* If the input value is greater than max value of datatype, then also
2564 kstrtou8 fails */
2565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2566 "%s: kstrtou8 failed range [%d - %d]", __func__,
2567 CFG_LFR_FEATURE_ENABLED_MIN,
2568 CFG_LFR_FEATURE_ENABLED_MAX);
2569 ret = -EINVAL;
2570 goto exit;
2571 }
2572 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2573 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2574 {
2575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2576 "Roam Mode value %d is out of range"
2577 " (Min: %d Max: %d)", roamMode,
2578 CFG_LFR_FEATURE_ENABLED_MIN,
2579 CFG_LFR_FEATURE_ENABLED_MAX);
2580 ret = -EINVAL;
2581 goto exit;
2582 }
2583
2584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2585 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2586 /*
2587 * Note that
2588 * SETROAMMODE 0 is to enable LFR while
2589 * SETROAMMODE 1 is to disable LFR, but
2590 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2591 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2592 */
2593 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2594 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2595 else
2596 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2597
2598 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2599 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2600 }
2601 /* GETROAMMODE */
2602 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2603 {
2604 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2605 char extra[32];
2606 tANI_U8 len = 0;
2607
2608 /*
2609 * roamMode value shall be inverted because the sementics is different.
2610 */
2611 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2612 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2613 else
2614 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2615
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002616 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002617 if (copy_to_user(priv_data.buf, &extra, len + 1))
2618 {
2619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2620 "%s: failed to copy data to user buffer", __func__);
2621 ret = -EFAULT;
2622 goto exit;
2623 }
2624 }
2625#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002626#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002627#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002628 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2629 {
2630 tANI_U8 *value = command;
2631 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2632
2633 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2634 value = value + 13;
2635 /* Convert the value from ascii to integer */
2636 ret = kstrtou8(value, 10, &roamRssiDiff);
2637 if (ret < 0)
2638 {
2639 /* If the input value is greater than max value of datatype, then also
2640 kstrtou8 fails */
2641 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2642 "%s: kstrtou8 failed range [%d - %d]", __func__,
2643 CFG_ROAM_RSSI_DIFF_MIN,
2644 CFG_ROAM_RSSI_DIFF_MAX);
2645 ret = -EINVAL;
2646 goto exit;
2647 }
2648
2649 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2650 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2651 {
2652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2653 "Roam rssi diff value %d is out of range"
2654 " (Min: %d Max: %d)", roamRssiDiff,
2655 CFG_ROAM_RSSI_DIFF_MIN,
2656 CFG_ROAM_RSSI_DIFF_MAX);
2657 ret = -EINVAL;
2658 goto exit;
2659 }
2660
2661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2662 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2663
2664 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2665 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2666 }
2667 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2668 {
2669 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2670 char extra[32];
2671 tANI_U8 len = 0;
2672
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302673 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2674 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2675 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002676 len = scnprintf(extra, sizeof(extra), "%s %d",
2677 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002678 if (copy_to_user(priv_data.buf, &extra, len + 1))
2679 {
2680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2681 "%s: failed to copy data to user buffer", __func__);
2682 ret = -EFAULT;
2683 goto exit;
2684 }
2685 }
2686#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002687#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002688 else if (strncmp(command, "GETBAND", 7) == 0)
2689 {
2690 int band = -1;
2691 char extra[32];
2692 tANI_U8 len = 0;
2693 hdd_getBand_helper(pHddCtx, &band);
2694
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302695 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2696 TRACE_CODE_HDD_GETBAND_IOCTL,
2697 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002698 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002699 if (copy_to_user(priv_data.buf, &extra, len + 1))
2700 {
2701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2702 "%s: failed to copy data to user buffer", __func__);
2703 ret = -EFAULT;
2704 goto exit;
2705 }
2706 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002707 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2708 {
2709 tANI_U8 *value = command;
2710 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2711 tANI_U8 numChannels = 0;
2712 eHalStatus status = eHAL_STATUS_SUCCESS;
2713
2714 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2715 if (eHAL_STATUS_SUCCESS != status)
2716 {
2717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2718 "%s: Failed to parse channel list information", __func__);
2719 ret = -EINVAL;
2720 goto exit;
2721 }
2722
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302723 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2724 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2725 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002726 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2727 {
2728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2729 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2730 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2731 ret = -EINVAL;
2732 goto exit;
2733 }
2734 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2735 numChannels);
2736 if (eHAL_STATUS_SUCCESS != status)
2737 {
2738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2739 "%s: Failed to update channel list information", __func__);
2740 ret = -EINVAL;
2741 goto exit;
2742 }
2743 }
2744 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2745 {
2746 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2747 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002748 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002749 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002750 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002751
2752 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2753 ChannelList, &numChannels ))
2754 {
2755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2756 "%s: failed to get roam scan channel list", __func__);
2757 ret = -EFAULT;
2758 goto exit;
2759 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2761 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2762 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002763 /* output channel list is of the format
2764 [Number of roam scan channels][Channel1][Channel2]... */
2765 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002766 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002767 for (j = 0; (j < numChannels); j++)
2768 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002769 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2770 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002771 }
2772
2773 if (copy_to_user(priv_data.buf, &extra, len + 1))
2774 {
2775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2776 "%s: failed to copy data to user buffer", __func__);
2777 ret = -EFAULT;
2778 goto exit;
2779 }
2780 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002781 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2782 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002783 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002784 char extra[32];
2785 tANI_U8 len = 0;
2786
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002787 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002788 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002789 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002790 hdd_is_okc_mode_enabled(pHddCtx) &&
2791 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2792 {
2793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002794 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002795 " hence this operation is not permitted!", __func__);
2796 ret = -EPERM;
2797 goto exit;
2798 }
2799
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002800 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002801 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002802 if (copy_to_user(priv_data.buf, &extra, len + 1))
2803 {
2804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2805 "%s: failed to copy data to user buffer", __func__);
2806 ret = -EFAULT;
2807 goto exit;
2808 }
2809 }
2810 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2811 {
2812 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2813 char extra[32];
2814 tANI_U8 len = 0;
2815
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002816 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002817 then this operation is not permitted (return FAILURE) */
2818 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002819 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002820 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2821 {
2822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002823 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002824 " hence this operation is not permitted!", __func__);
2825 ret = -EPERM;
2826 goto exit;
2827 }
2828
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002829 len = scnprintf(extra, sizeof(extra), "%s %d",
2830 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002831 if (copy_to_user(priv_data.buf, &extra, len + 1))
2832 {
2833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2834 "%s: failed to copy data to user buffer", __func__);
2835 ret = -EFAULT;
2836 goto exit;
2837 }
2838 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002839 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002840 {
2841 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2842 char extra[32];
2843 tANI_U8 len = 0;
2844
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002845 len = scnprintf(extra, sizeof(extra), "%s %d",
2846 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002847 if (copy_to_user(priv_data.buf, &extra, len + 1))
2848 {
2849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2850 "%s: failed to copy data to user buffer", __func__);
2851 ret = -EFAULT;
2852 goto exit;
2853 }
2854 }
2855 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2856 {
2857 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2858 char extra[32];
2859 tANI_U8 len = 0;
2860
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002861 len = scnprintf(extra, sizeof(extra), "%s %d",
2862 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002863 if (copy_to_user(priv_data.buf, &extra, len + 1))
2864 {
2865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2866 "%s: failed to copy data to user buffer", __func__);
2867 ret = -EFAULT;
2868 goto exit;
2869 }
2870 }
2871 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2872 {
2873 tANI_U8 *value = command;
2874 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2875
2876 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2877 value = value + 26;
2878 /* Convert the value from ascii to integer */
2879 ret = kstrtou8(value, 10, &minTime);
2880 if (ret < 0)
2881 {
2882 /* If the input value is greater than max value of datatype, then also
2883 kstrtou8 fails */
2884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2885 "%s: kstrtou8 failed range [%d - %d]", __func__,
2886 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2887 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2888 ret = -EINVAL;
2889 goto exit;
2890 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002891 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2892 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2893 {
2894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2895 "scan min channel time value %d is out of range"
2896 " (Min: %d Max: %d)", minTime,
2897 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2898 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2899 ret = -EINVAL;
2900 goto exit;
2901 }
2902
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302903 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2904 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2905 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2907 "%s: Received Command to change channel min time = %d", __func__, minTime);
2908
2909 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2910 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2911 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002912 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2913 {
2914 tANI_U8 *value = command;
2915 tANI_U8 channel = 0;
2916 tANI_U8 dwellTime = 0;
2917 tANI_U8 bufLen = 0;
2918 tANI_U8 *buf = NULL;
2919 tSirMacAddr targetApBssid;
2920 eHalStatus status = eHAL_STATUS_SUCCESS;
2921 struct ieee80211_channel chan;
2922 tANI_U8 finalLen = 0;
2923 tANI_U8 *finalBuf = NULL;
2924 tANI_U8 temp = 0;
2925 u64 cookie;
2926 hdd_station_ctx_t *pHddStaCtx = NULL;
2927 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2928
2929 /* if not associated, no need to send action frame */
2930 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2931 {
2932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2933 ret = -EINVAL;
2934 goto exit;
2935 }
2936
2937 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2938 &dwellTime, &buf, &bufLen);
2939 if (eHAL_STATUS_SUCCESS != status)
2940 {
2941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2942 "%s: Failed to parse send action frame data", __func__);
2943 ret = -EINVAL;
2944 goto exit;
2945 }
2946
2947 /* if the target bssid is different from currently associated AP,
2948 then no need to send action frame */
2949 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2950 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2951 {
2952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2953 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002954 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002955 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002956 goto exit;
2957 }
2958
2959 /* if the channel number is different from operating channel then
2960 no need to send action frame */
2961 if (channel != pHddStaCtx->conn_info.operationChannel)
2962 {
2963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2964 "%s: channel(%d) is different from operating channel(%d)",
2965 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2966 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002967 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002968 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002969 goto exit;
2970 }
2971 chan.center_freq = sme_ChnToFreq(channel);
2972
2973 finalLen = bufLen + 24;
2974 finalBuf = vos_mem_malloc(finalLen);
2975 if (NULL == finalBuf)
2976 {
2977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2978 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002979 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002980 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002981 goto exit;
2982 }
2983 vos_mem_zero(finalBuf, finalLen);
2984
2985 /* Fill subtype */
2986 temp = SIR_MAC_MGMT_ACTION << 4;
2987 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2988
2989 /* Fill type */
2990 temp = SIR_MAC_MGMT_FRAME;
2991 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2992
2993 /* Fill destination address (bssid of the AP) */
2994 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2995
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002996 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002997 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2998
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002999 /* Fill BSSID (AP mac address) */
3000 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003001
3002 /* Fill received buffer from 24th address */
3003 vos_mem_copy(finalBuf + 24, buf, bufLen);
3004
Jeff Johnson11c33152013-04-16 17:52:40 -07003005 /* done with the parsed buffer */
3006 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003007 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003008
DARAM SUDHA39eede62014-02-12 11:16:40 +05303009 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003010#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3011 &(pAdapter->wdev),
3012#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003013 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003014#endif
3015 &chan, 0,
3016#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3017 NL80211_CHAN_HT20, 1,
3018#endif
3019 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003020 1, &cookie );
3021 vos_mem_free(finalBuf);
3022 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003023 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3024 {
3025 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3026 char extra[32];
3027 tANI_U8 len = 0;
3028
3029 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003030 len = scnprintf(extra, sizeof(extra), "%s %d",
3031 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303032 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3033 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3034 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003035 if (copy_to_user(priv_data.buf, &extra, len + 1))
3036 {
3037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3038 "%s: failed to copy data to user buffer", __func__);
3039 ret = -EFAULT;
3040 goto exit;
3041 }
3042 }
3043 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3044 {
3045 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003046 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003047
3048 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3049 value = value + 19;
3050 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003051 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003052 if (ret < 0)
3053 {
3054 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003055 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003057 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003058 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3059 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3060 ret = -EINVAL;
3061 goto exit;
3062 }
3063
3064 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3065 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3066 {
3067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3068 "lfr mode value %d is out of range"
3069 " (Min: %d Max: %d)", maxTime,
3070 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3071 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3072 ret = -EINVAL;
3073 goto exit;
3074 }
3075
3076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3077 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3078
3079 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3080 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3081 }
3082 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3083 {
3084 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3085 char extra[32];
3086 tANI_U8 len = 0;
3087
3088 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003089 len = scnprintf(extra, sizeof(extra), "%s %d",
3090 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003091 if (copy_to_user(priv_data.buf, &extra, len + 1))
3092 {
3093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3094 "%s: failed to copy data to user buffer", __func__);
3095 ret = -EFAULT;
3096 goto exit;
3097 }
3098 }
3099 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3100 {
3101 tANI_U8 *value = command;
3102 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3103
3104 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3105 value = value + 16;
3106 /* Convert the value from ascii to integer */
3107 ret = kstrtou16(value, 10, &val);
3108 if (ret < 0)
3109 {
3110 /* If the input value is greater than max value of datatype, then also
3111 kstrtou16 fails */
3112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3113 "%s: kstrtou16 failed range [%d - %d]", __func__,
3114 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3115 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3116 ret = -EINVAL;
3117 goto exit;
3118 }
3119
3120 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3121 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3122 {
3123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3124 "scan home time value %d is out of range"
3125 " (Min: %d Max: %d)", val,
3126 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3127 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3128 ret = -EINVAL;
3129 goto exit;
3130 }
3131
3132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3133 "%s: Received Command to change scan home time = %d", __func__, val);
3134
3135 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3136 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3137 }
3138 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3139 {
3140 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3141 char extra[32];
3142 tANI_U8 len = 0;
3143
3144 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003145 len = scnprintf(extra, sizeof(extra), "%s %d",
3146 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003147 if (copy_to_user(priv_data.buf, &extra, len + 1))
3148 {
3149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3150 "%s: failed to copy data to user buffer", __func__);
3151 ret = -EFAULT;
3152 goto exit;
3153 }
3154 }
3155 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3156 {
3157 tANI_U8 *value = command;
3158 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3159
3160 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3161 value = value + 17;
3162 /* Convert the value from ascii to integer */
3163 ret = kstrtou8(value, 10, &val);
3164 if (ret < 0)
3165 {
3166 /* If the input value is greater than max value of datatype, then also
3167 kstrtou8 fails */
3168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3169 "%s: kstrtou8 failed range [%d - %d]", __func__,
3170 CFG_ROAM_INTRA_BAND_MIN,
3171 CFG_ROAM_INTRA_BAND_MAX);
3172 ret = -EINVAL;
3173 goto exit;
3174 }
3175
3176 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3177 (val > CFG_ROAM_INTRA_BAND_MAX))
3178 {
3179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3180 "intra band mode value %d is out of range"
3181 " (Min: %d Max: %d)", val,
3182 CFG_ROAM_INTRA_BAND_MIN,
3183 CFG_ROAM_INTRA_BAND_MAX);
3184 ret = -EINVAL;
3185 goto exit;
3186 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3188 "%s: Received Command to change intra band = %d", __func__, val);
3189
3190 pHddCtx->cfg_ini->nRoamIntraBand = val;
3191 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3192 }
3193 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3194 {
3195 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3196 char extra[32];
3197 tANI_U8 len = 0;
3198
3199 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003200 len = scnprintf(extra, sizeof(extra), "%s %d",
3201 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003202 if (copy_to_user(priv_data.buf, &extra, len + 1))
3203 {
3204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3205 "%s: failed to copy data to user buffer", __func__);
3206 ret = -EFAULT;
3207 goto exit;
3208 }
3209 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003210 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3211 {
3212 tANI_U8 *value = command;
3213 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3214
3215 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3216 value = value + 15;
3217 /* Convert the value from ascii to integer */
3218 ret = kstrtou8(value, 10, &nProbes);
3219 if (ret < 0)
3220 {
3221 /* If the input value is greater than max value of datatype, then also
3222 kstrtou8 fails */
3223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3224 "%s: kstrtou8 failed range [%d - %d]", __func__,
3225 CFG_ROAM_SCAN_N_PROBES_MIN,
3226 CFG_ROAM_SCAN_N_PROBES_MAX);
3227 ret = -EINVAL;
3228 goto exit;
3229 }
3230
3231 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3232 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3233 {
3234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3235 "NProbes value %d is out of range"
3236 " (Min: %d Max: %d)", nProbes,
3237 CFG_ROAM_SCAN_N_PROBES_MIN,
3238 CFG_ROAM_SCAN_N_PROBES_MAX);
3239 ret = -EINVAL;
3240 goto exit;
3241 }
3242
3243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3244 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3245
3246 pHddCtx->cfg_ini->nProbes = nProbes;
3247 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3248 }
3249 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3250 {
3251 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3252 char extra[32];
3253 tANI_U8 len = 0;
3254
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003255 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003256 if (copy_to_user(priv_data.buf, &extra, len + 1))
3257 {
3258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3259 "%s: failed to copy data to user buffer", __func__);
3260 ret = -EFAULT;
3261 goto exit;
3262 }
3263 }
3264 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3265 {
3266 tANI_U8 *value = command;
3267 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3268
3269 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3270 /* input value is in units of msec */
3271 value = value + 20;
3272 /* Convert the value from ascii to integer */
3273 ret = kstrtou16(value, 10, &homeAwayTime);
3274 if (ret < 0)
3275 {
3276 /* If the input value is greater than max value of datatype, then also
3277 kstrtou8 fails */
3278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3279 "%s: kstrtou8 failed range [%d - %d]", __func__,
3280 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3281 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3282 ret = -EINVAL;
3283 goto exit;
3284 }
3285
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003286 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3287 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3288 {
3289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3290 "homeAwayTime value %d is out of range"
3291 " (Min: %d Max: %d)", homeAwayTime,
3292 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3293 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3294 ret = -EINVAL;
3295 goto exit;
3296 }
3297
3298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3299 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003300 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3301 {
3302 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3303 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3304 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003305 }
3306 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3307 {
3308 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3309 char extra[32];
3310 tANI_U8 len = 0;
3311
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003312 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003313 if (copy_to_user(priv_data.buf, &extra, len + 1))
3314 {
3315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3316 "%s: failed to copy data to user buffer", __func__);
3317 ret = -EFAULT;
3318 goto exit;
3319 }
3320 }
3321 else if (strncmp(command, "REASSOC", 7) == 0)
3322 {
3323 tANI_U8 *value = command;
3324 tANI_U8 channel = 0;
3325 tSirMacAddr targetApBssid;
3326 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003327#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3328 tCsrHandoffRequest handoffInfo;
3329#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003330 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003331 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3332
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003333 /* if not associated, no need to proceed with reassoc */
3334 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3335 {
3336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3337 ret = -EINVAL;
3338 goto exit;
3339 }
3340
3341 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3342 if (eHAL_STATUS_SUCCESS != status)
3343 {
3344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3345 "%s: Failed to parse reassoc command data", __func__);
3346 ret = -EINVAL;
3347 goto exit;
3348 }
3349
3350 /* if the target bssid is same as currently associated AP,
3351 then no need to proceed with reassoc */
3352 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3353 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3354 {
3355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3356 ret = -EINVAL;
3357 goto exit;
3358 }
3359
3360 /* Check channel number is a valid channel number */
3361 if(VOS_STATUS_SUCCESS !=
3362 wlan_hdd_validate_operation_channel(pAdapter, channel))
3363 {
3364 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003365 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003366 return -EINVAL;
3367 }
3368
3369 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003370#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3371 handoffInfo.channel = channel;
3372 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3373 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3374#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003375 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003376 else if (strncmp(command, "SETWESMODE", 10) == 0)
3377 {
3378 tANI_U8 *value = command;
3379 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3380
3381 /* Move pointer to ahead of SETWESMODE<delimiter> */
3382 value = value + 11;
3383 /* Convert the value from ascii to integer */
3384 ret = kstrtou8(value, 10, &wesMode);
3385 if (ret < 0)
3386 {
3387 /* If the input value is greater than max value of datatype, then also
3388 kstrtou8 fails */
3389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3390 "%s: kstrtou8 failed range [%d - %d]", __func__,
3391 CFG_ENABLE_WES_MODE_NAME_MIN,
3392 CFG_ENABLE_WES_MODE_NAME_MAX);
3393 ret = -EINVAL;
3394 goto exit;
3395 }
3396
3397 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3398 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3399 {
3400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3401 "WES Mode value %d is out of range"
3402 " (Min: %d Max: %d)", wesMode,
3403 CFG_ENABLE_WES_MODE_NAME_MIN,
3404 CFG_ENABLE_WES_MODE_NAME_MAX);
3405 ret = -EINVAL;
3406 goto exit;
3407 }
3408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3409 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3410
3411 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3412 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3413 }
3414 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3415 {
3416 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3417 char extra[32];
3418 tANI_U8 len = 0;
3419
Arif Hussain826d9412013-11-12 16:44:54 -08003420 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003421 if (copy_to_user(priv_data.buf, &extra, len + 1))
3422 {
3423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3424 "%s: failed to copy data to user buffer", __func__);
3425 ret = -EFAULT;
3426 goto exit;
3427 }
3428 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003429#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003430#ifdef FEATURE_WLAN_LFR
3431 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3432 {
3433 tANI_U8 *value = command;
3434 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3435
3436 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3437 value = value + 12;
3438 /* Convert the value from ascii to integer */
3439 ret = kstrtou8(value, 10, &lfrMode);
3440 if (ret < 0)
3441 {
3442 /* If the input value is greater than max value of datatype, then also
3443 kstrtou8 fails */
3444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3445 "%s: kstrtou8 failed range [%d - %d]", __func__,
3446 CFG_LFR_FEATURE_ENABLED_MIN,
3447 CFG_LFR_FEATURE_ENABLED_MAX);
3448 ret = -EINVAL;
3449 goto exit;
3450 }
3451
3452 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3453 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3454 {
3455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3456 "lfr mode value %d is out of range"
3457 " (Min: %d Max: %d)", lfrMode,
3458 CFG_LFR_FEATURE_ENABLED_MIN,
3459 CFG_LFR_FEATURE_ENABLED_MAX);
3460 ret = -EINVAL;
3461 goto exit;
3462 }
3463
3464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3465 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3466
3467 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3468 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3469 }
3470#endif
3471#ifdef WLAN_FEATURE_VOWIFI_11R
3472 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3473 {
3474 tANI_U8 *value = command;
3475 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3476
3477 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3478 value = value + 18;
3479 /* Convert the value from ascii to integer */
3480 ret = kstrtou8(value, 10, &ft);
3481 if (ret < 0)
3482 {
3483 /* If the input value is greater than max value of datatype, then also
3484 kstrtou8 fails */
3485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3486 "%s: kstrtou8 failed range [%d - %d]", __func__,
3487 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3488 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3489 ret = -EINVAL;
3490 goto exit;
3491 }
3492
3493 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3494 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3495 {
3496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3497 "ft mode value %d is out of range"
3498 " (Min: %d Max: %d)", ft,
3499 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3500 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3501 ret = -EINVAL;
3502 goto exit;
3503 }
3504
3505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3506 "%s: Received Command to change ft mode = %d", __func__, ft);
3507
3508 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3509 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3510 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303511
3512 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3513 {
3514 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303515 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303516 tSirMacAddr targetApBssid;
3517 tANI_U8 trigger = 0;
3518 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303519 tHalHandle hHal;
3520 v_U32_t roamId = 0;
3521 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303522 hdd_station_ctx_t *pHddStaCtx = NULL;
3523 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303524 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303525
3526 /* if not associated, no need to proceed with reassoc */
3527 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3528 {
3529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3530 ret = -EINVAL;
3531 goto exit;
3532 }
3533
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303534 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303535 if (eHAL_STATUS_SUCCESS != status)
3536 {
3537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3538 "%s: Failed to parse reassoc command data", __func__);
3539 ret = -EINVAL;
3540 goto exit;
3541 }
3542
3543 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303544 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303545 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3546 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3547 {
3548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3549 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3550 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303551 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3552 &modProfileFields);
3553 sme_RoamReassoc(hHal, pAdapter->sessionId,
3554 NULL, modProfileFields, &roamId, 1);
3555 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303556 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303557
3558 /* Check channel number is a valid channel number */
3559 if(VOS_STATUS_SUCCESS !=
3560 wlan_hdd_validate_operation_channel(pAdapter, channel))
3561 {
3562 hddLog(VOS_TRACE_LEVEL_ERROR,
3563 "%s: Invalid Channel [%d]", __func__, channel);
3564 return -EINVAL;
3565 }
3566
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303567 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303568
3569 /* Proceed with scan/roam */
3570 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3571 &targetApBssid[0],
3572 (tSmeFastRoamTrigger)(trigger));
3573 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003574#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003575#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003576 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3577 {
3578 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003579 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003580
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003581 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003582 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003583 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003584 hdd_is_okc_mode_enabled(pHddCtx) &&
3585 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3586 {
3587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003588 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003589 " hence this operation is not permitted!", __func__);
3590 ret = -EPERM;
3591 goto exit;
3592 }
3593
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003594 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3595 value = value + 11;
3596 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003597 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003598 if (ret < 0)
3599 {
3600 /* If the input value is greater than max value of datatype, then also
3601 kstrtou8 fails */
3602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3603 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003604 CFG_ESE_FEATURE_ENABLED_MIN,
3605 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003606 ret = -EINVAL;
3607 goto exit;
3608 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003609 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3610 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003611 {
3612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003613 "Ese mode value %d is out of range"
3614 " (Min: %d Max: %d)", eseMode,
3615 CFG_ESE_FEATURE_ENABLED_MIN,
3616 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003617 ret = -EINVAL;
3618 goto exit;
3619 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003621 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003622
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003623 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3624 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003625 }
3626#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003627 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3628 {
3629 tANI_U8 *value = command;
3630 tANI_BOOLEAN roamScanControl = 0;
3631
3632 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3633 value = value + 19;
3634 /* Convert the value from ascii to integer */
3635 ret = kstrtou8(value, 10, &roamScanControl);
3636 if (ret < 0)
3637 {
3638 /* If the input value is greater than max value of datatype, then also
3639 kstrtou8 fails */
3640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3641 "%s: kstrtou8 failed ", __func__);
3642 ret = -EINVAL;
3643 goto exit;
3644 }
3645
3646 if (0 != roamScanControl)
3647 {
3648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3649 "roam scan control invalid value = %d",
3650 roamScanControl);
3651 ret = -EINVAL;
3652 goto exit;
3653 }
3654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3655 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3656
3657 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3658 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003659#ifdef FEATURE_WLAN_OKC
3660 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3661 {
3662 tANI_U8 *value = command;
3663 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3664
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003665 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003666 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003667 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003668 hdd_is_okc_mode_enabled(pHddCtx) &&
3669 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3670 {
3671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003672 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003673 " hence this operation is not permitted!", __func__);
3674 ret = -EPERM;
3675 goto exit;
3676 }
3677
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003678 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3679 value = value + 11;
3680 /* Convert the value from ascii to integer */
3681 ret = kstrtou8(value, 10, &okcMode);
3682 if (ret < 0)
3683 {
3684 /* If the input value is greater than max value of datatype, then also
3685 kstrtou8 fails */
3686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3687 "%s: kstrtou8 failed range [%d - %d]", __func__,
3688 CFG_OKC_FEATURE_ENABLED_MIN,
3689 CFG_OKC_FEATURE_ENABLED_MAX);
3690 ret = -EINVAL;
3691 goto exit;
3692 }
3693
3694 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3695 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3696 {
3697 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3698 "Okc mode value %d is out of range"
3699 " (Min: %d Max: %d)", okcMode,
3700 CFG_OKC_FEATURE_ENABLED_MIN,
3701 CFG_OKC_FEATURE_ENABLED_MAX);
3702 ret = -EINVAL;
3703 goto exit;
3704 }
3705
3706 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3707 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3708
3709 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3710 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003711#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003712 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3713 {
3714 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3715 char extra[32];
3716 tANI_U8 len = 0;
3717
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003718 len = scnprintf(extra, sizeof(extra), "%s %d",
3719 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003720 if (copy_to_user(priv_data.buf, &extra, len + 1))
3721 {
3722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3723 "%s: failed to copy data to user buffer", __func__);
3724 ret = -EFAULT;
3725 goto exit;
3726 }
3727 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303728#ifdef WLAN_FEATURE_PACKET_FILTERING
3729 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3730 {
3731 tANI_U8 filterType = 0;
3732 tANI_U8 *value = command;
3733
3734 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3735 value = value + 22;
3736
3737 /* Convert the value from ascii to integer */
3738 ret = kstrtou8(value, 10, &filterType);
3739 if (ret < 0)
3740 {
3741 /* If the input value is greater than max value of datatype,
3742 * then also kstrtou8 fails
3743 */
3744 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3745 "%s: kstrtou8 failed range ", __func__);
3746 ret = -EINVAL;
3747 goto exit;
3748 }
3749
3750 if (filterType != 0 && filterType != 1)
3751 {
3752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3753 "%s: Accepted Values are 0 and 1 ", __func__);
3754 ret = -EINVAL;
3755 goto exit;
3756 }
3757 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3758 pAdapter->sessionId);
3759 }
3760#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303761 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3762 {
Kiet Lamad161252014-07-22 11:23:32 -07003763 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303764 int ret;
3765
Kiet Lamad161252014-07-22 11:23:32 -07003766 dhcpPhase = command + 11;
3767 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303768 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003770 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303771
3772 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003773
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303774 ret = wlan_hdd_scan_abort(pAdapter);
3775 if (ret < 0)
3776 {
3777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3778 FL("failed to abort existing scan %d"), ret);
3779 }
3780
Kiet Lamad161252014-07-22 11:23:32 -07003781 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3782 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303783 }
Kiet Lamad161252014-07-22 11:23:32 -07003784 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303785 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003787 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303788
3789 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003790
3791 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3792 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303793 }
3794 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003795 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3796 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3798 FL("making default scan to ACTIVE"));
3799 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003800 }
3801 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3802 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3804 FL("making default scan to PASSIVE"));
3805 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003806 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303807 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3808 {
3809 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3810 char extra[32];
3811 tANI_U8 len = 0;
3812
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303813 memset(extra, 0, sizeof(extra));
3814 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3815 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303816 {
3817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3818 "%s: failed to copy data to user buffer", __func__);
3819 ret = -EFAULT;
3820 goto exit;
3821 }
3822 ret = len;
3823 }
3824 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3825 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303826 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303827 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003828 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3829 {
3830 tANI_U8 filterType = 0;
3831 tANI_U8 *value;
3832 value = command + 9;
3833
3834 /* Convert the value from ascii to integer */
3835 ret = kstrtou8(value, 10, &filterType);
3836 if (ret < 0)
3837 {
3838 /* If the input value is greater than max value of datatype,
3839 * then also kstrtou8 fails
3840 */
3841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3842 "%s: kstrtou8 failed range ", __func__);
3843 ret = -EINVAL;
3844 goto exit;
3845 }
3846 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3847 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3848 {
3849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3850 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3851 " 2-Sink ", __func__);
3852 ret = -EINVAL;
3853 goto exit;
3854 }
3855 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3856 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303857 pScanInfo = &pHddCtx->scan_info;
3858 if (filterType && pScanInfo != NULL &&
3859 pHddCtx->scan_info.mScanPending)
3860 {
3861 /*Miracast Session started. Abort Scan */
3862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3863 "%s, Aborting Scan For Miracast",__func__);
3864 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3865 eCSR_SCAN_ABORT_DEFAULT);
3866 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003867 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303868 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003869 }
Leo Chang614d2072013-08-22 14:59:44 -07003870 else if (strncmp(command, "SETMCRATE", 9) == 0)
3871 {
Leo Chang614d2072013-08-22 14:59:44 -07003872 tANI_U8 *value = command;
3873 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003874 tSirRateUpdateInd *rateUpdate;
3875 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003876
3877 /* Only valid for SAP mode */
3878 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3879 {
3880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3881 "%s: SAP mode is not running", __func__);
3882 ret = -EFAULT;
3883 goto exit;
3884 }
3885
3886 /* Move pointer to ahead of SETMCRATE<delimiter> */
3887 /* input value is in units of hundred kbps */
3888 value = value + 10;
3889 /* Convert the value from ascii to integer, decimal base */
3890 ret = kstrtouint(value, 10, &targetRate);
3891
Leo Chang1f98cbd2013-10-17 15:03:52 -07003892 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3893 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003894 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003895 hddLog(VOS_TRACE_LEVEL_ERROR,
3896 "%s: SETMCRATE indication alloc fail", __func__);
3897 ret = -EFAULT;
3898 goto exit;
3899 }
3900 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3901
3902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3903 "MC Target rate %d", targetRate);
3904 /* Ignore unicast */
3905 rateUpdate->ucastDataRate = -1;
3906 rateUpdate->mcastDataRate24GHz = targetRate;
3907 rateUpdate->mcastDataRate5GHz = targetRate;
3908 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3909 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3910 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3911 if (eHAL_STATUS_SUCCESS != status)
3912 {
3913 hddLog(VOS_TRACE_LEVEL_ERROR,
3914 "%s: SET_MC_RATE failed", __func__);
3915 vos_mem_free(rateUpdate);
3916 ret = -EFAULT;
3917 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003918 }
3919 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303920#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003921 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303922 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003923 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303924 }
3925#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003926#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003927 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3928 {
3929 tANI_U8 *value = command;
3930 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3931 tANI_U8 numChannels = 0;
3932 eHalStatus status = eHAL_STATUS_SUCCESS;
3933
3934 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3935 if (eHAL_STATUS_SUCCESS != status)
3936 {
3937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3938 "%s: Failed to parse channel list information", __func__);
3939 ret = -EINVAL;
3940 goto exit;
3941 }
3942
3943 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3944 {
3945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3946 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3947 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3948 ret = -EINVAL;
3949 goto exit;
3950 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003951 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003952 ChannelList,
3953 numChannels);
3954 if (eHAL_STATUS_SUCCESS != status)
3955 {
3956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3957 "%s: Failed to update channel list information", __func__);
3958 ret = -EINVAL;
3959 goto exit;
3960 }
3961 }
3962 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3963 {
3964 tANI_U8 *value = command;
3965 char extra[128] = {0};
3966 int len = 0;
3967 tANI_U8 tid = 0;
3968 hdd_station_ctx_t *pHddStaCtx = NULL;
3969 tAniTrafStrmMetrics tsmMetrics;
3970 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3971
3972 /* if not associated, return error */
3973 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3974 {
3975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3976 ret = -EINVAL;
3977 goto exit;
3978 }
3979
3980 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3981 value = value + 12;
3982 /* Convert the value from ascii to integer */
3983 ret = kstrtou8(value, 10, &tid);
3984 if (ret < 0)
3985 {
3986 /* If the input value is greater than max value of datatype, then also
3987 kstrtou8 fails */
3988 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3989 "%s: kstrtou8 failed range [%d - %d]", __func__,
3990 TID_MIN_VALUE,
3991 TID_MAX_VALUE);
3992 ret = -EINVAL;
3993 goto exit;
3994 }
3995
3996 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3997 {
3998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3999 "tid value %d is out of range"
4000 " (Min: %d Max: %d)", tid,
4001 TID_MIN_VALUE,
4002 TID_MAX_VALUE);
4003 ret = -EINVAL;
4004 goto exit;
4005 }
4006
4007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4008 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4009
4010 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4011 {
4012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4013 "%s: failed to get tsm stats", __func__);
4014 ret = -EFAULT;
4015 goto exit;
4016 }
4017
4018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4019 "UplinkPktQueueDly(%d)\n"
4020 "UplinkPktQueueDlyHist[0](%d)\n"
4021 "UplinkPktQueueDlyHist[1](%d)\n"
4022 "UplinkPktQueueDlyHist[2](%d)\n"
4023 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304024 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004025 "UplinkPktLoss(%d)\n"
4026 "UplinkPktCount(%d)\n"
4027 "RoamingCount(%d)\n"
4028 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4029 tsmMetrics.UplinkPktQueueDlyHist[0],
4030 tsmMetrics.UplinkPktQueueDlyHist[1],
4031 tsmMetrics.UplinkPktQueueDlyHist[2],
4032 tsmMetrics.UplinkPktQueueDlyHist[3],
4033 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4034 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4035
4036 /* Output TSM stats is of the format
4037 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4038 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004039 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004040 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4041 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4042 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4043 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4044 tsmMetrics.RoamingDly);
4045
4046 if (copy_to_user(priv_data.buf, &extra, len + 1))
4047 {
4048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4049 "%s: failed to copy data to user buffer", __func__);
4050 ret = -EFAULT;
4051 goto exit;
4052 }
4053 }
4054 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4055 {
4056 tANI_U8 *value = command;
4057 tANI_U8 *cckmIe = NULL;
4058 tANI_U8 cckmIeLen = 0;
4059 eHalStatus status = eHAL_STATUS_SUCCESS;
4060
4061 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4062 if (eHAL_STATUS_SUCCESS != status)
4063 {
4064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4065 "%s: Failed to parse cckm ie data", __func__);
4066 ret = -EINVAL;
4067 goto exit;
4068 }
4069
4070 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4071 {
4072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4073 "%s: CCKM Ie input length is more than max[%d]", __func__,
4074 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004075 vos_mem_free(cckmIe);
4076 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004077 ret = -EINVAL;
4078 goto exit;
4079 }
4080 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004081 vos_mem_free(cckmIe);
4082 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004083 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004084 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4085 {
4086 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004087 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004088 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004089
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004090 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004091 if (eHAL_STATUS_SUCCESS != status)
4092 {
4093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004094 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004095 ret = -EINVAL;
4096 goto exit;
4097 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004098 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4099 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4100 hdd_indicateEseBcnReportNoResults (pAdapter,
4101 eseBcnReq.bcnReq[0].measurementToken,
4102 0x02, //BIT(1) set for measurement done
4103 0); // no BSS
4104 goto exit;
4105 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004106
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004107 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4108 if (eHAL_STATUS_SUCCESS != status)
4109 {
4110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4111 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4112 ret = -EINVAL;
4113 goto exit;
4114 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004115 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004116#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304117 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4118 {
4119 eHalStatus status;
4120 char buf[32], len;
4121 long waitRet;
4122 bcnMissRateContext_t getBcnMissRateCtx;
4123
4124 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4125
4126 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4127 {
4128 hddLog(VOS_TRACE_LEVEL_WARN,
4129 FL("GETBCNMISSRATE: STA is not in connected state"));
4130 ret = -1;
4131 goto exit;
4132 }
4133
4134 init_completion(&(getBcnMissRateCtx.completion));
4135 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4136
4137 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4138 pAdapter->sessionId,
4139 (void *)getBcnMissRateCB,
4140 (void *)(&getBcnMissRateCtx));
4141 if( eHAL_STATUS_SUCCESS != status)
4142 {
4143 hddLog(VOS_TRACE_LEVEL_INFO,
4144 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4145 ret = -EINVAL;
4146 goto exit;
4147 }
4148
4149 waitRet = wait_for_completion_interruptible_timeout
4150 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4151 if(waitRet <= 0)
4152 {
4153 hddLog(VOS_TRACE_LEVEL_ERROR,
4154 FL("failed to wait on bcnMissRateComp %d"), ret);
4155
4156 //Make magic number to zero so that callback is not called.
4157 spin_lock(&hdd_context_lock);
4158 getBcnMissRateCtx.magic = 0x0;
4159 spin_unlock(&hdd_context_lock);
4160 ret = -EINVAL;
4161 goto exit;
4162 }
4163
4164 hddLog(VOS_TRACE_LEVEL_INFO,
4165 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4166
4167 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4168 if (copy_to_user(priv_data.buf, &buf, len + 1))
4169 {
4170 hddLog(VOS_TRACE_LEVEL_ERROR,
4171 "%s: failed to copy data to user buffer", __func__);
4172 ret = -EFAULT;
4173 goto exit;
4174 }
4175 ret = len;
4176 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304177#ifdef FEATURE_WLAN_TDLS
4178 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4179 tANI_U8 *value = command;
4180 int set_value;
4181 /* Move pointer to ahead of TDLSOFFCH*/
4182 value += 26;
4183 sscanf(value, "%d", &set_value);
4184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4185 "%s: Tdls offchannel offset:%d",
4186 __func__, set_value);
4187 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4188 if (ret < 0)
4189 {
4190 ret = -EINVAL;
4191 goto exit;
4192 }
4193
4194 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4195 tANI_U8 *value = command;
4196 int set_value;
4197 /* Move pointer to ahead of tdlsoffchnmode*/
4198 value += 18;
4199 sscanf(value, "%d", &set_value);
4200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4201 "%s: Tdls offchannel mode:%d",
4202 __func__, set_value);
4203 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4204 if (ret < 0)
4205 {
4206 ret = -EINVAL;
4207 goto exit;
4208 }
4209 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4210 tANI_U8 *value = command;
4211 int set_value;
4212 /* Move pointer to ahead of TDLSOFFCH*/
4213 value += 14;
4214 sscanf(value, "%d", &set_value);
4215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4216 "%s: Tdls offchannel num: %d",
4217 __func__, set_value);
4218 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4219 if (ret < 0)
4220 {
4221 ret = -EINVAL;
4222 goto exit;
4223 }
4224 }
4225#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304226 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4227 {
4228 eHalStatus status;
4229 char *buf = NULL;
4230 char len;
4231 long waitRet;
4232 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304233 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304234 tANI_U8 *ptr = command;
4235 int stats = *(ptr + 11) - '0';
4236
4237 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4238 if (!IS_FEATURE_FW_STATS_ENABLE)
4239 {
4240 hddLog(VOS_TRACE_LEVEL_INFO,
4241 FL("Get Firmware stats feature not supported"));
4242 ret = -EINVAL;
4243 goto exit;
4244 }
4245
4246 if (FW_STATS_MAX <= stats || 0 >= stats)
4247 {
4248 hddLog(VOS_TRACE_LEVEL_INFO,
4249 FL(" stats %d not supported"),stats);
4250 ret = -EINVAL;
4251 goto exit;
4252 }
4253
4254 init_completion(&(fwStatsCtx.completion));
4255 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4256 fwStatsCtx.pAdapter = pAdapter;
4257 fwStatsRsp->type = 0;
4258 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304259 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304260 if (eHAL_STATUS_SUCCESS != status)
4261 {
4262 hddLog(VOS_TRACE_LEVEL_ERROR,
4263 FL(" fail to post WDA cmd status = %d"), status);
4264 ret = -EINVAL;
4265 goto exit;
4266 }
4267 waitRet = wait_for_completion_timeout
4268 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4269 if (waitRet <= 0)
4270 {
4271 hddLog(VOS_TRACE_LEVEL_ERROR,
4272 FL("failed to wait on GwtFwstats"));
4273 //Make magic number to zero so that callback is not executed.
4274 spin_lock(&hdd_context_lock);
4275 fwStatsCtx.magic = 0x0;
4276 spin_unlock(&hdd_context_lock);
4277 ret = -EINVAL;
4278 goto exit;
4279 }
4280 if (fwStatsRsp->type)
4281 {
4282 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4283 if (!buf)
4284 {
4285 hddLog(VOS_TRACE_LEVEL_ERROR,
4286 FL(" failed to allocate memory"));
4287 ret = -ENOMEM;
4288 goto exit;
4289 }
4290 switch( fwStatsRsp->type )
4291 {
4292 case FW_UBSP_STATS:
4293 {
4294 len = snprintf(buf, FW_STATE_RSP_LEN,
4295 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304296 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4297 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304298 }
4299 break;
4300 default:
4301 {
4302 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4303 ret = -EFAULT;
4304 kfree(buf);
4305 goto exit;
4306 }
4307 }
4308 if (copy_to_user(priv_data.buf, buf, len + 1))
4309 {
4310 hddLog(VOS_TRACE_LEVEL_ERROR,
4311 FL(" failed to copy data to user buffer"));
4312 ret = -EFAULT;
4313 kfree(buf);
4314 goto exit;
4315 }
4316 ret = len;
4317 kfree(buf);
4318 }
4319 else
4320 {
4321 hddLog(VOS_TRACE_LEVEL_ERROR,
4322 FL("failed to fetch the stats"));
4323 ret = -EFAULT;
4324 goto exit;
4325 }
4326
4327 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004328 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304329 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4330 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4331 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304332 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4333 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004334 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004335 }
4336exit:
4337 if (command)
4338 {
4339 kfree(command);
4340 }
4341 return ret;
4342}
4343
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004344#ifdef CONFIG_COMPAT
4345static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4346{
4347 struct {
4348 compat_uptr_t buf;
4349 int used_len;
4350 int total_len;
4351 } compat_priv_data;
4352 hdd_priv_data_t priv_data;
4353 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004354
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004355 /*
4356 * Note that pAdapter and ifr have already been verified by caller,
4357 * and HDD context has also been validated
4358 */
4359 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4360 sizeof(compat_priv_data))) {
4361 ret = -EFAULT;
4362 goto exit;
4363 }
4364 priv_data.buf = compat_ptr(compat_priv_data.buf);
4365 priv_data.used_len = compat_priv_data.used_len;
4366 priv_data.total_len = compat_priv_data.total_len;
4367 ret = hdd_driver_command(pAdapter, &priv_data);
4368 exit:
4369 return ret;
4370}
4371#else /* CONFIG_COMPAT */
4372static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4373{
4374 /* will never be invoked */
4375 return 0;
4376}
4377#endif /* CONFIG_COMPAT */
4378
4379static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4380{
4381 hdd_priv_data_t priv_data;
4382 int ret = 0;
4383
4384 /*
4385 * Note that pAdapter and ifr have already been verified by caller,
4386 * and HDD context has also been validated
4387 */
4388 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4389 ret = -EFAULT;
4390 } else {
4391 ret = hdd_driver_command(pAdapter, &priv_data);
4392 }
4393 return ret;
4394}
4395
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304396int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004397{
4398 hdd_adapter_t *pAdapter;
4399 hdd_context_t *pHddCtx;
4400 int ret;
4401
4402 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4403 if (NULL == pAdapter) {
4404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4405 "%s: HDD adapter context is Null", __func__);
4406 ret = -ENODEV;
4407 goto exit;
4408 }
4409 if (dev != pAdapter->dev) {
4410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4411 "%s: HDD adapter/dev inconsistency", __func__);
4412 ret = -ENODEV;
4413 goto exit;
4414 }
4415
4416 if ((!ifr) || (!ifr->ifr_data)) {
4417 ret = -EINVAL;
4418 goto exit;
4419 }
4420
4421 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4422 ret = wlan_hdd_validate_context(pHddCtx);
4423 if (ret) {
Mahesh A Saptasagar5b16d0a2014-11-03 17:55:29 +05304424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004425 "%s: invalid context", __func__);
4426 ret = -EBUSY;
4427 goto exit;
4428 }
4429
4430 switch (cmd) {
4431 case (SIOCDEVPRIVATE + 1):
4432 if (is_compat_task())
4433 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4434 else
4435 ret = hdd_driver_ioctl(pAdapter, ifr);
4436 break;
4437 default:
4438 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4439 __func__, cmd);
4440 ret = -EINVAL;
4441 break;
4442 }
4443 exit:
4444 return ret;
4445}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004446
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304447int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4448{
4449 int ret;
4450
4451 vos_ssr_protect(__func__);
4452 ret = __hdd_ioctl(dev, ifr, cmd);
4453 vos_ssr_unprotect(__func__);
4454
4455 return ret;
4456}
4457
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004458#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004459/**---------------------------------------------------------------------------
4460
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004461 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004462
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004463 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004464 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4465 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4466 <space>Scan Mode N<space>Meas Duration N
4467 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4468 then take N.
4469 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4470 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4471 This function does not take care of removing duplicate channels from the list
4472
4473 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004474 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004475
4476 \return - 0 for success non-zero for failure
4477
4478 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004479static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4480 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004481{
4482 tANI_U8 *inPtr = pValue;
4483 int tempInt = 0;
4484 int j = 0, i = 0, v = 0;
4485 char buf[32];
4486
4487 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4488 /*no argument after the command*/
4489 if (NULL == inPtr)
4490 {
4491 return -EINVAL;
4492 }
4493 /*no space after the command*/
4494 else if (SPACE_ASCII_VALUE != *inPtr)
4495 {
4496 return -EINVAL;
4497 }
4498
4499 /*removing empty spaces*/
4500 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4501
4502 /*no argument followed by spaces*/
4503 if ('\0' == *inPtr) return -EINVAL;
4504
4505 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004506 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004507 if (1 != v) return -EINVAL;
4508
4509 v = kstrtos32(buf, 10, &tempInt);
4510 if ( v < 0) return -EINVAL;
4511
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004512 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004513
4514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004515 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004516
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004517 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004518 {
4519 for (i = 0; i < 4; i++)
4520 {
4521 /*inPtr pointing to the beginning of first space after number of ie fields*/
4522 inPtr = strpbrk( inPtr, " " );
4523 /*no ie data after the number of ie fields argument*/
4524 if (NULL == inPtr) return -EINVAL;
4525
4526 /*removing empty space*/
4527 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4528
4529 /*no ie data after the number of ie fields argument and spaces*/
4530 if ( '\0' == *inPtr ) return -EINVAL;
4531
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004532 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004533 if (1 != v) return -EINVAL;
4534
4535 v = kstrtos32(buf, 10, &tempInt);
4536 if (v < 0) return -EINVAL;
4537
4538 switch (i)
4539 {
4540 case 0: /* Measurement token */
4541 if (tempInt <= 0)
4542 {
4543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4544 "Invalid Measurement Token(%d)", tempInt);
4545 return -EINVAL;
4546 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004547 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004548 break;
4549
4550 case 1: /* Channel number */
4551 if ((tempInt <= 0) ||
4552 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4553 {
4554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4555 "Invalid Channel Number(%d)", tempInt);
4556 return -EINVAL;
4557 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004558 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004559 break;
4560
4561 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004562 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004563 {
4564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4565 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4566 return -EINVAL;
4567 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004568 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004569 break;
4570
4571 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004572 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4573 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004574 {
4575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4576 "Invalid Measurement Duration(%d)", tempInt);
4577 return -EINVAL;
4578 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004579 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004580 break;
4581 }
4582 }
4583 }
4584
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004585 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004586 {
4587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304588 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004589 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004590 pEseBcnReq->bcnReq[j].measurementToken,
4591 pEseBcnReq->bcnReq[j].channel,
4592 pEseBcnReq->bcnReq[j].scanMode,
4593 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004594 }
4595
4596 return VOS_STATUS_SUCCESS;
4597}
4598
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004599static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4600{
4601 struct statsContext *pStatsContext = NULL;
4602 hdd_adapter_t *pAdapter = NULL;
4603
4604 if (NULL == pContext)
4605 {
4606 hddLog(VOS_TRACE_LEVEL_ERROR,
4607 "%s: Bad param, pContext [%p]",
4608 __func__, pContext);
4609 return;
4610 }
4611
Jeff Johnson72a40512013-12-19 10:14:15 -08004612 /* there is a race condition that exists between this callback
4613 function and the caller since the caller could time out either
4614 before or while this code is executing. we use a spinlock to
4615 serialize these actions */
4616 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004617
4618 pStatsContext = pContext;
4619 pAdapter = pStatsContext->pAdapter;
4620 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4621 {
4622 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004623 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004624 hddLog(VOS_TRACE_LEVEL_WARN,
4625 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4626 __func__, pAdapter, pStatsContext->magic);
4627 return;
4628 }
4629
Jeff Johnson72a40512013-12-19 10:14:15 -08004630 /* context is valid so caller is still waiting */
4631
4632 /* paranoia: invalidate the magic */
4633 pStatsContext->magic = 0;
4634
4635 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004636 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4637 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4638 tsmMetrics.UplinkPktQueueDlyHist,
4639 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4640 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4641 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4642 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4643 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4644 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4645 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4646
Jeff Johnson72a40512013-12-19 10:14:15 -08004647 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004648 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004649
4650 /* serialization is complete */
4651 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004652}
4653
4654
4655
4656static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4657 tAniTrafStrmMetrics* pTsmMetrics)
4658{
4659 hdd_station_ctx_t *pHddStaCtx = NULL;
4660 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004661 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004662 long lrc;
4663 struct statsContext context;
4664 hdd_context_t *pHddCtx = NULL;
4665
4666 if (NULL == pAdapter)
4667 {
4668 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4669 return VOS_STATUS_E_FAULT;
4670 }
4671
4672 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4673 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4674
4675 /* we are connected prepare our callback context */
4676 init_completion(&context.completion);
4677 context.pAdapter = pAdapter;
4678 context.magic = STATS_CONTEXT_MAGIC;
4679
4680 /* query tsm stats */
4681 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4682 pHddStaCtx->conn_info.staId[ 0 ],
4683 pHddStaCtx->conn_info.bssId,
4684 &context, pHddCtx->pvosContext, tid);
4685
4686 if (eHAL_STATUS_SUCCESS != hstatus)
4687 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4689 __func__);
4690 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004691 }
4692 else
4693 {
4694 /* request was sent -- wait for the response */
4695 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4696 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004697 if (lrc <= 0)
4698 {
4699 hddLog(VOS_TRACE_LEVEL_ERROR,
4700 "%s: SME %s while retrieving statistics",
4701 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004702 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004703 }
4704 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004705
Jeff Johnson72a40512013-12-19 10:14:15 -08004706 /* either we never sent a request, we sent a request and received a
4707 response or we sent a request and timed out. if we never sent a
4708 request or if we sent a request and got a response, we want to
4709 clear the magic out of paranoia. if we timed out there is a
4710 race condition such that the callback function could be
4711 executing at the same time we are. of primary concern is if the
4712 callback function had already verified the "magic" but had not
4713 yet set the completion variable when a timeout occurred. we
4714 serialize these activities by invalidating the magic while
4715 holding a shared spinlock which will cause us to block if the
4716 callback is currently executing */
4717 spin_lock(&hdd_context_lock);
4718 context.magic = 0;
4719 spin_unlock(&hdd_context_lock);
4720
4721 if (VOS_STATUS_SUCCESS == vstatus)
4722 {
4723 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4724 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4725 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4726 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4727 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4728 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4729 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4730 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4731 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4732 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4733 }
4734 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004735}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004736#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004737
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004738#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004739void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4740{
4741 eCsrBand band = -1;
4742 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4743 switch (band)
4744 {
4745 case eCSR_BAND_ALL:
4746 *pBand = WLAN_HDD_UI_BAND_AUTO;
4747 break;
4748
4749 case eCSR_BAND_24:
4750 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4751 break;
4752
4753 case eCSR_BAND_5G:
4754 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4755 break;
4756
4757 default:
4758 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4759 *pBand = -1;
4760 break;
4761 }
4762}
4763
4764/**---------------------------------------------------------------------------
4765
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004766 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4767
4768 This function parses the send action frame data passed in the format
4769 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4770
Srinivas Girigowda56076852013-08-20 14:00:50 -07004771 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004772 \param - pTargetApBssid Pointer to target Ap bssid
4773 \param - pChannel Pointer to the Target AP channel
4774 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4775 \param - pBuf Pointer to data
4776 \param - pBufLen Pointer to data length
4777
4778 \return - 0 for success non-zero for failure
4779
4780 --------------------------------------------------------------------------*/
4781VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4782 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4783{
4784 tANI_U8 *inPtr = pValue;
4785 tANI_U8 *dataEnd;
4786 int tempInt;
4787 int j = 0;
4788 int i = 0;
4789 int v = 0;
4790 tANI_U8 tempBuf[32];
4791 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004792 /* 12 hexa decimal digits, 5 ':' and '\0' */
4793 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004794
4795 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4796 /*no argument after the command*/
4797 if (NULL == inPtr)
4798 {
4799 return -EINVAL;
4800 }
4801
4802 /*no space after the command*/
4803 else if (SPACE_ASCII_VALUE != *inPtr)
4804 {
4805 return -EINVAL;
4806 }
4807
4808 /*removing empty spaces*/
4809 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4810
4811 /*no argument followed by spaces*/
4812 if ('\0' == *inPtr)
4813 {
4814 return -EINVAL;
4815 }
4816
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004817 v = sscanf(inPtr, "%17s", macAddress);
4818 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004819 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4821 "Invalid MAC address or All hex inputs are not read (%d)", v);
4822 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004823 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004824
4825 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4826 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4827 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4828 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4829 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4830 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004831
4832 /* point to the next argument */
4833 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4834 /*no argument after the command*/
4835 if (NULL == inPtr) return -EINVAL;
4836
4837 /*removing empty spaces*/
4838 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4839
4840 /*no argument followed by spaces*/
4841 if ('\0' == *inPtr)
4842 {
4843 return -EINVAL;
4844 }
4845
4846 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004847 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004848 if (1 != v) return -EINVAL;
4849
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004850 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304851 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304852 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004853
4854 *pChannel = tempInt;
4855
4856 /* point to the next argument */
4857 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4858 /*no argument after the command*/
4859 if (NULL == inPtr) return -EINVAL;
4860 /*removing empty spaces*/
4861 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4862
4863 /*no argument followed by spaces*/
4864 if ('\0' == *inPtr)
4865 {
4866 return -EINVAL;
4867 }
4868
4869 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004870 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004871 if (1 != v) return -EINVAL;
4872
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004873 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004874 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004875
4876 *pDwellTime = tempInt;
4877
4878 /* point to the next argument */
4879 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4880 /*no argument after the command*/
4881 if (NULL == inPtr) return -EINVAL;
4882 /*removing empty spaces*/
4883 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4884
4885 /*no argument followed by spaces*/
4886 if ('\0' == *inPtr)
4887 {
4888 return -EINVAL;
4889 }
4890
4891 /* find the length of data */
4892 dataEnd = inPtr;
4893 while(('\0' != *dataEnd) )
4894 {
4895 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004896 }
Kiet Lambe150c22013-11-21 16:30:32 +05304897 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004898 if ( *pBufLen <= 0) return -EINVAL;
4899
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004900 /* Allocate the number of bytes based on the number of input characters
4901 whether it is even or odd.
4902 if the number of input characters are even, then we need N/2 byte.
4903 if the number of input characters are odd, then we need do (N+1)/2 to
4904 compensate rounding off.
4905 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4906 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4907 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004908 if (NULL == *pBuf)
4909 {
4910 hddLog(VOS_TRACE_LEVEL_FATAL,
4911 "%s: vos_mem_alloc failed ", __func__);
4912 return -EINVAL;
4913 }
4914
4915 /* the buffer received from the upper layer is character buffer,
4916 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4917 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4918 and f0 in 3rd location */
4919 for (i = 0, j = 0; j < *pBufLen; j += 2)
4920 {
Kiet Lambe150c22013-11-21 16:30:32 +05304921 if( j+1 == *pBufLen)
4922 {
4923 tempByte = hdd_parse_hex(inPtr[j]);
4924 }
4925 else
4926 {
4927 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4928 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004929 (*pBuf)[i++] = tempByte;
4930 }
4931 *pBufLen = i;
4932 return VOS_STATUS_SUCCESS;
4933}
4934
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004935/**---------------------------------------------------------------------------
4936
Srinivas Girigowdade697412013-02-14 16:31:48 -08004937 \brief hdd_parse_channellist() - HDD Parse channel list
4938
4939 This function parses the channel list passed in the format
4940 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004941 if the Number of channels (N) does not match with the actual number of channels passed
4942 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4943 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4944 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4945 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004946
4947 \param - pValue Pointer to input channel list
4948 \param - ChannelList Pointer to local output array to record channel list
4949 \param - pNumChannels Pointer to number of roam scan channels
4950
4951 \return - 0 for success non-zero for failure
4952
4953 --------------------------------------------------------------------------*/
4954VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4955{
4956 tANI_U8 *inPtr = pValue;
4957 int tempInt;
4958 int j = 0;
4959 int v = 0;
4960 char buf[32];
4961
4962 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4963 /*no argument after the command*/
4964 if (NULL == inPtr)
4965 {
4966 return -EINVAL;
4967 }
4968
4969 /*no space after the command*/
4970 else if (SPACE_ASCII_VALUE != *inPtr)
4971 {
4972 return -EINVAL;
4973 }
4974
4975 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004976 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004977
4978 /*no argument followed by spaces*/
4979 if ('\0' == *inPtr)
4980 {
4981 return -EINVAL;
4982 }
4983
4984 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004985 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004986 if (1 != v) return -EINVAL;
4987
Srinivas Girigowdade697412013-02-14 16:31:48 -08004988 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004989 if ((v < 0) ||
4990 (tempInt <= 0) ||
4991 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4992 {
4993 return -EINVAL;
4994 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004995
4996 *pNumChannels = tempInt;
4997
4998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4999 "Number of channels are: %d", *pNumChannels);
5000
5001 for (j = 0; j < (*pNumChannels); j++)
5002 {
5003 /*inPtr pointing to the beginning of first space after number of channels*/
5004 inPtr = strpbrk( inPtr, " " );
5005 /*no channel list after the number of channels argument*/
5006 if (NULL == inPtr)
5007 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005008 if (0 != j)
5009 {
5010 *pNumChannels = j;
5011 return VOS_STATUS_SUCCESS;
5012 }
5013 else
5014 {
5015 return -EINVAL;
5016 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005017 }
5018
5019 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005020 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005021
5022 /*no channel list after the number of channels argument and spaces*/
5023 if ( '\0' == *inPtr )
5024 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005025 if (0 != j)
5026 {
5027 *pNumChannels = j;
5028 return VOS_STATUS_SUCCESS;
5029 }
5030 else
5031 {
5032 return -EINVAL;
5033 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005034 }
5035
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005036 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005037 if (1 != v) return -EINVAL;
5038
Srinivas Girigowdade697412013-02-14 16:31:48 -08005039 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005040 if ((v < 0) ||
5041 (tempInt <= 0) ||
5042 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5043 {
5044 return -EINVAL;
5045 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005046 pChannelList[j] = tempInt;
5047
5048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5049 "Channel %d added to preferred channel list",
5050 pChannelList[j] );
5051 }
5052
Srinivas Girigowdade697412013-02-14 16:31:48 -08005053 return VOS_STATUS_SUCCESS;
5054}
5055
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005056
5057/**---------------------------------------------------------------------------
5058
5059 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5060
5061 This function parses the reasoc command data passed in the format
5062 REASSOC<space><bssid><space><channel>
5063
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005064 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005065 \param - pTargetApBssid Pointer to target Ap bssid
5066 \param - pChannel Pointer to the Target AP channel
5067
5068 \return - 0 for success non-zero for failure
5069
5070 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005071VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5072 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005073{
5074 tANI_U8 *inPtr = pValue;
5075 int tempInt;
5076 int v = 0;
5077 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005078 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005079 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005080
5081 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5082 /*no argument after the command*/
5083 if (NULL == inPtr)
5084 {
5085 return -EINVAL;
5086 }
5087
5088 /*no space after the command*/
5089 else if (SPACE_ASCII_VALUE != *inPtr)
5090 {
5091 return -EINVAL;
5092 }
5093
5094 /*removing empty spaces*/
5095 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5096
5097 /*no argument followed by spaces*/
5098 if ('\0' == *inPtr)
5099 {
5100 return -EINVAL;
5101 }
5102
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005103 v = sscanf(inPtr, "%17s", macAddress);
5104 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005105 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5107 "Invalid MAC address or All hex inputs are not read (%d)", v);
5108 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005109 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005110
5111 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5112 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5113 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5114 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5115 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5116 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005117
5118 /* point to the next argument */
5119 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5120 /*no argument after the command*/
5121 if (NULL == inPtr) return -EINVAL;
5122
5123 /*removing empty spaces*/
5124 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5125
5126 /*no argument followed by spaces*/
5127 if ('\0' == *inPtr)
5128 {
5129 return -EINVAL;
5130 }
5131
5132 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005133 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005134 if (1 != v) return -EINVAL;
5135
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005136 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005137 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305138 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005139 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5140 {
5141 return -EINVAL;
5142 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005143
5144 *pChannel = tempInt;
5145 return VOS_STATUS_SUCCESS;
5146}
5147
5148#endif
5149
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005150#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005151/**---------------------------------------------------------------------------
5152
5153 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5154
5155 This function parses the SETCCKM IE command
5156 SETCCKMIE<space><ie data>
5157
5158 \param - pValue Pointer to input data
5159 \param - pCckmIe Pointer to output cckm Ie
5160 \param - pCckmIeLen Pointer to output cckm ie length
5161
5162 \return - 0 for success non-zero for failure
5163
5164 --------------------------------------------------------------------------*/
5165VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5166 tANI_U8 *pCckmIeLen)
5167{
5168 tANI_U8 *inPtr = pValue;
5169 tANI_U8 *dataEnd;
5170 int j = 0;
5171 int i = 0;
5172 tANI_U8 tempByte = 0;
5173
5174 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5175 /*no argument after the command*/
5176 if (NULL == inPtr)
5177 {
5178 return -EINVAL;
5179 }
5180
5181 /*no space after the command*/
5182 else if (SPACE_ASCII_VALUE != *inPtr)
5183 {
5184 return -EINVAL;
5185 }
5186
5187 /*removing empty spaces*/
5188 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5189
5190 /*no argument followed by spaces*/
5191 if ('\0' == *inPtr)
5192 {
5193 return -EINVAL;
5194 }
5195
5196 /* find the length of data */
5197 dataEnd = inPtr;
5198 while(('\0' != *dataEnd) )
5199 {
5200 dataEnd++;
5201 ++(*pCckmIeLen);
5202 }
5203 if ( *pCckmIeLen <= 0) return -EINVAL;
5204
5205 /* Allocate the number of bytes based on the number of input characters
5206 whether it is even or odd.
5207 if the number of input characters are even, then we need N/2 byte.
5208 if the number of input characters are odd, then we need do (N+1)/2 to
5209 compensate rounding off.
5210 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5211 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5212 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5213 if (NULL == *pCckmIe)
5214 {
5215 hddLog(VOS_TRACE_LEVEL_FATAL,
5216 "%s: vos_mem_alloc failed ", __func__);
5217 return -EINVAL;
5218 }
5219 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5220 /* the buffer received from the upper layer is character buffer,
5221 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5222 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5223 and f0 in 3rd location */
5224 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5225 {
5226 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5227 (*pCckmIe)[i++] = tempByte;
5228 }
5229 *pCckmIeLen = i;
5230
5231 return VOS_STATUS_SUCCESS;
5232}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005233#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005234
Jeff Johnson295189b2012-06-20 16:38:30 -07005235/**---------------------------------------------------------------------------
5236
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005237 \brief hdd_is_valid_mac_address() - Validate MAC address
5238
5239 This function validates whether the given MAC address is valid or not
5240 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5241 where X is the hexa decimal digit character and separated by ':'
5242 This algorithm works even if MAC address is not separated by ':'
5243
5244 This code checks given input string mac contains exactly 12 hexadecimal digits.
5245 and a separator colon : appears in the input string only after
5246 an even number of hex digits.
5247
5248 \param - pMacAddr pointer to the input MAC address
5249 \return - 1 for valid and 0 for invalid
5250
5251 --------------------------------------------------------------------------*/
5252
5253v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5254{
5255 int xdigit = 0;
5256 int separator = 0;
5257 while (*pMacAddr)
5258 {
5259 if (isxdigit(*pMacAddr))
5260 {
5261 xdigit++;
5262 }
5263 else if (':' == *pMacAddr)
5264 {
5265 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5266 break;
5267
5268 ++separator;
5269 }
5270 else
5271 {
5272 separator = -1;
5273 /* Invalid MAC found */
5274 return 0;
5275 }
5276 ++pMacAddr;
5277 }
5278 return (xdigit == 12 && (separator == 5 || separator == 0));
5279}
5280
5281/**---------------------------------------------------------------------------
5282
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305283 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005284
5285 \param - dev Pointer to net_device structure
5286
5287 \return - 0 for success non-zero for failure
5288
5289 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305290int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005291{
5292 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5293 hdd_context_t *pHddCtx;
5294 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5295 VOS_STATUS status;
5296 v_BOOL_t in_standby = TRUE;
5297
5298 if (NULL == pAdapter)
5299 {
5300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305301 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005302 return -ENODEV;
5303 }
5304
5305 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305306 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5307 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005308 if (NULL == pHddCtx)
5309 {
5310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005311 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005312 return -ENODEV;
5313 }
5314
5315 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5316 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5317 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005318 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5319 {
5320 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305321 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005322 in_standby = FALSE;
5323 break;
5324 }
5325 else
5326 {
5327 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5328 pAdapterNode = pNext;
5329 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005330 }
5331
5332 if (TRUE == in_standby)
5333 {
5334 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5335 {
5336 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5337 "wlan out of power save", __func__);
5338 return -EINVAL;
5339 }
5340 }
5341
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005342 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005343 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5344 {
5345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005346 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005347 /* Enable TX queues only when we are connected */
5348 netif_tx_start_all_queues(dev);
5349 }
5350
5351 return 0;
5352}
5353
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305354/**---------------------------------------------------------------------------
5355
5356 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5357
5358 This is called in response to ifconfig up
5359
5360 \param - dev Pointer to net_device structure
5361
5362 \return - 0 for success non-zero for failure
5363
5364 --------------------------------------------------------------------------*/
5365int hdd_open(struct net_device *dev)
5366{
5367 int ret;
5368
5369 vos_ssr_protect(__func__);
5370 ret = __hdd_open(dev);
5371 vos_ssr_unprotect(__func__);
5372
5373 return ret;
5374}
5375
Jeff Johnson295189b2012-06-20 16:38:30 -07005376int hdd_mon_open (struct net_device *dev)
5377{
5378 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5379
5380 if(pAdapter == NULL) {
5381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005382 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005383 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005384 }
5385
5386 netif_start_queue(dev);
5387
5388 return 0;
5389}
5390/**---------------------------------------------------------------------------
5391
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305392 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005393
5394 \param - dev Pointer to net_device structure
5395
5396 \return - 0 for success non-zero for failure
5397
5398 --------------------------------------------------------------------------*/
5399
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305400int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005401{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305402 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005403 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5404 hdd_context_t *pHddCtx;
5405 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5406 VOS_STATUS status;
5407 v_BOOL_t enter_standby = TRUE;
5408
5409 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005410 if (NULL == pAdapter)
5411 {
5412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305413 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005414 return -ENODEV;
5415 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305416 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5417 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305418
5419 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5420 ret = wlan_hdd_validate_context(pHddCtx);
5421 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005422 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5424 "%s: HDD context is not valid!", __func__);
5425 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005426 }
5427
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305428 /* Nothing to be done if the interface is not opened */
5429 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5430 {
5431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5432 "%s: NETDEV Interface is not OPENED", __func__);
5433 return -ENODEV;
5434 }
5435
5436 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005437 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305439
5440 /* Disable TX on the interface, after this hard_start_xmit() will not
5441 * be called on that interface
5442 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005443 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305444
5445 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005446 netif_carrier_off(pAdapter->dev);
5447
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305448 /* The interface is marked as down for outside world (aka kernel)
5449 * But the driver is pretty much alive inside. The driver needs to
5450 * tear down the existing connection on the netdev (session)
5451 * cleanup the data pipes and wait until the control plane is stabilized
5452 * for this interface. The call also needs to wait until the above
5453 * mentioned actions are completed before returning to the caller.
5454 * Notice that the hdd_stop_adapter is requested not to close the session
5455 * That is intentional to be able to scan if it is a STA/P2P interface
5456 */
5457 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07005458
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305459 /* DeInit the adapter. This ensures datapath cleanup as well */
5460 hdd_deinit_adapter(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 /* SoftAP ifaces should never go in power save mode
5462 making sure same here. */
5463 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5464 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005465 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 )
5467 {
5468 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5470 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005471 EXIT();
5472 return 0;
5473 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305474 /* Find if any iface is up. If any iface is up then can't put device to
5475 * sleep/power save mode
5476 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5478 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5479 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005480 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5481 {
5482 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305483 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005484 enter_standby = FALSE;
5485 break;
5486 }
5487 else
5488 {
5489 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5490 pAdapterNode = pNext;
5491 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005492 }
5493
5494 if (TRUE == enter_standby)
5495 {
5496 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5497 "entering standby", __func__);
5498 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5499 {
5500 /*log and return success*/
5501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5502 "wlan in power save", __func__);
5503 }
5504 }
5505
5506 EXIT();
5507 return 0;
5508}
5509
5510/**---------------------------------------------------------------------------
5511
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305512 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005513
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305514 This is called in response to ifconfig down
5515
5516 \param - dev Pointer to net_device structure
5517
5518 \return - 0 for success non-zero for failure
5519-----------------------------------------------------------------------------*/
5520int hdd_stop (struct net_device *dev)
5521{
5522 int ret;
5523
5524 vos_ssr_protect(__func__);
5525 ret = __hdd_stop(dev);
5526 vos_ssr_unprotect(__func__);
5527
5528 return ret;
5529}
5530
5531/**---------------------------------------------------------------------------
5532
5533 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005534
5535 \param - dev Pointer to net_device structure
5536
5537 \return - void
5538
5539 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305540static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005541{
5542 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5543
5544 ENTER();
5545
5546 do
5547 {
5548 if (NULL == pAdapter)
5549 {
5550 hddLog(VOS_TRACE_LEVEL_FATAL,
5551 "%s: NULL pAdapter", __func__);
5552 break;
5553 }
5554
5555 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5556 {
5557 hddLog(VOS_TRACE_LEVEL_FATAL,
5558 "%s: Invalid magic", __func__);
5559 break;
5560 }
5561
5562 if (NULL == pAdapter->pHddCtx)
5563 {
5564 hddLog(VOS_TRACE_LEVEL_FATAL,
5565 "%s: NULL pHddCtx", __func__);
5566 break;
5567 }
5568
5569 if (dev != pAdapter->dev)
5570 {
5571 hddLog(VOS_TRACE_LEVEL_FATAL,
5572 "%s: Invalid device reference", __func__);
5573 /* we haven't validated all cases so let this go for now */
5574 }
5575
5576 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5577
5578 /* after uninit our adapter structure will no longer be valid */
5579 pAdapter->dev = NULL;
5580 pAdapter->magic = 0;
5581 } while (0);
5582
5583 EXIT();
5584}
5585
5586/**---------------------------------------------------------------------------
5587
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305588 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5589
5590 This is called during the netdev unregister to uninitialize all data
5591associated with the device
5592
5593 \param - dev Pointer to net_device structure
5594
5595 \return - void
5596
5597 --------------------------------------------------------------------------*/
5598static void hdd_uninit (struct net_device *dev)
5599{
5600 vos_ssr_protect(__func__);
5601 __hdd_uninit(dev);
5602 vos_ssr_unprotect(__func__);
5603}
5604
5605/**---------------------------------------------------------------------------
5606
Jeff Johnson295189b2012-06-20 16:38:30 -07005607 \brief hdd_release_firmware() -
5608
5609 This function calls the release firmware API to free the firmware buffer.
5610
5611 \param - pFileName Pointer to the File Name.
5612 pCtx - Pointer to the adapter .
5613
5614
5615 \return - 0 for success, non zero for failure
5616
5617 --------------------------------------------------------------------------*/
5618
5619VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5620{
5621 VOS_STATUS status = VOS_STATUS_SUCCESS;
5622 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5623 ENTER();
5624
5625
5626 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5627
5628 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5629
5630 if(pHddCtx->fw) {
5631 release_firmware(pHddCtx->fw);
5632 pHddCtx->fw = NULL;
5633 }
5634 else
5635 status = VOS_STATUS_E_FAILURE;
5636 }
5637 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5638 if(pHddCtx->nv) {
5639 release_firmware(pHddCtx->nv);
5640 pHddCtx->nv = NULL;
5641 }
5642 else
5643 status = VOS_STATUS_E_FAILURE;
5644
5645 }
5646
5647 EXIT();
5648 return status;
5649}
5650
5651/**---------------------------------------------------------------------------
5652
5653 \brief hdd_request_firmware() -
5654
5655 This function reads the firmware file using the request firmware
5656 API and returns the the firmware data and the firmware file size.
5657
5658 \param - pfileName - Pointer to the file name.
5659 - pCtx - Pointer to the adapter .
5660 - ppfw_data - Pointer to the pointer of the firmware data.
5661 - pSize - Pointer to the file size.
5662
5663 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5664
5665 --------------------------------------------------------------------------*/
5666
5667
5668VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5669{
5670 int status;
5671 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5672 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5673 ENTER();
5674
5675 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5676
5677 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5678
5679 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5680 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5681 __func__, pfileName);
5682 retval = VOS_STATUS_E_FAILURE;
5683 }
5684
5685 else {
5686 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5687 *pSize = pHddCtx->fw->size;
5688 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5689 __func__, *pSize);
5690 }
5691 }
5692 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5693
5694 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5695
5696 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5697 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5698 __func__, pfileName);
5699 retval = VOS_STATUS_E_FAILURE;
5700 }
5701
5702 else {
5703 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5704 *pSize = pHddCtx->nv->size;
5705 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5706 __func__, *pSize);
5707 }
5708 }
5709
5710 EXIT();
5711 return retval;
5712}
5713/**---------------------------------------------------------------------------
5714 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5715
5716 This is the function invoked by SME to inform the result of a full power
5717 request issued by HDD
5718
5719 \param - callbackcontext - Pointer to cookie
5720 status - result of request
5721
5722 \return - None
5723
5724--------------------------------------------------------------------------*/
5725void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5726{
5727 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5728
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005729 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 if(&pHddCtx->full_pwr_comp_var)
5731 {
5732 complete(&pHddCtx->full_pwr_comp_var);
5733 }
5734}
5735
5736/**---------------------------------------------------------------------------
5737
5738 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5739
5740 This is the function invoked by SME to inform the result of BMPS
5741 request issued by HDD
5742
5743 \param - callbackcontext - Pointer to cookie
5744 status - result of request
5745
5746 \return - None
5747
5748--------------------------------------------------------------------------*/
5749void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5750{
5751
5752 struct completion *completion_var = (struct completion*) callbackContext;
5753
Arif Hussain6d2a3322013-11-17 19:50:10 -08005754 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005755 if(completion_var != NULL)
5756 {
5757 complete(completion_var);
5758 }
5759}
5760
5761/**---------------------------------------------------------------------------
5762
5763 \brief hdd_get_cfg_file_size() -
5764
5765 This function reads the configuration file using the request firmware
5766 API and returns the configuration file size.
5767
5768 \param - pCtx - Pointer to the adapter .
5769 - pFileName - Pointer to the file name.
5770 - pBufSize - Pointer to the buffer size.
5771
5772 \return - 0 for success, non zero for failure
5773
5774 --------------------------------------------------------------------------*/
5775
5776VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5777{
5778 int status;
5779 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5780
5781 ENTER();
5782
5783 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5784
5785 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5786 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5787 status = VOS_STATUS_E_FAILURE;
5788 }
5789 else {
5790 *pBufSize = pHddCtx->fw->size;
5791 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5792 release_firmware(pHddCtx->fw);
5793 pHddCtx->fw = NULL;
5794 }
5795
5796 EXIT();
5797 return VOS_STATUS_SUCCESS;
5798}
5799
5800/**---------------------------------------------------------------------------
5801
5802 \brief hdd_read_cfg_file() -
5803
5804 This function reads the configuration file using the request firmware
5805 API and returns the cfg data and the buffer size of the configuration file.
5806
5807 \param - pCtx - Pointer to the adapter .
5808 - pFileName - Pointer to the file name.
5809 - pBuffer - Pointer to the data buffer.
5810 - pBufSize - Pointer to the buffer size.
5811
5812 \return - 0 for success, non zero for failure
5813
5814 --------------------------------------------------------------------------*/
5815
5816VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5817 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5818{
5819 int status;
5820 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5821
5822 ENTER();
5823
5824 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5825
5826 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5827 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5828 return VOS_STATUS_E_FAILURE;
5829 }
5830 else {
5831 if(*pBufSize != pHddCtx->fw->size) {
5832 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5833 "file size", __func__);
5834 release_firmware(pHddCtx->fw);
5835 pHddCtx->fw = NULL;
5836 return VOS_STATUS_E_FAILURE;
5837 }
5838 else {
5839 if(pBuffer) {
5840 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5841 }
5842 release_firmware(pHddCtx->fw);
5843 pHddCtx->fw = NULL;
5844 }
5845 }
5846
5847 EXIT();
5848
5849 return VOS_STATUS_SUCCESS;
5850}
5851
5852/**---------------------------------------------------------------------------
5853
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305854 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005855
5856 This function sets the user specified mac address using
5857 the command ifconfig wlanX hw ether <mac adress>.
5858
5859 \param - dev - Pointer to the net device.
5860 - addr - Pointer to the sockaddr.
5861 \return - 0 for success, non zero for failure
5862
5863 --------------------------------------------------------------------------*/
5864
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305865static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005866{
5867 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5868 struct sockaddr *psta_mac_addr = addr;
5869 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5870
5871 ENTER();
5872
5873 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5875
5876 EXIT();
5877 return halStatus;
5878}
5879
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305880/**---------------------------------------------------------------------------
5881
5882 \brief hdd_set_mac_address() -
5883
5884 Wrapper function to protect __hdd_set_mac_address() function from ssr
5885
5886 \param - dev - Pointer to the net device.
5887 - addr - Pointer to the sockaddr.
5888 \return - 0 for success, non zero for failure
5889
5890 --------------------------------------------------------------------------*/
5891static int hdd_set_mac_address(struct net_device *dev, void *addr)
5892{
5893 int ret;
5894
5895 vos_ssr_protect(__func__);
5896 ret = __hdd_set_mac_address(dev, addr);
5897 vos_ssr_unprotect(__func__);
5898
5899 return ret;
5900}
5901
Jeff Johnson295189b2012-06-20 16:38:30 -07005902tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5903{
5904 int i;
5905 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5906 {
Abhishek Singheb183782014-02-06 13:37:21 +05305907 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 break;
5909 }
5910
5911 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5912 return NULL;
5913
5914 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5915 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5916}
5917
5918void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5919{
5920 int i;
5921 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5922 {
5923 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5924 {
5925 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5926 break;
5927 }
5928 }
5929 return;
5930}
5931
5932#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5933 static struct net_device_ops wlan_drv_ops = {
5934 .ndo_open = hdd_open,
5935 .ndo_stop = hdd_stop,
5936 .ndo_uninit = hdd_uninit,
5937 .ndo_start_xmit = hdd_hard_start_xmit,
5938 .ndo_tx_timeout = hdd_tx_timeout,
5939 .ndo_get_stats = hdd_stats,
5940 .ndo_do_ioctl = hdd_ioctl,
5941 .ndo_set_mac_address = hdd_set_mac_address,
5942 .ndo_select_queue = hdd_select_queue,
5943#ifdef WLAN_FEATURE_PACKET_FILTERING
5944#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5945 .ndo_set_rx_mode = hdd_set_multicast_list,
5946#else
5947 .ndo_set_multicast_list = hdd_set_multicast_list,
5948#endif //LINUX_VERSION_CODE
5949#endif
5950 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005951 static struct net_device_ops wlan_mon_drv_ops = {
5952 .ndo_open = hdd_mon_open,
5953 .ndo_stop = hdd_stop,
5954 .ndo_uninit = hdd_uninit,
5955 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5956 .ndo_tx_timeout = hdd_tx_timeout,
5957 .ndo_get_stats = hdd_stats,
5958 .ndo_do_ioctl = hdd_ioctl,
5959 .ndo_set_mac_address = hdd_set_mac_address,
5960 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005961
5962#endif
5963
5964void hdd_set_station_ops( struct net_device *pWlanDev )
5965{
5966#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005967 pWlanDev->netdev_ops = &wlan_drv_ops;
5968#else
5969 pWlanDev->open = hdd_open;
5970 pWlanDev->stop = hdd_stop;
5971 pWlanDev->uninit = hdd_uninit;
5972 pWlanDev->hard_start_xmit = NULL;
5973 pWlanDev->tx_timeout = hdd_tx_timeout;
5974 pWlanDev->get_stats = hdd_stats;
5975 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 pWlanDev->set_mac_address = hdd_set_mac_address;
5977#endif
5978}
5979
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005980static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005981{
5982 struct net_device *pWlanDev = NULL;
5983 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 /*
5985 * cfg80211 initialization and registration....
5986 */
5987 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5988
Jeff Johnson295189b2012-06-20 16:38:30 -07005989 if(pWlanDev != NULL)
5990 {
5991
5992 //Save the pointer to the net_device in the HDD adapter
5993 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5994
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5996
5997 pAdapter->dev = pWlanDev;
5998 pAdapter->pHddCtx = pHddCtx;
5999 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306000 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006001
6002 init_completion(&pAdapter->session_open_comp_var);
6003 init_completion(&pAdapter->session_close_comp_var);
6004 init_completion(&pAdapter->disconnect_comp_var);
6005 init_completion(&pAdapter->linkup_event_var);
6006 init_completion(&pAdapter->cancel_rem_on_chan_var);
6007 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306008 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6010 init_completion(&pAdapter->offchannel_tx_event);
6011#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006013#ifdef FEATURE_WLAN_TDLS
6014 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006015 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006016 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306017 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006018#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006019 init_completion(&pHddCtx->mc_sus_event_var);
6020 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306021 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006022 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006023 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006024
Rajeev79dbe4c2013-10-05 11:03:42 +05306025#ifdef FEATURE_WLAN_BATCH_SCAN
6026 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6027 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6028 pAdapter->pBatchScanRsp = NULL;
6029 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006030 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006031 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306032 mutex_init(&pAdapter->hdd_batch_scan_lock);
6033#endif
6034
Jeff Johnson295189b2012-06-20 16:38:30 -07006035 pAdapter->isLinkUpSvcNeeded = FALSE;
6036 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6037 //Init the net_device structure
6038 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6039
6040 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6041 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6042 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6043 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6044
6045 hdd_set_station_ops( pAdapter->dev );
6046
6047 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006048 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6049 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6050 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 /* set pWlanDev's parent to underlying device */
6052 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006053
6054 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006055 }
6056
6057 return pAdapter;
6058}
6059
6060VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6061{
6062 struct net_device *pWlanDev = pAdapter->dev;
6063 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6064 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6065 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6066
6067 if( rtnl_lock_held )
6068 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006069 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006070 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6071 {
6072 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6073 return VOS_STATUS_E_FAILURE;
6074 }
6075 }
6076 if (register_netdevice(pWlanDev))
6077 {
6078 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6079 return VOS_STATUS_E_FAILURE;
6080 }
6081 }
6082 else
6083 {
6084 if(register_netdev(pWlanDev))
6085 {
6086 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6087 return VOS_STATUS_E_FAILURE;
6088 }
6089 }
6090 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6091
6092 return VOS_STATUS_SUCCESS;
6093}
6094
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006095static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006096{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006097 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006098
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006099 if (NULL == pAdapter)
6100 {
6101 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6102 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006103 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006104
6105 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6106 {
6107 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6108 return eHAL_STATUS_NOT_INITIALIZED;
6109 }
6110
6111 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6112
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006113#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006114 /* need to make sure all of our scheduled work has completed.
6115 * This callback is called from MC thread context, so it is safe to
6116 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006117 *
6118 * Even though this is called from MC thread context, if there is a faulty
6119 * work item in the system, that can hang this call forever. So flushing
6120 * this global work queue is not safe; and now we make sure that
6121 * individual work queues are stopped correctly. But the cancel work queue
6122 * is a GPL only API, so the proprietary version of the driver would still
6123 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006124 */
6125 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006126#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006127
6128 /* We can be blocked while waiting for scheduled work to be
6129 * flushed, and the adapter structure can potentially be freed, in
6130 * which case the magic will have been reset. So make sure the
6131 * magic is still good, and hence the adapter structure is still
6132 * valid, before signaling completion */
6133 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6134 {
6135 complete(&pAdapter->session_close_comp_var);
6136 }
6137
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 return eHAL_STATUS_SUCCESS;
6139}
6140
6141VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6142{
6143 struct net_device *pWlanDev = pAdapter->dev;
6144 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6145 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6146 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6147 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306148 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006149
6150 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006151 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 //Open a SME session for future operation
6153 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006154 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006155 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6156 {
6157 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006158 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006159 halStatus, halStatus );
6160 status = VOS_STATUS_E_FAILURE;
6161 goto error_sme_open;
6162 }
6163
6164 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306165 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006166 &pAdapter->session_open_comp_var,
6167 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306168 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006169 {
6170 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306171 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006172 status = VOS_STATUS_E_FAILURE;
6173 goto error_sme_open;
6174 }
6175
6176 // Register wireless extensions
6177 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6178 {
6179 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006180 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006181 halStatus, halStatus );
6182 status = VOS_STATUS_E_FAILURE;
6183 goto error_register_wext;
6184 }
6185 //Safe to register the hard_start_xmit function again
6186#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6187 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6188#else
6189 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6190#endif
6191
6192 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306193 hddLog(VOS_TRACE_LEVEL_INFO,
6194 "%s: Set HDD connState to eConnectionState_NotConnected",
6195 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006196 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6197
6198 //Set the default operation channel
6199 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6200
6201 /* Make the default Auth Type as OPEN*/
6202 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6203
6204 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6205 {
6206 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006207 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006208 status, status );
6209 goto error_init_txrx;
6210 }
6211
6212 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6213
6214 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6215 {
6216 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006217 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006218 status, status );
6219 goto error_wmm_init;
6220 }
6221
6222 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6223
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006224#ifdef FEATURE_WLAN_TDLS
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306225 if(0 != wlan_hdd_sta_tdls_init(pAdapter))
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006226 {
6227 status = VOS_STATUS_E_FAILURE;
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306228 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006229 goto error_tdls_init;
6230 }
6231 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
6232#endif
6233
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 return VOS_STATUS_SUCCESS;
6235
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006236#ifdef FEATURE_WLAN_TDLS
6237error_tdls_init:
6238 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6239 hdd_wmm_adapter_close(pAdapter);
6240#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006241error_wmm_init:
6242 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6243 hdd_deinit_tx_rx(pAdapter);
6244error_init_txrx:
6245 hdd_UnregisterWext(pWlanDev);
6246error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006247 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 {
6249 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006250 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006252 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306254 unsigned long rc;
6255
Jeff Johnson295189b2012-06-20 16:38:30 -07006256 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306257 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006259 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306260 if (rc <= 0)
6261 hddLog(VOS_TRACE_LEVEL_ERROR,
6262 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006263 }
6264}
6265error_sme_open:
6266 return status;
6267}
6268
Jeff Johnson295189b2012-06-20 16:38:30 -07006269void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6270{
6271 hdd_cfg80211_state_t *cfgState;
6272
6273 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6274
6275 if( NULL != cfgState->buf )
6276 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306277 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6279 rc = wait_for_completion_interruptible_timeout(
6280 &pAdapter->tx_action_cnf_event,
6281 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306282 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006284 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306285 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6286 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006287 }
6288 }
6289 return;
6290}
Jeff Johnson295189b2012-06-20 16:38:30 -07006291
6292void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6293{
6294 ENTER();
6295 switch ( pAdapter->device_mode )
6296 {
6297 case WLAN_HDD_INFRA_STATION:
6298 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006299 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 {
6301 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6302 {
6303 hdd_deinit_tx_rx( pAdapter );
6304 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6305 }
6306
6307 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6308 {
6309 hdd_wmm_adapter_close( pAdapter );
6310 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6311 }
6312
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006314#ifdef FEATURE_WLAN_TDLS
6315 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
6316 {
6317 wlan_hdd_tdls_exit(pAdapter);
6318 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
6319 }
6320#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006321
6322 break;
6323 }
6324
6325 case WLAN_HDD_SOFTAP:
6326 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306328
6329 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6330 {
6331 hdd_wmm_adapter_close( pAdapter );
6332 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6333 }
6334
Jeff Johnson295189b2012-06-20 16:38:30 -07006335 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006336
6337 hdd_unregister_hostapd(pAdapter);
6338 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006339 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 break;
6341 }
6342
6343 case WLAN_HDD_MONITOR:
6344 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6347 {
6348 hdd_deinit_tx_rx( pAdapter );
6349 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 if(NULL != pAdapterforTx)
6352 {
6353 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6354 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 break;
6356 }
6357
6358
6359 default:
6360 break;
6361 }
6362
6363 EXIT();
6364}
6365
6366void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6367{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006368 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306369
6370 ENTER();
6371 if (NULL == pAdapter)
6372 {
6373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6374 "%s: HDD adapter is Null", __func__);
6375 return;
6376 }
6377
6378 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006379
Rajeev79dbe4c2013-10-05 11:03:42 +05306380#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306381 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6382 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006383 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306384 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6385 )
6386 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006387 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306388 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006389 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6390 {
6391 hdd_deinit_batch_scan(pAdapter);
6392 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306393 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006394 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306395#endif
6396
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6398 if( rtnl_held )
6399 {
6400 unregister_netdevice(pWlanDev);
6401 }
6402 else
6403 {
6404 unregister_netdev(pWlanDev);
6405 }
6406 // note that the pAdapter is no longer valid at this point
6407 // since the memory has been reclaimed
6408 }
6409
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306410 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006411}
6412
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006413void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6414{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306415 VOS_STATUS status;
6416 hdd_adapter_t *pAdapter = NULL;
6417 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006418
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306419 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006420
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306421 /*loop through all adapters.*/
6422 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006423 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306424 pAdapter = pAdapterNode->pAdapter;
6425 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6426 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006427
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306428 { // we skip this registration for modes other than STA and P2P client modes.
6429 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6430 pAdapterNode = pNext;
6431 continue;
6432 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006433
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306434 //Apply Dynamic DTIM For P2P
6435 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6436 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6437 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6438 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6439 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6440 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6441 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6442 (eConnectionState_Associated ==
6443 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6444 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6445 {
6446 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006447
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306448 powerRequest.uIgnoreDTIM = 1;
6449 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6450
6451 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6452 {
6453 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6454 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6455 }
6456 else
6457 {
6458 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6459 }
6460
6461 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6462 * specified during Enter/Exit BMPS when LCD off*/
6463 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6464 NULL, eANI_BOOLEAN_FALSE);
6465 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6466 NULL, eANI_BOOLEAN_FALSE);
6467
6468 /* switch to the DTIM specified in cfg.ini */
6469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6470 "Switch to DTIM %d", powerRequest.uListenInterval);
6471 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6472 break;
6473
6474 }
6475
6476 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6477 pAdapterNode = pNext;
6478 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006479}
6480
6481void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6482{
6483 /*Switch back to DTIM 1*/
6484 tSirSetPowerParamsReq powerRequest = { 0 };
6485
6486 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6487 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006488 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006489
6490 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6491 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6492 NULL, eANI_BOOLEAN_FALSE);
6493 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6494 NULL, eANI_BOOLEAN_FALSE);
6495
6496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6497 "Switch to DTIM%d",powerRequest.uListenInterval);
6498 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6499
6500}
6501
Jeff Johnson295189b2012-06-20 16:38:30 -07006502VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6503{
6504 VOS_STATUS status = VOS_STATUS_SUCCESS;
6505
6506 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6507 {
6508 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6509 }
6510
6511 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6512 {
6513 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6514 }
6515
6516 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6517 {
6518 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6519 }
6520
6521 return status;
6522}
6523
6524VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6525{
6526 hdd_adapter_t *pAdapter = NULL;
6527 eHalStatus halStatus;
6528 VOS_STATUS status = VOS_STATUS_E_INVAL;
6529 v_BOOL_t disableBmps = FALSE;
6530 v_BOOL_t disableImps = FALSE;
6531
6532 switch(session_type)
6533 {
6534 case WLAN_HDD_INFRA_STATION:
6535 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006536 case WLAN_HDD_P2P_CLIENT:
6537 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 //Exit BMPS -> Is Sta/P2P Client is already connected
6539 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6540 if((NULL != pAdapter)&&
6541 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6542 {
6543 disableBmps = TRUE;
6544 }
6545
6546 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6547 if((NULL != pAdapter)&&
6548 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6549 {
6550 disableBmps = TRUE;
6551 }
6552
6553 //Exit both Bmps and Imps incase of Go/SAP Mode
6554 if((WLAN_HDD_SOFTAP == session_type) ||
6555 (WLAN_HDD_P2P_GO == session_type))
6556 {
6557 disableBmps = TRUE;
6558 disableImps = TRUE;
6559 }
6560
6561 if(TRUE == disableImps)
6562 {
6563 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6564 {
6565 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6566 }
6567 }
6568
6569 if(TRUE == disableBmps)
6570 {
6571 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6572 {
6573 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6574
6575 if(eHAL_STATUS_SUCCESS != halStatus)
6576 {
6577 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006578 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006579 VOS_ASSERT(0);
6580 return status;
6581 }
6582 }
6583
6584 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6585 {
6586 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6587
6588 if(eHAL_STATUS_SUCCESS != halStatus)
6589 {
6590 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006591 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 VOS_ASSERT(0);
6593 return status;
6594 }
6595 }
6596 }
6597
6598 if((TRUE == disableBmps) ||
6599 (TRUE == disableImps))
6600 {
6601 /* Now, get the chip into Full Power now */
6602 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6603 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6604 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6605
6606 if(halStatus != eHAL_STATUS_SUCCESS)
6607 {
6608 if(halStatus == eHAL_STATUS_PMC_PENDING)
6609 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306610 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306612 ret = wait_for_completion_interruptible_timeout(
6613 &pHddCtx->full_pwr_comp_var,
6614 msecs_to_jiffies(1000));
6615 if (ret <= 0)
6616 {
6617 hddLog(VOS_TRACE_LEVEL_ERROR,
6618 "%s: wait on full_pwr_comp_var failed %ld",
6619 __func__, ret);
6620 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 }
6622 else
6623 {
6624 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006625 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 VOS_ASSERT(0);
6627 return status;
6628 }
6629 }
6630
6631 status = VOS_STATUS_SUCCESS;
6632 }
6633
6634 break;
6635 }
6636 return status;
6637}
6638
6639hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006640 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006641 tANI_U8 rtnl_held )
6642{
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05306643 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006644 hdd_adapter_t *pAdapter = NULL;
6645 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6646 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6647 VOS_STATUS exitbmpsStatus;
6648
Arif Hussain6d2a3322013-11-17 19:50:10 -08006649 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006650
Nirav Shah436658f2014-02-28 17:05:45 +05306651 if(macAddr == NULL)
6652 {
6653 /* Not received valid macAddr */
6654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6655 "%s:Unable to add virtual intf: Not able to get"
6656 "valid mac address",__func__);
6657 return NULL;
6658 }
6659
Jeff Johnson295189b2012-06-20 16:38:30 -07006660 //Disable BMPS incase of Concurrency
6661 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6662
6663 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6664 {
6665 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306666 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 VOS_ASSERT(0);
6668 return NULL;
6669 }
6670
6671 switch(session_type)
6672 {
6673 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006674 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006675 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006676 {
6677 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6678
6679 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306680 {
6681 hddLog(VOS_TRACE_LEVEL_FATAL,
6682 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306684 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006685
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306686#ifdef FEATURE_WLAN_TDLS
6687 /* A Mutex Lock is introduced while changing/initializing the mode to
6688 * protect the concurrent access for the Adapters by TDLS module.
6689 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306690 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306691#endif
6692
Jeff Johnsone7245742012-09-05 17:12:55 -07006693 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6694 NL80211_IFTYPE_P2P_CLIENT:
6695 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006696
Jeff Johnson295189b2012-06-20 16:38:30 -07006697 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306698#ifdef FEATURE_WLAN_TDLS
6699 mutex_unlock(&pHddCtx->tdls_lock);
6700#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306701
6702 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006703 if( VOS_STATUS_SUCCESS != status )
6704 goto err_free_netdev;
6705
6706 status = hdd_register_interface( pAdapter, rtnl_held );
6707 if( VOS_STATUS_SUCCESS != status )
6708 {
6709 hdd_deinit_adapter(pHddCtx, pAdapter);
6710 goto err_free_netdev;
6711 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306712
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306713 // Workqueue which gets scheduled in IPv4 notification callback.
6714 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05306715 // Register IPv4 notifier to notify if any change in IP
6716 // So that we can reconfigure the offload parameters
6717 pAdapter->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
6718 ret = register_inetaddr_notifier(&pAdapter->ipv4_notifier);
6719 if (ret)
6720 {
6721 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
6722 }
6723 else
6724 {
6725 hddLog(LOG1, FL("Registered IPv4 notifier"));
6726 pAdapter->ipv4_notifier_registered = true;
6727 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306728
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306729#ifdef WLAN_NS_OFFLOAD
6730 // Workqueue which gets scheduled in IPv6 notification callback.
6731 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05306732 // Register IPv6 notifier to notify if any change in IP
6733 // So that we can reconfigure the offload parameters
6734 pAdapter->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
6735 ret = register_inet6addr_notifier(&pAdapter->ipv6_notifier);
6736 if (ret)
6737 {
6738 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
6739 }
6740 else
6741 {
6742 hddLog(LOG1, FL("Registered IPv6 notifier"));
6743 pAdapter->ipv6_notifier_registered = true;
6744 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306745#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 //Stop the Interface TX queue.
6747 netif_tx_disable(pAdapter->dev);
6748 //netif_tx_disable(pWlanDev);
6749 netif_carrier_off(pAdapter->dev);
6750
6751 break;
6752 }
6753
Jeff Johnson295189b2012-06-20 16:38:30 -07006754 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 case WLAN_HDD_SOFTAP:
6756 {
6757 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6758 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306759 {
6760 hddLog(VOS_TRACE_LEVEL_FATAL,
6761 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006762 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306763 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006764
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6766 NL80211_IFTYPE_AP:
6767 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 pAdapter->device_mode = session_type;
6769
6770 status = hdd_init_ap_mode(pAdapter);
6771 if( VOS_STATUS_SUCCESS != status )
6772 goto err_free_netdev;
6773
6774 status = hdd_register_hostapd( pAdapter, rtnl_held );
6775 if( VOS_STATUS_SUCCESS != status )
6776 {
6777 hdd_deinit_adapter(pHddCtx, pAdapter);
6778 goto err_free_netdev;
6779 }
6780
6781 netif_tx_disable(pAdapter->dev);
6782 netif_carrier_off(pAdapter->dev);
6783
6784 hdd_set_conparam( 1 );
6785 break;
6786 }
6787 case WLAN_HDD_MONITOR:
6788 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6790 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306791 {
6792 hddLog(VOS_TRACE_LEVEL_FATAL,
6793 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306795 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006796
6797 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6798 pAdapter->device_mode = session_type;
6799 status = hdd_register_interface( pAdapter, rtnl_held );
6800#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6801 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6802#else
6803 pAdapter->dev->open = hdd_mon_open;
6804 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6805#endif
6806 hdd_init_tx_rx( pAdapter );
6807 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6808 //Set adapter to be used for data tx. It will use either GO or softap.
6809 pAdapter->sessionCtx.monitor.pAdapterForTx =
6810 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006811 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6812 {
6813 pAdapter->sessionCtx.monitor.pAdapterForTx =
6814 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6815 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 /* This workqueue will be used to transmit management packet over
6817 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006818 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6819 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6820 return NULL;
6821 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006822
Jeff Johnson295189b2012-06-20 16:38:30 -07006823 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6824 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 }
6826 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006827 case WLAN_HDD_FTM:
6828 {
6829 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6830
6831 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306832 {
6833 hddLog(VOS_TRACE_LEVEL_FATAL,
6834 FL("failed to allocate adapter for session %d"), session_type);
6835 return NULL;
6836 }
6837
Jeff Johnson295189b2012-06-20 16:38:30 -07006838 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6839 * message while loading driver in FTM mode. */
6840 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6841 pAdapter->device_mode = session_type;
6842 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306843
6844 hdd_init_tx_rx( pAdapter );
6845
6846 //Stop the Interface TX queue.
6847 netif_tx_disable(pAdapter->dev);
6848 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 }
6850 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 default:
6852 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306853 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6854 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 VOS_ASSERT(0);
6856 return NULL;
6857 }
6858 }
6859
Jeff Johnson295189b2012-06-20 16:38:30 -07006860 if( VOS_STATUS_SUCCESS == status )
6861 {
6862 //Add it to the hdd's session list.
6863 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6864 if( NULL == pHddAdapterNode )
6865 {
6866 status = VOS_STATUS_E_NOMEM;
6867 }
6868 else
6869 {
6870 pHddAdapterNode->pAdapter = pAdapter;
6871 status = hdd_add_adapter_back ( pHddCtx,
6872 pHddAdapterNode );
6873 }
6874 }
6875
6876 if( VOS_STATUS_SUCCESS != status )
6877 {
6878 if( NULL != pAdapter )
6879 {
6880 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6881 pAdapter = NULL;
6882 }
6883 if( NULL != pHddAdapterNode )
6884 {
6885 vos_mem_free( pHddAdapterNode );
6886 }
6887
6888 goto resume_bmps;
6889 }
6890
6891 if(VOS_STATUS_SUCCESS == status)
6892 {
6893 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6894
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006895 //Initialize the WoWL service
6896 if(!hdd_init_wowl(pAdapter))
6897 {
6898 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6899 goto err_free_netdev;
6900 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006901 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006902 return pAdapter;
6903
6904err_free_netdev:
6905 free_netdev(pAdapter->dev);
6906 wlan_hdd_release_intf_addr( pHddCtx,
6907 pAdapter->macAddressCurrent.bytes );
6908
6909resume_bmps:
6910 //If bmps disabled enable it
6911 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6912 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306913 if (pHddCtx->hdd_wlan_suspended)
6914 {
6915 hdd_set_pwrparams(pHddCtx);
6916 }
6917 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006918 }
6919 return NULL;
6920}
6921
6922VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6923 tANI_U8 rtnl_held )
6924{
6925 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6926 VOS_STATUS status;
6927
6928 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6929 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306930 {
6931 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6932 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006935
6936 while ( pCurrent->pAdapter != pAdapter )
6937 {
6938 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6939 if( VOS_STATUS_SUCCESS != status )
6940 break;
6941
6942 pCurrent = pNext;
6943 }
6944 pAdapterNode = pCurrent;
6945 if( VOS_STATUS_SUCCESS == status )
6946 {
6947 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6948 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306949
6950#ifdef FEATURE_WLAN_TDLS
6951
6952 /* A Mutex Lock is introduced while changing/initializing the mode to
6953 * protect the concurrent access for the Adapters by TDLS module.
6954 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306955 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306956#endif
6957
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 hdd_remove_adapter( pHddCtx, pAdapterNode );
6959 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006960 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006961
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306962#ifdef FEATURE_WLAN_TDLS
6963 mutex_unlock(&pHddCtx->tdls_lock);
6964#endif
6965
Jeff Johnson295189b2012-06-20 16:38:30 -07006966
6967 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306968 if ((!vos_concurrent_open_sessions_running()) &&
6969 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6970 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006971 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306972 if (pHddCtx->hdd_wlan_suspended)
6973 {
6974 hdd_set_pwrparams(pHddCtx);
6975 }
6976 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006977 }
6978
6979 return VOS_STATUS_SUCCESS;
6980 }
6981
6982 return VOS_STATUS_E_FAILURE;
6983}
6984
6985VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6986{
6987 hdd_adapter_list_node_t *pHddAdapterNode;
6988 VOS_STATUS status;
6989
6990 ENTER();
6991
6992 do
6993 {
6994 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6995 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6996 {
6997 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6998 vos_mem_free( pHddAdapterNode );
6999 }
7000 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7001
7002 EXIT();
7003
7004 return VOS_STATUS_SUCCESS;
7005}
7006
7007void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7008{
7009 v_U8_t addIE[1] = {0};
7010
7011 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7012 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7013 eANI_BOOLEAN_FALSE) )
7014 {
7015 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007016 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 }
7018
7019 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7020 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7021 eANI_BOOLEAN_FALSE) )
7022 {
7023 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007024 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 }
7026
7027 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7028 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7029 eANI_BOOLEAN_FALSE) )
7030 {
7031 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007032 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007033 }
7034}
7035
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307036VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7037 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007038{
7039 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7040 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307041 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007042 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307043 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307044 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007045
7046 ENTER();
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307047 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007048 switch(pAdapter->device_mode)
7049 {
7050 case WLAN_HDD_INFRA_STATION:
7051 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007052 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307053 {
7054 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7055 if( hdd_connIsConnected(pstation) ||
7056 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007057 {
7058 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7059 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7060 pAdapter->sessionId,
7061 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7062 else
7063 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7064 pAdapter->sessionId,
7065 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7066 //success implies disconnect command got queued up successfully
7067 if(halStatus == eHAL_STATUS_SUCCESS)
7068 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307069 ret = wait_for_completion_interruptible_timeout(
7070 &pAdapter->disconnect_comp_var,
7071 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7072 if (ret <= 0)
7073 {
7074 hddLog(VOS_TRACE_LEVEL_ERROR,
7075 "%s: wait on disconnect_comp_var failed %ld",
7076 __func__, ret);
7077 }
7078 }
7079 else
7080 {
7081 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7082 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007083 }
7084 memset(&wrqu, '\0', sizeof(wrqu));
7085 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7086 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7087 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7088 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307089 else if(pstation->conn_info.connState ==
7090 eConnectionState_Disconnecting)
7091 {
7092 ret = wait_for_completion_interruptible_timeout(
7093 &pAdapter->disconnect_comp_var,
7094 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7095 if (ret <= 0)
7096 {
7097 hddLog(VOS_TRACE_LEVEL_ERROR,
7098 FL("wait on disconnect_comp_var failed %ld"), ret);
7099 }
7100 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307101 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007102 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307103 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307104 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307106 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7107 {
7108 while (pAdapter->is_roc_inprogress)
7109 {
7110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7111 "%s: ROC in progress for session %d!!!",
7112 __func__, pAdapter->sessionId);
7113 // waiting for ROC to expire
7114 msleep(500);
7115 /* In GO present case , if retry exceeds 3,
7116 it means something went wrong. */
7117 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7118 {
7119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7120 "%s: ROC completion is not received.!!!", __func__);
7121 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
7122 pAdapter->sessionId);
7123 wait_for_completion_interruptible_timeout(
7124 &pAdapter->cancel_rem_on_chan_var,
7125 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7126 break;
7127 }
7128 }
7129 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307130#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307131#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307132 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7133#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307134 if (pAdapter->ipv6_notifier_registered)
7135 {
7136 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
7137 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
7138 pAdapter->ipv6_notifier_registered = false;
7139 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307140#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05307141 if (pAdapter->ipv4_notifier_registered)
7142 {
7143 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
7144 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
7145 pAdapter->ipv4_notifier_registered = false;
7146 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307147#ifdef WLAN_OPEN_SOURCE
7148 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7149#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307150 /* It is possible that the caller of this function does not
7151 * wish to close the session
7152 */
7153 if (VOS_TRUE == bCloseSession &&
7154 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007155 {
7156 INIT_COMPLETION(pAdapter->session_close_comp_var);
7157 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307158 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7159 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307161 unsigned long ret;
7162
Jeff Johnson295189b2012-06-20 16:38:30 -07007163 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307164 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307165 &pAdapter->session_close_comp_var,
7166 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307167 if ( 0 >= ret)
7168 {
7169 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307170 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307171 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007172 }
7173 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307174 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007175 break;
7176
7177 case WLAN_HDD_SOFTAP:
7178 case WLAN_HDD_P2P_GO:
7179 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307180 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7181 while (pAdapter->is_roc_inprogress) {
7182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7183 "%s: ROC in progress for session %d!!!",
7184 __func__, pAdapter->sessionId);
7185 msleep(500);
7186 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7188 "%s: ROC completion is not received.!!!", __func__);
7189 WLANSAP_CancelRemainOnChannel(
7190 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7191 wait_for_completion_interruptible_timeout(
7192 &pAdapter->cancel_rem_on_chan_var,
7193 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7194 break;
7195 }
7196 }
7197 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007198 mutex_lock(&pHddCtx->sap_lock);
7199 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7200 {
7201 VOS_STATUS status;
7202 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7203
7204 //Stop Bss.
7205 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7206 if (VOS_IS_STATUS_SUCCESS(status))
7207 {
7208 hdd_hostapd_state_t *pHostapdState =
7209 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7210
7211 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7212
7213 if (!VOS_IS_STATUS_SUCCESS(status))
7214 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307215 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7216 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007217 }
7218 }
7219 else
7220 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007221 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 }
7223 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307224 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007225
7226 if (eHAL_STATUS_FAILURE ==
7227 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7228 0, NULL, eANI_BOOLEAN_FALSE))
7229 {
7230 hddLog(LOGE,
7231 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007232 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007233 }
7234
7235 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7236 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7237 eANI_BOOLEAN_FALSE) )
7238 {
7239 hddLog(LOGE,
7240 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7241 }
7242
7243 // Reset WNI_CFG_PROBE_RSP Flags
7244 wlan_hdd_reset_prob_rspies(pAdapter);
7245 kfree(pAdapter->sessionCtx.ap.beacon);
7246 pAdapter->sessionCtx.ap.beacon = NULL;
7247 }
7248 mutex_unlock(&pHddCtx->sap_lock);
7249 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007250
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007252#ifdef WLAN_OPEN_SOURCE
7253 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7254#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007255 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007256
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 default:
7258 break;
7259 }
7260
7261 EXIT();
7262 return VOS_STATUS_SUCCESS;
7263}
7264
7265VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7266{
7267 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7268 VOS_STATUS status;
7269 hdd_adapter_t *pAdapter;
7270
7271 ENTER();
7272
7273 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7274
7275 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7276 {
7277 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007278
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307279 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007280
7281 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7282 pAdapterNode = pNext;
7283 }
7284
7285 EXIT();
7286
7287 return VOS_STATUS_SUCCESS;
7288}
7289
Rajeev Kumarf999e582014-01-09 17:33:29 -08007290
7291#ifdef FEATURE_WLAN_BATCH_SCAN
7292/**---------------------------------------------------------------------------
7293
7294 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7295 structures
7296
7297 \param - pAdapter Pointer to HDD adapter
7298
7299 \return - None
7300
7301 --------------------------------------------------------------------------*/
7302void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7303{
7304 tHddBatchScanRsp *pNode;
7305 tHddBatchScanRsp *pPrev;
7306
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307307 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007308 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307309 hddLog(VOS_TRACE_LEVEL_ERROR,
7310 "%s: Adapter context is Null", __func__);
7311 return;
7312 }
7313
7314 pNode = pAdapter->pBatchScanRsp;
7315 while (pNode)
7316 {
7317 pPrev = pNode;
7318 pNode = pNode->pNext;
7319 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007320 }
7321
7322 pAdapter->pBatchScanRsp = NULL;
7323 pAdapter->numScanList = 0;
7324 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7325 pAdapter->prev_batch_id = 0;
7326
7327 return;
7328}
7329#endif
7330
7331
Jeff Johnson295189b2012-06-20 16:38:30 -07007332VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7333{
7334 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7335 VOS_STATUS status;
7336 hdd_adapter_t *pAdapter;
7337
7338 ENTER();
7339
7340 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7341
7342 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7343 {
7344 pAdapter = pAdapterNode->pAdapter;
7345 netif_tx_disable(pAdapter->dev);
7346 netif_carrier_off(pAdapter->dev);
7347
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007348 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7349
Jeff Johnson295189b2012-06-20 16:38:30 -07007350 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307351
7352 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7353
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307354 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7355 {
7356 hdd_wmm_adapter_close( pAdapter );
7357 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7358 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007359
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307360 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7361 {
7362 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7363 }
7364
Rajeev Kumarf999e582014-01-09 17:33:29 -08007365#ifdef FEATURE_WLAN_BATCH_SCAN
7366 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7367 {
7368 hdd_deinit_batch_scan(pAdapter);
7369 }
7370#endif
7371
Jeff Johnson295189b2012-06-20 16:38:30 -07007372 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7373 pAdapterNode = pNext;
7374 }
7375
7376 EXIT();
7377
7378 return VOS_STATUS_SUCCESS;
7379}
7380
7381VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7382{
7383 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7384 VOS_STATUS status;
7385 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307386 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007387
7388 ENTER();
7389
7390 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7391
7392 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7393 {
7394 pAdapter = pAdapterNode->pAdapter;
7395
Kumar Anand82c009f2014-05-29 00:29:42 -07007396 hdd_wmm_init( pAdapter );
7397
Jeff Johnson295189b2012-06-20 16:38:30 -07007398 switch(pAdapter->device_mode)
7399 {
7400 case WLAN_HDD_INFRA_STATION:
7401 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007402 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307403
7404 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7405
Jeff Johnson295189b2012-06-20 16:38:30 -07007406 hdd_init_station_mode(pAdapter);
7407 /* Open the gates for HDD to receive Wext commands */
7408 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007409 pHddCtx->scan_info.mScanPending = FALSE;
7410 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007411
7412 //Trigger the initial scan
7413 hdd_wlan_initial_scan(pAdapter);
7414
7415 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307416 if (eConnectionState_Associated == connState ||
7417 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 {
7419 union iwreq_data wrqu;
7420 memset(&wrqu, '\0', sizeof(wrqu));
7421 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7422 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7423 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007424 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007425
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 /* indicate disconnected event to nl80211 */
7427 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7428 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007429 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307430 else if (eConnectionState_Connecting == connState)
7431 {
7432 /*
7433 * Indicate connect failure to supplicant if we were in the
7434 * process of connecting
7435 */
7436 cfg80211_connect_result(pAdapter->dev, NULL,
7437 NULL, 0, NULL, 0,
7438 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7439 GFP_KERNEL);
7440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007441 break;
7442
7443 case WLAN_HDD_SOFTAP:
7444 /* softAP can handle SSR */
7445 break;
7446
7447 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007448 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007450 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 break;
7452
7453 case WLAN_HDD_MONITOR:
7454 /* monitor interface start */
7455 break;
7456 default:
7457 break;
7458 }
7459
7460 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7461 pAdapterNode = pNext;
7462 }
7463
7464 EXIT();
7465
7466 return VOS_STATUS_SUCCESS;
7467}
7468
7469VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7470{
7471 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7472 hdd_adapter_t *pAdapter;
7473 VOS_STATUS status;
7474 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307475 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007476
7477 ENTER();
7478
7479 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7480
7481 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7482 {
7483 pAdapter = pAdapterNode->pAdapter;
7484
7485 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7486 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7487 {
7488 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7489 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7490
Abhishek Singhf4669da2014-05-26 15:07:49 +05307491 hddLog(VOS_TRACE_LEVEL_INFO,
7492 "%s: Set HDD connState to eConnectionState_NotConnected",
7493 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7495 init_completion(&pAdapter->disconnect_comp_var);
7496 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7497 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7498
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307499 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 &pAdapter->disconnect_comp_var,
7501 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307502 if (0 >= ret)
7503 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7504 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007505
7506 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7507 pHddCtx->isAmpAllowed = VOS_FALSE;
7508 sme_RoamConnect(pHddCtx->hHal,
7509 pAdapter->sessionId, &(pWextState->roamProfile),
7510 &roamId);
7511 }
7512
7513 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7514 pAdapterNode = pNext;
7515 }
7516
7517 EXIT();
7518
7519 return VOS_STATUS_SUCCESS;
7520}
7521
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007522void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7523{
7524 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7525 VOS_STATUS status;
7526 hdd_adapter_t *pAdapter;
7527 hdd_station_ctx_t *pHddStaCtx;
7528 hdd_ap_ctx_t *pHddApCtx;
7529 hdd_hostapd_state_t * pHostapdState;
7530 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7531 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7532 const char *p2pMode = "DEV";
7533 const char *ccMode = "Standalone";
7534 int n;
7535
7536 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7537 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7538 {
7539 pAdapter = pAdapterNode->pAdapter;
7540 switch (pAdapter->device_mode) {
7541 case WLAN_HDD_INFRA_STATION:
7542 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7543 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7544 staChannel = pHddStaCtx->conn_info.operationChannel;
7545 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7546 }
7547 break;
7548 case WLAN_HDD_P2P_CLIENT:
7549 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7550 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7551 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7552 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7553 p2pMode = "CLI";
7554 }
7555 break;
7556 case WLAN_HDD_P2P_GO:
7557 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7558 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7559 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7560 p2pChannel = pHddApCtx->operatingChannel;
7561 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7562 }
7563 p2pMode = "GO";
7564 break;
7565 case WLAN_HDD_SOFTAP:
7566 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7567 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7568 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7569 apChannel = pHddApCtx->operatingChannel;
7570 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7571 }
7572 break;
7573 default:
7574 break;
7575 }
7576 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7577 pAdapterNode = pNext;
7578 }
7579 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7580 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7581 }
7582 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7583 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7584 if (p2pChannel > 0) {
7585 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7586 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7587 }
7588 if (apChannel > 0) {
7589 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7590 apChannel, MAC_ADDR_ARRAY(apBssid));
7591 }
7592
7593 if (p2pChannel > 0 && apChannel > 0) {
7594 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7595 }
7596}
7597
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007598bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007599{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007600 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007601}
7602
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007603/* Once SSR is disabled then it cannot be set. */
7604void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007605{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007606 if (HDD_SSR_DISABLED == isSsrRequired)
7607 return;
7608
Jeff Johnson295189b2012-06-20 16:38:30 -07007609 isSsrRequired = value;
7610}
7611
7612VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7613 hdd_adapter_list_node_t** ppAdapterNode)
7614{
7615 VOS_STATUS status;
7616 spin_lock(&pHddCtx->hddAdapters.lock);
7617 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7618 (hdd_list_node_t**) ppAdapterNode );
7619 spin_unlock(&pHddCtx->hddAdapters.lock);
7620 return status;
7621}
7622
7623VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7624 hdd_adapter_list_node_t* pAdapterNode,
7625 hdd_adapter_list_node_t** pNextAdapterNode)
7626{
7627 VOS_STATUS status;
7628 spin_lock(&pHddCtx->hddAdapters.lock);
7629 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7630 (hdd_list_node_t*) pAdapterNode,
7631 (hdd_list_node_t**)pNextAdapterNode );
7632
7633 spin_unlock(&pHddCtx->hddAdapters.lock);
7634 return status;
7635}
7636
7637VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7638 hdd_adapter_list_node_t* pAdapterNode)
7639{
7640 VOS_STATUS status;
7641 spin_lock(&pHddCtx->hddAdapters.lock);
7642 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7643 &pAdapterNode->node );
7644 spin_unlock(&pHddCtx->hddAdapters.lock);
7645 return status;
7646}
7647
7648VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7649 hdd_adapter_list_node_t** ppAdapterNode)
7650{
7651 VOS_STATUS status;
7652 spin_lock(&pHddCtx->hddAdapters.lock);
7653 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7654 (hdd_list_node_t**) ppAdapterNode );
7655 spin_unlock(&pHddCtx->hddAdapters.lock);
7656 return status;
7657}
7658
7659VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7660 hdd_adapter_list_node_t* pAdapterNode)
7661{
7662 VOS_STATUS status;
7663 spin_lock(&pHddCtx->hddAdapters.lock);
7664 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7665 (hdd_list_node_t*) pAdapterNode );
7666 spin_unlock(&pHddCtx->hddAdapters.lock);
7667 return status;
7668}
7669
7670VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7671 hdd_adapter_list_node_t* pAdapterNode)
7672{
7673 VOS_STATUS status;
7674 spin_lock(&pHddCtx->hddAdapters.lock);
7675 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7676 (hdd_list_node_t*) pAdapterNode );
7677 spin_unlock(&pHddCtx->hddAdapters.lock);
7678 return status;
7679}
7680
7681hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7682 tSirMacAddr macAddr )
7683{
7684 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7685 hdd_adapter_t *pAdapter;
7686 VOS_STATUS status;
7687
7688 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7689
7690 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7691 {
7692 pAdapter = pAdapterNode->pAdapter;
7693
7694 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7695 macAddr, sizeof(tSirMacAddr) ) )
7696 {
7697 return pAdapter;
7698 }
7699 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7700 pAdapterNode = pNext;
7701 }
7702
7703 return NULL;
7704
7705}
7706
7707hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7708{
7709 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7710 hdd_adapter_t *pAdapter;
7711 VOS_STATUS status;
7712
7713 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7714
7715 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7716 {
7717 pAdapter = pAdapterNode->pAdapter;
7718
7719 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7720 IFNAMSIZ ) )
7721 {
7722 return pAdapter;
7723 }
7724 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7725 pAdapterNode = pNext;
7726 }
7727
7728 return NULL;
7729
7730}
7731
7732hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7733{
7734 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7735 hdd_adapter_t *pAdapter;
7736 VOS_STATUS status;
7737
7738 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7739
7740 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7741 {
7742 pAdapter = pAdapterNode->pAdapter;
7743
7744 if( pAdapter && (mode == pAdapter->device_mode) )
7745 {
7746 return pAdapter;
7747 }
7748 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7749 pAdapterNode = pNext;
7750 }
7751
7752 return NULL;
7753
7754}
7755
7756//Remove this function later
7757hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7758{
7759 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7760 hdd_adapter_t *pAdapter;
7761 VOS_STATUS status;
7762
7763 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7764
7765 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7766 {
7767 pAdapter = pAdapterNode->pAdapter;
7768
7769 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7770 {
7771 return pAdapter;
7772 }
7773
7774 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7775 pAdapterNode = pNext;
7776 }
7777
7778 return NULL;
7779
7780}
7781
Jeff Johnson295189b2012-06-20 16:38:30 -07007782/**---------------------------------------------------------------------------
7783
7784 \brief hdd_set_monitor_tx_adapter() -
7785
7786 This API initializes the adapter to be used while transmitting on monitor
7787 adapter.
7788
7789 \param - pHddCtx - Pointer to the HDD context.
7790 pAdapter - Adapter that will used for TX. This can be NULL.
7791 \return - None.
7792 --------------------------------------------------------------------------*/
7793void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7794{
7795 hdd_adapter_t *pMonAdapter;
7796
7797 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7798
7799 if( NULL != pMonAdapter )
7800 {
7801 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7802 }
7803}
Jeff Johnson295189b2012-06-20 16:38:30 -07007804/**---------------------------------------------------------------------------
7805
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307806 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007807
7808 This API returns the operating channel of the requested device mode
7809
7810 \param - pHddCtx - Pointer to the HDD context.
7811 - mode - Device mode for which operating channel is required
7812 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7813 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7814 \return - channel number. "0" id the requested device is not found OR it is not connected.
7815 --------------------------------------------------------------------------*/
7816v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7817{
7818 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7819 VOS_STATUS status;
7820 hdd_adapter_t *pAdapter;
7821 v_U8_t operatingChannel = 0;
7822
7823 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7824
7825 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7826 {
7827 pAdapter = pAdapterNode->pAdapter;
7828
7829 if( mode == pAdapter->device_mode )
7830 {
7831 switch(pAdapter->device_mode)
7832 {
7833 case WLAN_HDD_INFRA_STATION:
7834 case WLAN_HDD_P2P_CLIENT:
7835 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7836 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7837 break;
7838 case WLAN_HDD_SOFTAP:
7839 case WLAN_HDD_P2P_GO:
7840 /*softap connection info */
7841 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7842 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7843 break;
7844 default:
7845 break;
7846 }
7847
7848 break; //Found the device of interest. break the loop
7849 }
7850
7851 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7852 pAdapterNode = pNext;
7853 }
7854 return operatingChannel;
7855}
7856
7857#ifdef WLAN_FEATURE_PACKET_FILTERING
7858/**---------------------------------------------------------------------------
7859
7860 \brief hdd_set_multicast_list() -
7861
7862 This used to set the multicast address list.
7863
7864 \param - dev - Pointer to the WLAN device.
7865 - skb - Pointer to OS packet (sk_buff).
7866 \return - success/fail
7867
7868 --------------------------------------------------------------------------*/
7869static void hdd_set_multicast_list(struct net_device *dev)
7870{
7871 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007872 int mc_count;
7873 int i = 0;
7874 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307875
7876 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007877 {
7878 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307879 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 return;
7881 }
7882
7883 if (dev->flags & IFF_ALLMULTI)
7884 {
7885 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007886 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307887 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007888 }
7889 else
7890 {
7891 mc_count = netdev_mc_count(dev);
7892 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007893 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007894 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7895 {
7896 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007897 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307898 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007899 return;
7900 }
7901
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307902 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007903
7904 netdev_for_each_mc_addr(ha, dev) {
7905 if (i == mc_count)
7906 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307907 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7908 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007909 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307911 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007912 i++;
7913 }
7914 }
7915 return;
7916}
7917#endif
7918
7919/**---------------------------------------------------------------------------
7920
7921 \brief hdd_select_queue() -
7922
7923 This function is registered with the Linux OS for network
7924 core to decide which queue to use first.
7925
7926 \param - dev - Pointer to the WLAN device.
7927 - skb - Pointer to OS packet (sk_buff).
7928 \return - ac, Queue Index/access category corresponding to UP in IP header
7929
7930 --------------------------------------------------------------------------*/
7931v_U16_t hdd_select_queue(struct net_device *dev,
7932 struct sk_buff *skb)
7933{
7934 return hdd_wmm_select_queue(dev, skb);
7935}
7936
7937
7938/**---------------------------------------------------------------------------
7939
7940 \brief hdd_wlan_initial_scan() -
7941
7942 This function triggers the initial scan
7943
7944 \param - pAdapter - Pointer to the HDD adapter.
7945
7946 --------------------------------------------------------------------------*/
7947void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7948{
7949 tCsrScanRequest scanReq;
7950 tCsrChannelInfo channelInfo;
7951 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007952 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7954
7955 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7956 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7957 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7958
7959 if(sme_Is11dSupported(pHddCtx->hHal))
7960 {
7961 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7962 if ( HAL_STATUS_SUCCESS( halStatus ) )
7963 {
7964 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7965 if( !scanReq.ChannelInfo.ChannelList )
7966 {
7967 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7968 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007969 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 return;
7971 }
7972 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7973 channelInfo.numOfChannels);
7974 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7975 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007976 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007977 }
7978
7979 scanReq.scanType = eSIR_PASSIVE_SCAN;
7980 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7981 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7982 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7983 }
7984 else
7985 {
7986 scanReq.scanType = eSIR_ACTIVE_SCAN;
7987 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7988 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7989 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7990 }
7991
7992 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7993 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7994 {
7995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7996 __func__, halStatus );
7997 }
7998
7999 if(sme_Is11dSupported(pHddCtx->hHal))
8000 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8001}
8002
Jeff Johnson295189b2012-06-20 16:38:30 -07008003/**---------------------------------------------------------------------------
8004
8005 \brief hdd_full_power_callback() - HDD full power callback function
8006
8007 This is the function invoked by SME to inform the result of a full power
8008 request issued by HDD
8009
8010 \param - callbackcontext - Pointer to cookie
8011 \param - status - result of request
8012
8013 \return - None
8014
8015 --------------------------------------------------------------------------*/
8016static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8017{
Jeff Johnson72a40512013-12-19 10:14:15 -08008018 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008019
8020 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308021 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008022
8023 if (NULL == callbackContext)
8024 {
8025 hddLog(VOS_TRACE_LEVEL_ERROR,
8026 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008027 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008028 return;
8029 }
8030
Jeff Johnson72a40512013-12-19 10:14:15 -08008031 /* there is a race condition that exists between this callback
8032 function and the caller since the caller could time out either
8033 before or while this code is executing. we use a spinlock to
8034 serialize these actions */
8035 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008036
8037 if (POWER_CONTEXT_MAGIC != pContext->magic)
8038 {
8039 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008040 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008041 hddLog(VOS_TRACE_LEVEL_WARN,
8042 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008043 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008044 return;
8045 }
8046
Jeff Johnson72a40512013-12-19 10:14:15 -08008047 /* context is valid so caller is still waiting */
8048
8049 /* paranoia: invalidate the magic */
8050 pContext->magic = 0;
8051
8052 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008053 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008054
8055 /* serialization is complete */
8056 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008057}
8058
8059/**---------------------------------------------------------------------------
8060
8061 \brief hdd_wlan_exit() - HDD WLAN exit function
8062
8063 This is the driver exit point (invoked during rmmod)
8064
8065 \param - pHddCtx - Pointer to the HDD Context
8066
8067 \return - None
8068
8069 --------------------------------------------------------------------------*/
8070void hdd_wlan_exit(hdd_context_t *pHddCtx)
8071{
8072 eHalStatus halStatus;
8073 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8074 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308075 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008076 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008077 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308079 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008080
8081 ENTER();
8082
Jeff Johnson88ba7742013-02-27 14:36:02 -08008083 if (VOS_FTM_MODE != hdd_get_conparam())
8084 {
8085 // Unloading, restart logic is no more required.
8086 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008087
c_hpothu5ab05e92014-06-13 17:34:05 +05308088 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8089 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308091 pAdapter = pAdapterNode->pAdapter;
8092 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008093 {
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308094 /* Disable TX on the interface, after this hard_start_xmit() will
8095 * not be called on that interface
8096 */
8097 netif_tx_disable(pAdapter->dev);
8098
8099 /* Mark the interface status as "down" for outside world */
8100 netif_carrier_off(pAdapter->dev);
8101
8102 /* DeInit the adapter. This ensures that all data packets
8103 * are freed.
8104 */
8105 hdd_deinit_adapter(pHddCtx, pAdapter);
8106
c_hpothu5ab05e92014-06-13 17:34:05 +05308107 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8108 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8109 {
8110 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8111 hdd_UnregisterWext(pAdapter->dev);
8112 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308113
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308115 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8116 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308118 // Cancel any outstanding scan requests. We are about to close all
8119 // of our adapters, but an adapter structure is what SME passes back
8120 // to our callback function. Hence if there are any outstanding scan
8121 // requests then there is a race condition between when the adapter
8122 // is closed and when the callback is invoked.We try to resolve that
8123 // race condition here by canceling any outstanding scans before we
8124 // close the adapters.
8125 // Note that the scans may be cancelled in an asynchronous manner,
8126 // so ideally there needs to be some kind of synchronization. Rather
8127 // than introduce a new synchronization here, we will utilize the
8128 // fact that we are about to Request Full Power, and since that is
8129 // synchronized, the expectation is that by the time Request Full
8130 // Power has completed all scans will be cancelled.
8131 if (pHddCtx->scan_info.mScanPending)
8132 {
8133 hddLog(VOS_TRACE_LEVEL_INFO,
8134 FL("abort scan mode: %d sessionId: %d"),
8135 pAdapter->device_mode,
8136 pAdapter->sessionId);
8137 hdd_abort_mac_scan(pHddCtx,
8138 pHddCtx->scan_info.sessionId,
8139 eCSR_SCAN_ABORT_DEFAULT);
8140 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008141 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308142 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008143 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308144 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08008145 wlan_hdd_ftm_close(pHddCtx);
8146 goto free_hdd_ctx;
8147 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308148
Jeff Johnson295189b2012-06-20 16:38:30 -07008149 /* DeRegister with platform driver as client for Suspend/Resume */
8150 vosStatus = hddDeregisterPmOps(pHddCtx);
8151 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8152 {
8153 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8154 VOS_ASSERT(0);
8155 }
8156
8157 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8158 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8159 {
8160 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8161 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008162
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008163 //Stop the traffic monitor timer
8164 if ( VOS_TIMER_STATE_RUNNING ==
8165 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8166 {
8167 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8168 }
8169
8170 // Destroy the traffic monitor timer
8171 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8172 &pHddCtx->tx_rx_trafficTmr)))
8173 {
8174 hddLog(VOS_TRACE_LEVEL_ERROR,
8175 "%s: Cannot deallocate Traffic monitor timer", __func__);
8176 }
8177
Jeff Johnson295189b2012-06-20 16:38:30 -07008178 //Disable IMPS/BMPS as we do not want the device to enter any power
8179 //save mode during shutdown
8180 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8181 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8182 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8183
8184 //Ensure that device is in full power as we will touch H/W during vos_Stop
8185 init_completion(&powerContext.completion);
8186 powerContext.magic = POWER_CONTEXT_MAGIC;
8187
8188 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8189 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8190
8191 if (eHAL_STATUS_SUCCESS != halStatus)
8192 {
8193 if (eHAL_STATUS_PMC_PENDING == halStatus)
8194 {
8195 /* request was sent -- wait for the response */
8196 lrc = wait_for_completion_interruptible_timeout(
8197 &powerContext.completion,
8198 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008199 if (lrc <= 0)
8200 {
8201 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008202 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008203 }
8204 }
8205 else
8206 {
8207 hddLog(VOS_TRACE_LEVEL_ERROR,
8208 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008209 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008210 /* continue -- need to clean up as much as possible */
8211 }
8212 }
8213
Jeff Johnson72a40512013-12-19 10:14:15 -08008214 /* either we never sent a request, we sent a request and received a
8215 response or we sent a request and timed out. if we never sent a
8216 request or if we sent a request and got a response, we want to
8217 clear the magic out of paranoia. if we timed out there is a
8218 race condition such that the callback function could be
8219 executing at the same time we are. of primary concern is if the
8220 callback function had already verified the "magic" but had not
8221 yet set the completion variable when a timeout occurred. we
8222 serialize these activities by invalidating the magic while
8223 holding a shared spinlock which will cause us to block if the
8224 callback is currently executing */
8225 spin_lock(&hdd_context_lock);
8226 powerContext.magic = 0;
8227 spin_unlock(&hdd_context_lock);
8228
Yue Ma0d4891e2013-08-06 17:01:45 -07008229 hdd_debugfs_exit(pHddCtx);
8230
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 // Unregister the Net Device Notifier
8232 unregister_netdevice_notifier(&hdd_netdev_notifier);
8233
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 hdd_stop_all_adapters( pHddCtx );
8235
Jeff Johnson295189b2012-06-20 16:38:30 -07008236#ifdef WLAN_BTAMP_FEATURE
8237 vosStatus = WLANBAP_Stop(pVosContext);
8238 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8239 {
8240 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8241 "%s: Failed to stop BAP",__func__);
8242 }
8243#endif //WLAN_BTAMP_FEATURE
8244
8245 //Stop all the modules
8246 vosStatus = vos_stop( pVosContext );
8247 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8248 {
8249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8250 "%s: Failed to stop VOSS",__func__);
8251 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8252 }
8253
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008255 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008256
8257 //Close the scheduler before calling vos_close to make sure no thread is
8258 // scheduled after the each module close is called i.e after all the data
8259 // structures are freed.
8260 vosStatus = vos_sched_close( pVosContext );
8261 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8262 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8263 "%s: Failed to close VOSS Scheduler",__func__);
8264 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8265 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008266#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008267#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8268 /* Destroy the wake lock */
8269 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8270#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008271 /* Destroy the wake lock */
8272 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008273#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008274
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308275#ifdef CONFIG_ENABLE_LINUX_REG
8276 vosStatus = vos_nv_close();
8277 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8278 {
8279 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8280 "%s: Failed to close NV", __func__);
8281 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8282 }
8283#endif
8284
Jeff Johnson295189b2012-06-20 16:38:30 -07008285 //Close VOSS
8286 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8287 vos_close(pVosContext);
8288
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 //Close Watchdog
8290 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8291 vos_watchdog_close(pVosContext);
8292
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308293 //Clean up HDD Nlink Service
8294 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308295
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308296#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308297 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308298 {
8299 wlan_logging_sock_deactivate_svc();
8300 }
8301#endif
8302
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308303#ifdef WLAN_KD_READY_NOTIFIER
8304 nl_srv_exit(pHddCtx->ptt_pid);
8305#else
8306 nl_srv_exit();
8307#endif /* WLAN_KD_READY_NOTIFIER */
8308
8309
Jeff Johnson295189b2012-06-20 16:38:30 -07008310 hdd_close_all_adapters( pHddCtx );
8311
Jeff Johnson295189b2012-06-20 16:38:30 -07008312 /* free the power on lock from platform driver */
8313 if (free_riva_power_on_lock("wlan"))
8314 {
8315 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8316 __func__);
8317 }
8318
Jeff Johnson88ba7742013-02-27 14:36:02 -08008319free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308320
8321 //Free up dynamically allocated members inside HDD Adapter
8322 if (pHddCtx->cfg_ini)
8323 {
8324 kfree(pHddCtx->cfg_ini);
8325 pHddCtx->cfg_ini= NULL;
8326 }
8327
Leo Changf04ddad2013-09-18 13:46:38 -07008328 /* FTM mode, WIPHY did not registered
8329 If un-register here, system crash will happen */
8330 if (VOS_FTM_MODE != hdd_get_conparam())
8331 {
8332 wiphy_unregister(wiphy) ;
8333 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008334 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008335 if (hdd_is_ssr_required())
8336 {
8337 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008338 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 msleep(5000);
8340 }
8341 hdd_set_ssr_required (VOS_FALSE);
8342}
8343
8344
8345/**---------------------------------------------------------------------------
8346
8347 \brief hdd_update_config_from_nv() - Function to update the contents of
8348 the running configuration with parameters taken from NV storage
8349
8350 \param - pHddCtx - Pointer to the HDD global context
8351
8352 \return - VOS_STATUS_SUCCESS if successful
8353
8354 --------------------------------------------------------------------------*/
8355static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8356{
Jeff Johnson295189b2012-06-20 16:38:30 -07008357 v_BOOL_t itemIsValid = VOS_FALSE;
8358 VOS_STATUS status;
8359 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8360 v_U8_t macLoop;
8361
8362 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8363 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8364 if(status != VOS_STATUS_SUCCESS)
8365 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008366 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008367 return VOS_STATUS_E_FAILURE;
8368 }
8369
8370 if (itemIsValid == VOS_TRUE)
8371 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008372 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8374 VOS_MAX_CONCURRENCY_PERSONA);
8375 if(status != VOS_STATUS_SUCCESS)
8376 {
8377 /* Get MAC from NV fail, not update CFG info
8378 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008379 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008380 return VOS_STATUS_E_FAILURE;
8381 }
8382
8383 /* If first MAC is not valid, treat all others are not valid
8384 * Then all MACs will be got from ini file */
8385 if(vos_is_macaddr_zero(&macFromNV[0]))
8386 {
8387 /* MAC address in NV file is not configured yet */
8388 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8389 return VOS_STATUS_E_INVAL;
8390 }
8391
8392 /* Get MAC address from NV, update CFG info */
8393 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8394 {
8395 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8396 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308397 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 /* This MAC is not valid, skip it
8399 * This MAC will be got from ini file */
8400 }
8401 else
8402 {
8403 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8404 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8405 VOS_MAC_ADDR_SIZE);
8406 }
8407 }
8408 }
8409 else
8410 {
8411 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8412 return VOS_STATUS_E_FAILURE;
8413 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008414
Jeff Johnson295189b2012-06-20 16:38:30 -07008415
8416 return VOS_STATUS_SUCCESS;
8417}
8418
8419/**---------------------------------------------------------------------------
8420
8421 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8422
8423 \param - pAdapter - Pointer to the HDD
8424
8425 \return - None
8426
8427 --------------------------------------------------------------------------*/
8428VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8429{
8430 eHalStatus halStatus;
8431 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308432 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008433
Jeff Johnson295189b2012-06-20 16:38:30 -07008434
8435 // Send ready indication to the HDD. This will kick off the MAC
8436 // into a 'running' state and should kick off an initial scan.
8437 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8438 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8439 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308440 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 "code %08d [x%08x]",__func__, halStatus, halStatus );
8442 return VOS_STATUS_E_FAILURE;
8443 }
8444
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308445 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008446 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8447 // And RIVA will crash
8448 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8449 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308450 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8451 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8452
8453
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 return VOS_STATUS_SUCCESS;
8455}
8456
Jeff Johnson295189b2012-06-20 16:38:30 -07008457/* wake lock APIs for HDD */
8458void hdd_prevent_suspend(void)
8459{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008460#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008462#else
8463 wcnss_prevent_suspend();
8464#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008465}
8466
8467void hdd_allow_suspend(void)
8468{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008469#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008471#else
8472 wcnss_allow_suspend();
8473#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008474}
8475
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308476void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008477{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008478#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008479 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008480#else
8481 /* Do nothing as there is no API in wcnss for timeout*/
8482#endif
8483}
8484
Jeff Johnson295189b2012-06-20 16:38:30 -07008485/**---------------------------------------------------------------------------
8486
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008487 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8488 information between Host and Riva
8489
8490 This function gets reported version of FW
8491 It also finds the version of Riva headers used to compile the host
8492 It compares the above two and prints a warning if they are different
8493 It gets the SW and HW version string
8494 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8495 indicating the features they support through a bitmap
8496
8497 \param - pHddCtx - Pointer to HDD context
8498
8499 \return - void
8500
8501 --------------------------------------------------------------------------*/
8502
8503void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8504{
8505
8506 tSirVersionType versionCompiled;
8507 tSirVersionType versionReported;
8508 tSirVersionString versionString;
8509 tANI_U8 fwFeatCapsMsgSupported = 0;
8510 VOS_STATUS vstatus;
8511
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008512 memset(&versionCompiled, 0, sizeof(versionCompiled));
8513 memset(&versionReported, 0, sizeof(versionReported));
8514
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008515 /* retrieve and display WCNSS version information */
8516 do {
8517
8518 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8519 &versionCompiled);
8520 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8521 {
8522 hddLog(VOS_TRACE_LEVEL_FATAL,
8523 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008524 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008525 break;
8526 }
8527
8528 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8529 &versionReported);
8530 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8531 {
8532 hddLog(VOS_TRACE_LEVEL_FATAL,
8533 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008534 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008535 break;
8536 }
8537
8538 if ((versionCompiled.major != versionReported.major) ||
8539 (versionCompiled.minor != versionReported.minor) ||
8540 (versionCompiled.version != versionReported.version) ||
8541 (versionCompiled.revision != versionReported.revision))
8542 {
8543 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8544 "Host expected %u.%u.%u.%u\n",
8545 WLAN_MODULE_NAME,
8546 (int)versionReported.major,
8547 (int)versionReported.minor,
8548 (int)versionReported.version,
8549 (int)versionReported.revision,
8550 (int)versionCompiled.major,
8551 (int)versionCompiled.minor,
8552 (int)versionCompiled.version,
8553 (int)versionCompiled.revision);
8554 }
8555 else
8556 {
8557 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8558 WLAN_MODULE_NAME,
8559 (int)versionReported.major,
8560 (int)versionReported.minor,
8561 (int)versionReported.version,
8562 (int)versionReported.revision);
8563 }
8564
8565 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8566 versionString,
8567 sizeof(versionString));
8568 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8569 {
8570 hddLog(VOS_TRACE_LEVEL_FATAL,
8571 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008572 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008573 break;
8574 }
8575
8576 pr_info("%s: WCNSS software version %s\n",
8577 WLAN_MODULE_NAME, versionString);
8578
8579 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8580 versionString,
8581 sizeof(versionString));
8582 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8583 {
8584 hddLog(VOS_TRACE_LEVEL_FATAL,
8585 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008586 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008587 break;
8588 }
8589
8590 pr_info("%s: WCNSS hardware version %s\n",
8591 WLAN_MODULE_NAME, versionString);
8592
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008593 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8594 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008595 send the message only if it the riva is 1.1
8596 minor numbers for different riva branches:
8597 0 -> (1.0)Mainline Build
8598 1 -> (1.1)Mainline Build
8599 2->(1.04) Stability Build
8600 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008601 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008602 ((versionReported.minor>=1) && (versionReported.version>=1)))
8603 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8604 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008605
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008606 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008607 {
8608#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8609 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8610 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8611#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008612 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8613 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8614 {
8615 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8616 }
8617
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008618 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008619 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008620
8621 } while (0);
8622
8623}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308624void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8625{
8626 struct sk_buff *skb;
8627 struct nlmsghdr *nlh;
8628 tAniMsgHdr *ani_hdr;
8629
8630 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8631
8632 if(skb == NULL) {
8633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8634 "%s: alloc_skb failed", __func__);
8635 return;
8636 }
8637
8638 nlh = (struct nlmsghdr *)skb->data;
8639 nlh->nlmsg_pid = 0; /* from kernel */
8640 nlh->nlmsg_flags = 0;
8641 nlh->nlmsg_seq = 0;
8642 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8643
8644 ani_hdr = NLMSG_DATA(nlh);
8645 ani_hdr->type = type;
8646
8647 switch(type) {
8648 case WLAN_SVC_SAP_RESTART_IND:
8649 ani_hdr->length = 0;
8650 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8651 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8652 break;
8653 default:
8654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8655 "Attempt to send unknown nlink message %d", type);
8656 kfree_skb(skb);
8657 return;
8658 }
8659
8660 nl_srv_bcast(skb);
8661
8662 return;
8663}
8664
8665
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008666
8667/**---------------------------------------------------------------------------
8668
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308669 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8670
8671 \param - pHddCtx - Pointer to the hdd context
8672
8673 \return - true if hardware supports 5GHz
8674
8675 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308676boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308677{
8678 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8679 * then hardware support 5Ghz.
8680 */
8681 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8682 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308683 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308684 return true;
8685 }
8686 else
8687 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308689 __func__);
8690 return false;
8691 }
8692}
8693
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308694/**---------------------------------------------------------------------------
8695
8696 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8697 generate function
8698
8699 This is generate the random mac address for WLAN interface
8700
8701 \param - pHddCtx - Pointer to HDD context
8702 idx - Start interface index to get auto
8703 generated mac addr.
8704 mac_addr - Mac address
8705
8706 \return - 0 for success, < 0 for failure
8707
8708 --------------------------------------------------------------------------*/
8709
8710static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8711 int idx, v_MACADDR_t mac_addr)
8712{
8713 int i;
8714 unsigned int serialno;
8715 serialno = wcnss_get_serial_number();
8716
8717 if (0 != serialno)
8718 {
8719 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8720 bytes of the serial number that can be used to generate
8721 the other 3 bytes of the MAC address. Mask off all but
8722 the lower 3 bytes (this will also make sure we don't
8723 overflow in the next step) */
8724 serialno &= 0x00FFFFFF;
8725
8726 /* we need a unique address for each session */
8727 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8728
8729 /* autogen other Mac addresses */
8730 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8731 {
8732 /* start with the entire default address */
8733 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8734 /* then replace the lower 3 bytes */
8735 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8736 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8737 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8738
8739 serialno++;
8740 hddLog(VOS_TRACE_LEVEL_ERROR,
8741 "%s: Derived Mac Addr: "
8742 MAC_ADDRESS_STR, __func__,
8743 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8744 }
8745
8746 }
8747 else
8748 {
8749 hddLog(LOGE, FL("Failed to Get Serial NO"));
8750 return -1;
8751 }
8752 return 0;
8753}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308754
8755/**---------------------------------------------------------------------------
8756
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308757 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8758 completed to flush out the scan results
8759
8760 11d scan is done during driver load and is a passive scan on all
8761 channels supported by the device, 11d scans may find some APs on
8762 frequencies which are forbidden to be used in the regulatory domain
8763 the device is operating in. If these APs are notified to the supplicant
8764 it may try to connect to these APs, thus flush out all the scan results
8765 which are present in SME after 11d scan is done.
8766
8767 \return - eHalStatus
8768
8769 --------------------------------------------------------------------------*/
8770static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8771 tANI_U32 scanId, eCsrScanStatus status)
8772{
8773 ENTER();
8774
8775 sme_ScanFlushResult(halHandle, 0);
8776
8777 EXIT();
8778
8779 return eHAL_STATUS_SUCCESS;
8780}
8781
8782/**---------------------------------------------------------------------------
8783
Jeff Johnson295189b2012-06-20 16:38:30 -07008784 \brief hdd_wlan_startup() - HDD init function
8785
8786 This is the driver startup code executed once a WLAN device has been detected
8787
8788 \param - dev - Pointer to the underlying device
8789
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008790 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008791
8792 --------------------------------------------------------------------------*/
8793
8794int hdd_wlan_startup(struct device *dev )
8795{
8796 VOS_STATUS status;
8797 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008798 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 hdd_context_t *pHddCtx = NULL;
8800 v_CONTEXT_t pVosContext= NULL;
8801#ifdef WLAN_BTAMP_FEATURE
8802 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8803 WLANBAP_ConfigType btAmpConfig;
8804 hdd_config_t *pConfig;
8805#endif
8806 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008807 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308808 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008809
8810 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 /*
8812 * cfg80211: wiphy allocation
8813 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308814 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008815
8816 if(wiphy == NULL)
8817 {
8818 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008819 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008820 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008821 pHddCtx = wiphy_priv(wiphy);
8822
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 //Initialize the adapter context to zeros.
8824 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8825
Jeff Johnson295189b2012-06-20 16:38:30 -07008826 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308828 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008829
8830 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8831
8832 /*Get vos context here bcoz vos_open requires it*/
8833 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8834
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008835 if(pVosContext == NULL)
8836 {
8837 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8838 goto err_free_hdd_context;
8839 }
8840
Jeff Johnson295189b2012-06-20 16:38:30 -07008841 //Save the Global VOSS context in adapter context for future.
8842 pHddCtx->pvosContext = pVosContext;
8843
8844 //Save the adapter context in global context for future.
8845 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8846
Jeff Johnson295189b2012-06-20 16:38:30 -07008847 pHddCtx->parent_dev = dev;
8848
8849 init_completion(&pHddCtx->full_pwr_comp_var);
8850 init_completion(&pHddCtx->standby_comp_var);
8851 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008852 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008853 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308854 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308855 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008856
8857#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008858 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008859#else
8860 init_completion(&pHddCtx->driver_crda_req);
8861#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008862
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308863 spin_lock_init(&pHddCtx->schedScan_lock);
8864
Jeff Johnson295189b2012-06-20 16:38:30 -07008865 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8866
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308867#ifdef FEATURE_WLAN_TDLS
8868 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8869 * invoked by other instances also) to protect the concurrent
8870 * access for the Adapters by TDLS module.
8871 */
8872 mutex_init(&pHddCtx->tdls_lock);
8873#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05308874 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Agarwal Ashish1f422872014-07-22 00:11:55 +05308875 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308876
Agarwal Ashish1f422872014-07-22 00:11:55 +05308877 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 // Load all config first as TL config is needed during vos_open
8879 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8880 if(pHddCtx->cfg_ini == NULL)
8881 {
8882 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8883 goto err_free_hdd_context;
8884 }
8885
8886 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8887
8888 // Read and parse the qcom_cfg.ini file
8889 status = hdd_parse_config_ini( pHddCtx );
8890 if ( VOS_STATUS_SUCCESS != status )
8891 {
8892 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8893 __func__, WLAN_INI_FILE);
8894 goto err_config;
8895 }
Arif Hussaind5218912013-12-05 01:10:55 -08008896#ifdef MEMORY_DEBUG
8897 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8898 vos_mem_init();
8899
8900 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8901 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8902#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008903
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308904 /* INI has been read, initialise the configuredMcastBcastFilter with
8905 * INI value as this will serve as the default value
8906 */
8907 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8908 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8909 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308910
8911 if (false == hdd_is_5g_supported(pHddCtx))
8912 {
8913 //5Ghz is not supported.
8914 if (1 != pHddCtx->cfg_ini->nBandCapability)
8915 {
8916 hddLog(VOS_TRACE_LEVEL_INFO,
8917 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8918 pHddCtx->cfg_ini->nBandCapability = 1;
8919 }
8920 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308921
8922 /* If SNR Monitoring is enabled, FW has to parse all beacons
8923 * for calcaluting and storing the average SNR, so set Nth beacon
8924 * filter to 1 to enable FW to parse all the beaocons
8925 */
8926 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8927 {
8928 /* The log level is deliberately set to WARN as overriding
8929 * nthBeaconFilter to 1 will increase power cosumption and this
8930 * might just prove helpful to detect the power issue.
8931 */
8932 hddLog(VOS_TRACE_LEVEL_WARN,
8933 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8934 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8935 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308937 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008938 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008939 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008941 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8942 {
8943 hddLog(VOS_TRACE_LEVEL_FATAL,
8944 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8945 goto err_config;
8946 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008948
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008949 // Update VOS trace levels based upon the cfg.ini
8950 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8951 pHddCtx->cfg_ini->vosTraceEnableBAP);
8952 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8953 pHddCtx->cfg_ini->vosTraceEnableTL);
8954 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8955 pHddCtx->cfg_ini->vosTraceEnableWDI);
8956 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8957 pHddCtx->cfg_ini->vosTraceEnableHDD);
8958 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8959 pHddCtx->cfg_ini->vosTraceEnableSME);
8960 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8961 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308962 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8963 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008964 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8965 pHddCtx->cfg_ini->vosTraceEnableWDA);
8966 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8967 pHddCtx->cfg_ini->vosTraceEnableSYS);
8968 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8969 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008970 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8971 pHddCtx->cfg_ini->vosTraceEnableSAP);
8972 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8973 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008974
Jeff Johnson295189b2012-06-20 16:38:30 -07008975 // Update WDI trace levels based upon the cfg.ini
8976 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8977 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8978 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8979 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8980 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8981 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8982 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8983 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008984
Jeff Johnson88ba7742013-02-27 14:36:02 -08008985 if (VOS_FTM_MODE == hdd_get_conparam())
8986 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8988 {
8989 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8990 goto err_free_hdd_context;
8991 }
8992 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308993
8994 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008995 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008996 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008997
Jeff Johnson88ba7742013-02-27 14:36:02 -08008998 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9000 {
9001 status = vos_watchdog_open(pVosContext,
9002 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9003
9004 if(!VOS_IS_STATUS_SUCCESS( status ))
9005 {
9006 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309007 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009008 }
9009 }
9010
9011 pHddCtx->isLogpInProgress = FALSE;
9012 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9013
Amar Singhala49cbc52013-10-08 18:37:44 -07009014#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009015 /* initialize the NV module. This is required so that
9016 we can initialize the channel information in wiphy
9017 from the NV.bin data. The channel information in
9018 wiphy needs to be initialized before wiphy registration */
9019
9020 status = vos_nv_open();
9021 if (!VOS_IS_STATUS_SUCCESS(status))
9022 {
9023 /* NV module cannot be initialized */
9024 hddLog( VOS_TRACE_LEVEL_FATAL,
9025 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309026 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009027 }
9028
9029 status = vos_init_wiphy_from_nv_bin();
9030 if (!VOS_IS_STATUS_SUCCESS(status))
9031 {
9032 /* NV module cannot be initialized */
9033 hddLog( VOS_TRACE_LEVEL_FATAL,
9034 "%s: vos_init_wiphy failed", __func__);
9035 goto err_vos_nv_close;
9036 }
9037
Amar Singhala49cbc52013-10-08 18:37:44 -07009038#endif
9039
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309040 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009041 if ( !VOS_IS_STATUS_SUCCESS( status ))
9042 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009043 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309044 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009045 }
9046
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9048
9049 if ( NULL == pHddCtx->hHal )
9050 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009051 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 goto err_vosclose;
9053 }
9054
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009055 status = vos_preStart( pHddCtx->pvosContext );
9056 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9057 {
9058 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309059 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009060 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009061
Arif Hussaineaf68602013-12-30 23:10:44 -08009062 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9063 {
9064 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9065 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9066 __func__, enable_dfs_chan_scan);
9067 }
9068 if (0 == enable_11d || 1 == enable_11d)
9069 {
9070 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9071 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9072 __func__, enable_11d);
9073 }
9074
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009075 /* Note that the vos_preStart() sequence triggers the cfg download.
9076 The cfg download must occur before we update the SME config
9077 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009078 status = hdd_set_sme_config( pHddCtx );
9079
9080 if ( VOS_STATUS_SUCCESS != status )
9081 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009082 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309083 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009084 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009085
Jeff Johnson295189b2012-06-20 16:38:30 -07009086 /* In the integrated architecture we update the configuration from
9087 the INI file and from NV before vOSS has been started so that
9088 the final contents are available to send down to the cCPU */
9089
9090 // Apply the cfg.ini to cfg.dat
9091 if (FALSE == hdd_update_config_dat(pHddCtx))
9092 {
9093 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309094 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009095 }
9096
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309097 // Get mac addr from platform driver
9098 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9099
9100 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009101 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309102 /* Store the mac addr for first interface */
9103 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9104
9105 hddLog(VOS_TRACE_LEVEL_ERROR,
9106 "%s: WLAN Mac Addr: "
9107 MAC_ADDRESS_STR, __func__,
9108 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9109
9110 /* Here, passing Arg2 as 1 because we do not want to change the
9111 last 3 bytes (means non OUI bytes) of first interface mac
9112 addr.
9113 */
9114 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9115 {
9116 hddLog(VOS_TRACE_LEVEL_ERROR,
9117 "%s: Failed to generate wlan interface mac addr "
9118 "using MAC from ini file ", __func__);
9119 }
9120 }
9121 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9122 {
9123 // Apply the NV to cfg.dat
9124 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009125#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9126 /* There was not a valid set of MAC Addresses in NV. See if the
9127 default addresses were modified by the cfg.ini settings. If so,
9128 we'll use them, but if not, we'll autogenerate a set of MAC
9129 addresses based upon the device serial number */
9130
9131 static const v_MACADDR_t default_address =
9132 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009133
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309134 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9135 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009136 {
9137 /* cfg.ini has the default address, invoke autogen logic */
9138
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309139 /* Here, passing Arg2 as 0 because we want to change the
9140 last 3 bytes (means non OUI bytes) of all the interfaces
9141 mac addr.
9142 */
9143 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9144 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309146 hddLog(VOS_TRACE_LEVEL_ERROR,
9147 "%s: Failed to generate wlan interface mac addr "
9148 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9149 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009151 }
9152 else
9153#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9154 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009155 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 "%s: Invalid MAC address in NV, using MAC from ini file "
9157 MAC_ADDRESS_STR, __func__,
9158 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9159 }
9160 }
9161 {
9162 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309163
9164 /* Set the MAC Address Currently this is used by HAL to
9165 * add self sta. Remove this once self sta is added as
9166 * part of session open.
9167 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009168 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9169 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9170 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309171
Jeff Johnson295189b2012-06-20 16:38:30 -07009172 if (!HAL_STATUS_SUCCESS( halStatus ))
9173 {
9174 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9175 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309176 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 }
9178 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009179
9180 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9181 Note: Firmware image will be read and downloaded inside vos_start API */
9182 status = vos_start( pHddCtx->pvosContext );
9183 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9184 {
9185 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309186 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009187 }
9188
Leo Chang6cec3e22014-01-21 15:33:49 -08009189#ifdef FEATURE_WLAN_CH_AVOID
9190 /* Plug in avoid channel notification callback
9191 * This should happen before ADD_SELF_STA
9192 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309193
9194 /* check the Channel Avoidance is enabled */
9195 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9196 {
9197 sme_AddChAvoidCallback(pHddCtx->hHal,
9198 hdd_hostapd_ch_avoid_cb);
9199 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009200#endif /* FEATURE_WLAN_CH_AVOID */
9201
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009202 /* Exchange capability info between Host and FW and also get versioning info from FW */
9203 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009204
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309205#ifdef CONFIG_ENABLE_LINUX_REG
9206 status = wlan_hdd_init_channels(pHddCtx);
9207 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9208 {
9209 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9210 __func__);
9211 goto err_vosstop;
9212 }
9213#endif
9214
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 status = hdd_post_voss_start_config( pHddCtx );
9216 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9217 {
9218 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9219 __func__);
9220 goto err_vosstop;
9221 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009222
9223#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309224 wlan_hdd_cfg80211_update_reg_info( wiphy );
9225
9226 /* registration of wiphy dev with cfg80211 */
9227 if (0 > wlan_hdd_cfg80211_register(wiphy))
9228 {
9229 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9230 goto err_vosstop;
9231 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009232#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009233
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309234#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309235 /* registration of wiphy dev with cfg80211 */
9236 if (0 > wlan_hdd_cfg80211_register(wiphy))
9237 {
9238 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9239 goto err_vosstop;
9240 }
9241
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309242 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309243 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9244 {
9245 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9246 __func__);
9247 goto err_unregister_wiphy;
9248 }
9249#endif
9250
Jeff Johnson295189b2012-06-20 16:38:30 -07009251 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9252 {
9253 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9254 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9255 }
9256 else
9257 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9259 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9260 if (pAdapter != NULL)
9261 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309262 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009263 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309264 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9265 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9266 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009267
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309268 /* Generate the P2P Device Address. This consists of the device's
9269 * primary MAC address with the locally administered bit set.
9270 */
9271 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009272 }
9273 else
9274 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309275 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9276 if (p2p_dev_addr != NULL)
9277 {
9278 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9279 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9280 }
9281 else
9282 {
9283 hddLog(VOS_TRACE_LEVEL_FATAL,
9284 "%s: Failed to allocate mac_address for p2p_device",
9285 __func__);
9286 goto err_close_adapter;
9287 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009288 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009289
9290 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9291 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9292 if ( NULL == pP2pAdapter )
9293 {
9294 hddLog(VOS_TRACE_LEVEL_FATAL,
9295 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009296 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009297 goto err_close_adapter;
9298 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009299 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009300 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009301
9302 if( pAdapter == NULL )
9303 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009304 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9305 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009307
Arif Hussain66559122013-11-21 10:11:40 -08009308 if (country_code)
9309 {
9310 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009311 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009312 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9313#ifndef CONFIG_ENABLE_LINUX_REG
9314 hdd_checkandupdate_phymode(pAdapter, country_code);
9315#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009316 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9317 (void *)(tSmeChangeCountryCallback)
9318 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009319 country_code,
9320 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309321 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009322 if (eHAL_STATUS_SUCCESS == ret)
9323 {
Arif Hussaincb607082013-12-20 11:57:42 -08009324 ret = wait_for_completion_interruptible_timeout(
9325 &pAdapter->change_country_code,
9326 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9327
9328 if (0 >= ret)
9329 {
9330 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9331 "%s: SME while setting country code timed out", __func__);
9332 }
Arif Hussain66559122013-11-21 10:11:40 -08009333 }
9334 else
9335 {
Arif Hussaincb607082013-12-20 11:57:42 -08009336 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9337 "%s: SME Change Country code from module param fail ret=%d",
9338 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009339 }
9340 }
9341
Jeff Johnson295189b2012-06-20 16:38:30 -07009342#ifdef WLAN_BTAMP_FEATURE
9343 vStatus = WLANBAP_Open(pVosContext);
9344 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9345 {
9346 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9347 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009348 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 }
9350
9351 vStatus = BSL_Init(pVosContext);
9352 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9353 {
9354 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9355 "%s: Failed to Init BSL",__func__);
9356 goto err_bap_close;
9357 }
9358 vStatus = WLANBAP_Start(pVosContext);
9359 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9360 {
9361 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9362 "%s: Failed to start TL",__func__);
9363 goto err_bap_close;
9364 }
9365
9366 pConfig = pHddCtx->cfg_ini;
9367 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9368 status = WLANBAP_SetConfig(&btAmpConfig);
9369
9370#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009371
Mihir Shete9c238772014-10-15 14:35:16 +05309372 /*
9373 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9374 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9375 * which is greater than 0xf. So the below check is safe to make
9376 * sure that there is no entry for UapsdMask in the ini
9377 */
9378 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9379 {
9380 if(IS_DYNAMIC_WMM_PS_ENABLED)
9381 {
9382 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9383 __func__);
9384 pHddCtx->cfg_ini->UapsdMask =
9385 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9386 }
9387 else
9388 {
9389 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9390 __func__);
9391 pHddCtx->cfg_ini->UapsdMask =
9392 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9393 }
9394 }
9395
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009396#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9397 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9398 {
9399 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9400 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9401 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9402 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9403 }
9404#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009405
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309406 wlan_hdd_tdls_init(pHddCtx);
9407
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309408 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9409
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 /* Register with platform driver as client for Suspend/Resume */
9411 status = hddRegisterPmOps(pHddCtx);
9412 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9413 {
9414 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9415#ifdef WLAN_BTAMP_FEATURE
9416 goto err_bap_stop;
9417#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009418 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009419#endif //WLAN_BTAMP_FEATURE
9420 }
9421
Yue Ma0d4891e2013-08-06 17:01:45 -07009422 /* Open debugfs interface */
9423 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9424 {
9425 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9426 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009427 }
9428
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 /* Register TM level change handler function to the platform */
9430 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9431 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9432 {
9433 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9434 goto err_unregister_pmops;
9435 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009436
9437 /* register for riva power on lock to platform driver */
9438 if (req_riva_power_on_lock("wlan"))
9439 {
9440 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9441 __func__);
9442 goto err_unregister_pmops;
9443 }
9444
Jeff Johnson295189b2012-06-20 16:38:30 -07009445 // register net device notifier for device change notification
9446 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9447
9448 if(ret < 0)
9449 {
9450 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9451 goto err_free_power_on_lock;
9452 }
9453
9454 //Initialize the nlink service
9455 if(nl_srv_init() != 0)
9456 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309457 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009458 goto err_reg_netdev;
9459 }
9460
Leo Chang4ce1cc52013-10-21 18:27:15 -07009461#ifdef WLAN_KD_READY_NOTIFIER
9462 pHddCtx->kd_nl_init = 1;
9463#endif /* WLAN_KD_READY_NOTIFIER */
9464
Jeff Johnson295189b2012-06-20 16:38:30 -07009465 //Initialize the BTC service
9466 if(btc_activate_service(pHddCtx) != 0)
9467 {
9468 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9469 goto err_nl_srv;
9470 }
9471
9472#ifdef PTT_SOCK_SVC_ENABLE
9473 //Initialize the PTT service
9474 if(ptt_sock_activate_svc(pHddCtx) != 0)
9475 {
9476 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9477 goto err_nl_srv;
9478 }
9479#endif
9480
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309481#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9482 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9483 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309484 if(wlan_logging_sock_activate_svc(
9485 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9486 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9487 {
9488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9489 " failed", __func__);
9490 goto err_nl_srv;
9491 }
9492 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9493 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309494 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9495 pHddCtx->cfg_ini->gEnableDebugLog =
9496 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309497 }
9498#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009500 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009502 /* Action frame registered in one adapter which will
9503 * applicable to all interfaces
9504 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309505 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009507
9508 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309509 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009510
Jeff Johnson295189b2012-06-20 16:38:30 -07009511
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009512#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009513#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9514 /* Initialize the wake lcok */
9515 wake_lock_init(&pHddCtx->rx_wake_lock,
9516 WAKE_LOCK_SUSPEND,
9517 "qcom_rx_wakelock");
9518#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009519 /* Initialize the wake lcok */
9520 wake_lock_init(&pHddCtx->sap_wake_lock,
9521 WAKE_LOCK_SUSPEND,
9522 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009523#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009524
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009525 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9526 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009527
Katya Nigam5c306ea2014-06-19 15:39:54 +05309528 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9530 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309531
9532#ifdef FEATURE_WLAN_SCAN_PNO
9533 /*SME must send channel update configuration to RIVA*/
9534 sme_UpdateChannelConfig(pHddCtx->hHal);
9535#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309536 /* Send the update default channel list to the FW*/
9537 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309538#ifndef CONFIG_ENABLE_LINUX_REG
9539 /*updating wiphy so that regulatory user hints can be processed*/
9540 if (wiphy)
9541 {
9542 regulatory_hint(wiphy, "00");
9543 }
9544#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009545 // Initialize the restart logic
9546 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309547
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009548 //Register the traffic monitor timer now
9549 if ( pHddCtx->cfg_ini->dynSplitscan)
9550 {
9551 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9552 VOS_TIMER_TYPE_SW,
9553 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9554 (void *)pHddCtx);
9555 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309556#ifdef WLAN_FEATURE_EXTSCAN
9557 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9558 wlan_hdd_cfg80211_extscan_callback,
9559 pHddCtx);
9560#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009561 goto success;
9562
9563err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009564#ifdef WLAN_KD_READY_NOTIFIER
9565 nl_srv_exit(pHddCtx->ptt_pid);
9566#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009568#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009569err_reg_netdev:
9570 unregister_netdevice_notifier(&hdd_netdev_notifier);
9571
9572err_free_power_on_lock:
9573 free_riva_power_on_lock("wlan");
9574
9575err_unregister_pmops:
9576 hddDevTmUnregisterNotifyCallback(pHddCtx);
9577 hddDeregisterPmOps(pHddCtx);
9578
Yue Ma0d4891e2013-08-06 17:01:45 -07009579 hdd_debugfs_exit(pHddCtx);
9580
Jeff Johnson295189b2012-06-20 16:38:30 -07009581#ifdef WLAN_BTAMP_FEATURE
9582err_bap_stop:
9583 WLANBAP_Stop(pVosContext);
9584#endif
9585
9586#ifdef WLAN_BTAMP_FEATURE
9587err_bap_close:
9588 WLANBAP_Close(pVosContext);
9589#endif
9590
Jeff Johnson295189b2012-06-20 16:38:30 -07009591err_close_adapter:
9592 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309593#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309594err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309595#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309596 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009597err_vosstop:
9598 vos_stop(pVosContext);
9599
Amar Singhala49cbc52013-10-08 18:37:44 -07009600err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 status = vos_sched_close( pVosContext );
9602 if (!VOS_IS_STATUS_SUCCESS(status)) {
9603 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9604 "%s: Failed to close VOSS Scheduler", __func__);
9605 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9606 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009607 vos_close(pVosContext );
9608
Amar Singhal0a402232013-10-11 20:57:16 -07009609err_vos_nv_close:
9610
c_hpothue6a36282014-03-19 12:27:38 +05309611#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009612 vos_nv_close();
9613
c_hpothu70f8d812014-03-22 22:59:23 +05309614#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009615
9616err_wdclose:
9617 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9618 vos_watchdog_close(pVosContext);
9619
Jeff Johnson295189b2012-06-20 16:38:30 -07009620err_config:
9621 kfree(pHddCtx->cfg_ini);
9622 pHddCtx->cfg_ini= NULL;
9623
9624err_free_hdd_context:
9625 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 wiphy_free(wiphy) ;
9627 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 VOS_BUG(1);
9629
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009630 if (hdd_is_ssr_required())
9631 {
9632 /* WDI timeout had happened during load, so SSR is needed here */
9633 subsystem_restart("wcnss");
9634 msleep(5000);
9635 }
9636 hdd_set_ssr_required (VOS_FALSE);
9637
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009638 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009639
9640success:
9641 EXIT();
9642 return 0;
9643}
9644
9645/**---------------------------------------------------------------------------
9646
Jeff Johnson32d95a32012-09-10 13:15:23 -07009647 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009648
Jeff Johnson32d95a32012-09-10 13:15:23 -07009649 This is the driver entry point - called in different timeline depending
9650 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009651
9652 \param - None
9653
9654 \return - 0 for success, non zero for failure
9655
9656 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009657static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009658{
9659 VOS_STATUS status;
9660 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 struct device *dev = NULL;
9662 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009663#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9664 int max_retries = 0;
9665#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009666
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309667#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9668 wlan_logging_sock_init_svc();
9669#endif
9670
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 ENTER();
9672
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009673#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009674 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009675#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009676
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309677 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009678 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9679 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9680
Jeff Johnson295189b2012-06-20 16:38:30 -07009681#ifdef ANI_BUS_TYPE_PCI
9682
9683 dev = wcnss_wlan_get_device();
9684
9685#endif // ANI_BUS_TYPE_PCI
9686
9687#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009688
9689#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9690 /* wait until WCNSS driver downloads NV */
9691 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9692 msleep(1000);
9693 }
9694 if (max_retries >= 5) {
9695 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309696#ifdef WLAN_OPEN_SOURCE
9697 wake_lock_destroy(&wlan_wake_lock);
9698#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309699
9700#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9701 wlan_logging_sock_deinit_svc();
9702#endif
9703
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009704 return -ENODEV;
9705 }
9706#endif
9707
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 dev = wcnss_wlan_get_device();
9709#endif // ANI_BUS_TYPE_PLATFORM
9710
9711
9712 do {
9713 if (NULL == dev) {
9714 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9715 ret_status = -1;
9716 break;
9717 }
9718
Jeff Johnson295189b2012-06-20 16:38:30 -07009719#ifdef TIMER_MANAGER
9720 vos_timer_manager_init();
9721#endif
9722
9723 /* Preopen VOSS so that it is ready to start at least SAL */
9724 status = vos_preOpen(&pVosContext);
9725
9726 if (!VOS_IS_STATUS_SUCCESS(status))
9727 {
9728 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9729 ret_status = -1;
9730 break;
9731 }
9732
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009733#ifndef MODULE
9734 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9735 */
9736 hdd_set_conparam((v_UINT_t)con_mode);
9737#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009738
9739 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009740 if (hdd_wlan_startup(dev))
9741 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009742 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009743 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009744 vos_preClose( &pVosContext );
9745 ret_status = -1;
9746 break;
9747 }
9748
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 } while (0);
9750
9751 if (0 != ret_status)
9752 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009753#ifdef TIMER_MANAGER
9754 vos_timer_exit();
9755#endif
9756#ifdef MEMORY_DEBUG
9757 vos_mem_exit();
9758#endif
9759
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009760#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009762#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309763
9764#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9765 wlan_logging_sock_deinit_svc();
9766#endif
9767
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9769 }
9770 else
9771 {
9772 //Send WLAN UP indication to Nlink Service
9773 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9774
9775 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 }
9777
9778 EXIT();
9779
9780 return ret_status;
9781}
9782
Jeff Johnson32d95a32012-09-10 13:15:23 -07009783/**---------------------------------------------------------------------------
9784
9785 \brief hdd_module_init() - Init Function
9786
9787 This is the driver entry point (invoked when module is loaded using insmod)
9788
9789 \param - None
9790
9791 \return - 0 for success, non zero for failure
9792
9793 --------------------------------------------------------------------------*/
9794#ifdef MODULE
9795static int __init hdd_module_init ( void)
9796{
9797 return hdd_driver_init();
9798}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009799#else /* #ifdef MODULE */
9800static int __init hdd_module_init ( void)
9801{
9802 /* Driver initialization is delayed to fwpath_changed_handler */
9803 return 0;
9804}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009805#endif /* #ifdef MODULE */
9806
Jeff Johnson295189b2012-06-20 16:38:30 -07009807
9808/**---------------------------------------------------------------------------
9809
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009810 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009811
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009812 This is the driver exit point (invoked when module is unloaded using rmmod
9813 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009814
9815 \param - None
9816
9817 \return - None
9818
9819 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009820static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009821{
9822 hdd_context_t *pHddCtx = NULL;
9823 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309824 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309825 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009826
9827 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9828
9829 //Get the global vos context
9830 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9831
9832 if(!pVosContext)
9833 {
9834 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9835 goto done;
9836 }
9837
9838 //Get the HDD context.
9839 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9840
9841 if(!pHddCtx)
9842 {
9843 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9844 }
9845 else
9846 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309847 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9848
c_hpothu8adb97b2014-12-08 19:38:20 +05309849 if ((pHddCtx->isLogpInProgress) &&
9850 (FALSE == vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309851 {
c_hpothu8adb97b2014-12-08 19:38:20 +05309852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9853 "%s:SSR in Progress; block rmmod !!!", __func__);
9854 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9855 msecs_to_jiffies(30000));
9856 if(!rc)
9857 {
9858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9859 "%s:SSR timedout, fatal error", __func__);
9860 VOS_BUG(0);
9861 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309862 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009863
c_hpothu8adb97b2014-12-08 19:38:20 +05309864 rtnl_lock();
9865 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
9866 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9867 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -07009868
c_hpothu8adb97b2014-12-08 19:38:20 +05309869 /* Driver Need to send country code 00 in below condition
9870 * 1) If gCountryCodePriority is set to 1; and last country
9871 * code set is through 11d. This needs to be done in case
9872 * when NV country code is 00.
9873 * This Needs to be done as when kernel store last country
9874 * code and if stored country code is not through 11d,
9875 * in sme_HandleChangeCountryCodeByUser we will disable 11d
9876 * in next load/unload as soon as we get any country through
9877 * 11d. In sme_HandleChangeCountryCodeByUser
9878 * pMsg->countryCode will be last countryCode and
9879 * pMac->scan.countryCode11d will be country through 11d so
9880 * due to mismatch driver will disable 11d.
9881 *
9882 */
Agarwal Ashish8db39882014-07-30 21:56:07 +05309883
c_hpothu8adb97b2014-12-08 19:38:20 +05309884 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309885 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +05309886 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +05309887 {
9888 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309889 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +05309890 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9891 }
Agarwal Ashish5e414792014-06-08 15:25:23 +05309892
c_hpothu8adb97b2014-12-08 19:38:20 +05309893 //Do all the cleanup before deregistering the driver
9894 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009895 }
9896
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 vos_preClose( &pVosContext );
9898
9899#ifdef TIMER_MANAGER
9900 vos_timer_exit();
9901#endif
9902#ifdef MEMORY_DEBUG
9903 vos_mem_exit();
9904#endif
9905
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309906#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9907 wlan_logging_sock_deinit_svc();
9908#endif
9909
Jeff Johnson295189b2012-06-20 16:38:30 -07009910done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009911#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009913#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309914
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9916}
9917
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009918/**---------------------------------------------------------------------------
9919
9920 \brief hdd_module_exit() - Exit function
9921
9922 This is the driver exit point (invoked when module is unloaded using rmmod)
9923
9924 \param - None
9925
9926 \return - None
9927
9928 --------------------------------------------------------------------------*/
9929static void __exit hdd_module_exit(void)
9930{
9931 hdd_driver_exit();
9932}
9933
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009934#ifdef MODULE
9935static int fwpath_changed_handler(const char *kmessage,
9936 struct kernel_param *kp)
9937{
Jeff Johnson76052702013-04-16 13:55:05 -07009938 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009939}
9940
9941static int con_mode_handler(const char *kmessage,
9942 struct kernel_param *kp)
9943{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009944 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009945}
9946#else /* #ifdef MODULE */
9947/**---------------------------------------------------------------------------
9948
Jeff Johnson76052702013-04-16 13:55:05 -07009949 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009950
Jeff Johnson76052702013-04-16 13:55:05 -07009951 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009952 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009953 - invoked when module parameter fwpath is modified from userspace to signal
9954 initializing the WLAN driver or when con_mode is modified from userspace
9955 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009956
9957 \return - 0 for success, non zero for failure
9958
9959 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009960static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009961{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009962 int ret_status;
9963
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009964 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009965 ret_status = hdd_driver_init();
9966 wlan_hdd_inited = ret_status ? 0 : 1;
9967 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009968 }
9969
9970 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009971
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009972 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009973
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009974 ret_status = hdd_driver_init();
9975 wlan_hdd_inited = ret_status ? 0 : 1;
9976 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009977}
9978
Jeff Johnson295189b2012-06-20 16:38:30 -07009979/**---------------------------------------------------------------------------
9980
Jeff Johnson76052702013-04-16 13:55:05 -07009981 \brief fwpath_changed_handler() - Handler Function
9982
9983 Handle changes to the fwpath parameter
9984
9985 \return - 0 for success, non zero for failure
9986
9987 --------------------------------------------------------------------------*/
9988static int fwpath_changed_handler(const char *kmessage,
9989 struct kernel_param *kp)
9990{
9991 int ret;
9992
9993 ret = param_set_copystring(kmessage, kp);
9994 if (0 == ret)
9995 ret = kickstart_driver();
9996 return ret;
9997}
9998
9999/**---------------------------------------------------------------------------
10000
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010001 \brief con_mode_handler() -
10002
10003 Handler function for module param con_mode when it is changed by userspace
10004 Dynamically linked - do nothing
10005 Statically linked - exit and init driver, as in rmmod and insmod
10006
Jeff Johnson76052702013-04-16 13:55:05 -070010007 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010008
Jeff Johnson76052702013-04-16 13:55:05 -070010009 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010010
10011 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010012static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010013{
Jeff Johnson76052702013-04-16 13:55:05 -070010014 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010015
Jeff Johnson76052702013-04-16 13:55:05 -070010016 ret = param_set_int(kmessage, kp);
10017 if (0 == ret)
10018 ret = kickstart_driver();
10019 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010020}
10021#endif /* #ifdef MODULE */
10022
10023/**---------------------------------------------------------------------------
10024
Jeff Johnson295189b2012-06-20 16:38:30 -070010025 \brief hdd_get_conparam() -
10026
10027 This is the driver exit point (invoked when module is unloaded using rmmod)
10028
10029 \param - None
10030
10031 \return - tVOS_CON_MODE
10032
10033 --------------------------------------------------------------------------*/
10034tVOS_CON_MODE hdd_get_conparam ( void )
10035{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010036#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010038#else
10039 return (tVOS_CON_MODE)curr_con_mode;
10040#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010041}
10042void hdd_set_conparam ( v_UINT_t newParam )
10043{
10044 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010045#ifndef MODULE
10046 curr_con_mode = con_mode;
10047#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010048}
10049/**---------------------------------------------------------------------------
10050
10051 \brief hdd_softap_sta_deauth() - function
10052
10053 This to take counter measure to handle deauth req from HDD
10054
10055 \param - pAdapter - Pointer to the HDD
10056
10057 \param - enable - boolean value
10058
10059 \return - None
10060
10061 --------------------------------------------------------------------------*/
10062
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010063VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10064 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010065{
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010067 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010068
10069 ENTER();
10070
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010071 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10072 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010073
10074 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010075 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010076 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010077
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010078 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010079
10080 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010081 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010082}
10083
10084/**---------------------------------------------------------------------------
10085
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010086 \brief hdd_del_all_sta() - function
10087
10088 This function removes all the stations associated on stopping AP/P2P GO.
10089
10090 \param - pAdapter - Pointer to the HDD
10091
10092 \return - None
10093
10094 --------------------------------------------------------------------------*/
10095
10096int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10097{
10098 v_U16_t i;
10099 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010100 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10101 ptSapContext pSapCtx = NULL;
10102 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10103 if(pSapCtx == NULL){
10104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10105 FL("psapCtx is NULL"));
10106 return 1;
10107 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010108 ENTER();
10109
10110 hddLog(VOS_TRACE_LEVEL_INFO,
10111 "%s: Delete all STAs associated.",__func__);
10112 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10113 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10114 )
10115 {
10116 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10117 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010118 if ((pSapCtx->aStaInfo[i].isUsed) &&
10119 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010120 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010121 struct tagCsrDelStaParams delStaParams;
10122
10123 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010124 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010125 eCsrForcedDeauthSta, SIR_MAC_MGMT_DEAUTH >> 4,
10126 &delStaParams);
10127 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010128 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010129 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010130 }
10131 }
10132 }
10133
10134 EXIT();
10135 return 0;
10136}
10137
10138/**---------------------------------------------------------------------------
10139
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 \brief hdd_softap_sta_disassoc() - function
10141
10142 This to take counter measure to handle deauth req from HDD
10143
10144 \param - pAdapter - Pointer to the HDD
10145
10146 \param - enable - boolean value
10147
10148 \return - None
10149
10150 --------------------------------------------------------------------------*/
10151
10152void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10153{
10154 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10155
10156 ENTER();
10157
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010158 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010159
10160 //Ignore request to disassoc bcmc station
10161 if( pDestMacAddress[0] & 0x1 )
10162 return;
10163
10164 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10165}
10166
10167void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10168{
10169 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10170
10171 ENTER();
10172
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010173 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010174
10175 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10176}
10177
Jeff Johnson295189b2012-06-20 16:38:30 -070010178/**---------------------------------------------------------------------------
10179 *
10180 * \brief hdd_get__concurrency_mode() -
10181 *
10182 *
10183 * \param - None
10184 *
10185 * \return - CONCURRENCY MODE
10186 *
10187 * --------------------------------------------------------------------------*/
10188tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10189{
10190 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10191 hdd_context_t *pHddCtx;
10192
10193 if (NULL != pVosContext)
10194 {
10195 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10196 if (NULL != pHddCtx)
10197 {
10198 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10199 }
10200 }
10201
10202 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010203 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 return VOS_STA;
10205}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010206v_BOOL_t
10207wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10208{
10209 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010210
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010211 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10212 if (pAdapter == NULL)
10213 {
10214 hddLog(VOS_TRACE_LEVEL_INFO,
10215 FL("GO doesn't exist"));
10216 return TRUE;
10217 }
10218 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10219 {
10220 hddLog(VOS_TRACE_LEVEL_INFO,
10221 FL("GO started"));
10222 return TRUE;
10223 }
10224 else
10225 /* wait till GO changes its interface to p2p device */
10226 hddLog(VOS_TRACE_LEVEL_INFO,
10227 FL("Del_bss called, avoid apps suspend"));
10228 return FALSE;
10229
10230}
Jeff Johnson295189b2012-06-20 16:38:30 -070010231/* Decide whether to allow/not the apps power collapse.
10232 * Allow apps power collapse if we are in connected state.
10233 * if not, allow only if we are in IMPS */
10234v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10235{
10236 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010237 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010238 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010239 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10240 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10241 hdd_adapter_t *pAdapter = NULL;
10242 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010243 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010244
Jeff Johnson295189b2012-06-20 16:38:30 -070010245 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10246 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010247
Yathish9f22e662012-12-10 14:21:35 -080010248 concurrent_state = hdd_get_concurrency_mode();
10249
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010250 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10251 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10252 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010253#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010254
Yathish9f22e662012-12-10 14:21:35 -080010255 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010256 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010257 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10258 return TRUE;
10259#endif
10260
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 /*loop through all adapters. TBD fix for Concurrency */
10262 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10263 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10264 {
10265 pAdapter = pAdapterNode->pAdapter;
10266 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10267 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10268 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010269 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010270 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -080010271 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010272 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10273 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010274 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010275 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010276 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10277 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010278 return FALSE;
10279 }
10280 }
10281 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10282 pAdapterNode = pNext;
10283 }
10284 return TRUE;
10285}
10286
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010287/* Decides whether to send suspend notification to Riva
10288 * if any adapter is in BMPS; then it is required */
10289v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10290{
10291 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10292 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10293
10294 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10295 {
10296 return TRUE;
10297 }
10298 return FALSE;
10299}
10300
Jeff Johnson295189b2012-06-20 16:38:30 -070010301void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10302{
10303 switch(mode)
10304 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010305 case VOS_STA_MODE:
10306 case VOS_P2P_CLIENT_MODE:
10307 case VOS_P2P_GO_MODE:
10308 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010309 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010310 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010311 break;
10312 default:
10313 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010314 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010315 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10316 "Number of open sessions for mode %d = %d"),
10317 pHddCtx->concurrency_mode, mode,
10318 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010319}
10320
10321
10322void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10323{
10324 switch(mode)
10325 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010326 case VOS_STA_MODE:
10327 case VOS_P2P_CLIENT_MODE:
10328 case VOS_P2P_GO_MODE:
10329 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010330 pHddCtx->no_of_open_sessions[mode]--;
10331 if (!(pHddCtx->no_of_open_sessions[mode]))
10332 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 break;
10334 default:
10335 break;
10336 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010337 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10338 "Number of open sessions for mode %d = %d"),
10339 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10340
10341}
10342/**---------------------------------------------------------------------------
10343 *
10344 * \brief wlan_hdd_incr_active_session()
10345 *
10346 * This function increments the number of active sessions
10347 * maintained per device mode
10348 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10349 * Incase of SAP/P2P GO upon bss start it is incremented
10350 *
10351 * \param pHddCtx - HDD Context
10352 * \param mode - device mode
10353 *
10354 * \return - None
10355 *
10356 * --------------------------------------------------------------------------*/
10357void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10358{
10359 switch (mode) {
10360 case VOS_STA_MODE:
10361 case VOS_P2P_CLIENT_MODE:
10362 case VOS_P2P_GO_MODE:
10363 case VOS_STA_SAP_MODE:
10364 pHddCtx->no_of_active_sessions[mode]++;
10365 break;
10366 default:
10367 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10368 break;
10369 }
10370 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10371 mode,
10372 pHddCtx->no_of_active_sessions[mode]);
10373}
10374
10375/**---------------------------------------------------------------------------
10376 *
10377 * \brief wlan_hdd_decr_active_session()
10378 *
10379 * This function decrements the number of active sessions
10380 * maintained per device mode
10381 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10382 * Incase of SAP/P2P GO upon bss stop it is decremented
10383 *
10384 * \param pHddCtx - HDD Context
10385 * \param mode - device mode
10386 *
10387 * \return - None
10388 *
10389 * --------------------------------------------------------------------------*/
10390void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10391{
10392 switch (mode) {
10393 case VOS_STA_MODE:
10394 case VOS_P2P_CLIENT_MODE:
10395 case VOS_P2P_GO_MODE:
10396 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010397 if (pHddCtx->no_of_active_sessions[mode] > 0)
10398 pHddCtx->no_of_active_sessions[mode]--;
10399 else
10400 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10401 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010402 break;
10403 default:
10404 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10405 break;
10406 }
10407 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10408 mode,
10409 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010410}
10411
Jeff Johnsone7245742012-09-05 17:12:55 -070010412/**---------------------------------------------------------------------------
10413 *
10414 * \brief wlan_hdd_restart_init
10415 *
10416 * This function initalizes restart timer/flag. An internal function.
10417 *
10418 * \param - pHddCtx
10419 *
10420 * \return - None
10421 *
10422 * --------------------------------------------------------------------------*/
10423
10424static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10425{
10426 /* Initialize */
10427 pHddCtx->hdd_restart_retries = 0;
10428 atomic_set(&pHddCtx->isRestartInProgress, 0);
10429 vos_timer_init(&pHddCtx->hdd_restart_timer,
10430 VOS_TIMER_TYPE_SW,
10431 wlan_hdd_restart_timer_cb,
10432 pHddCtx);
10433}
10434/**---------------------------------------------------------------------------
10435 *
10436 * \brief wlan_hdd_restart_deinit
10437 *
10438 * This function cleans up the resources used. An internal function.
10439 *
10440 * \param - pHddCtx
10441 *
10442 * \return - None
10443 *
10444 * --------------------------------------------------------------------------*/
10445
10446static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10447{
10448
10449 VOS_STATUS vos_status;
10450 /* Block any further calls */
10451 atomic_set(&pHddCtx->isRestartInProgress, 1);
10452 /* Cleanup */
10453 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10454 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010455 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010456 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10457 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010458 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010459
10460}
10461
10462/**---------------------------------------------------------------------------
10463 *
10464 * \brief wlan_hdd_framework_restart
10465 *
10466 * This function uses a cfg80211 API to start a framework initiated WLAN
10467 * driver module unload/load.
10468 *
10469 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10470 *
10471 *
10472 * \param - pHddCtx
10473 *
10474 * \return - VOS_STATUS_SUCCESS: Success
10475 * VOS_STATUS_E_EMPTY: Adapter is Empty
10476 * VOS_STATUS_E_NOMEM: No memory
10477
10478 * --------------------------------------------------------------------------*/
10479
10480static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10481{
10482 VOS_STATUS status = VOS_STATUS_SUCCESS;
10483 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010484 int len = (sizeof (struct ieee80211_mgmt));
10485 struct ieee80211_mgmt *mgmt = NULL;
10486
10487 /* Prepare the DEAUTH managment frame with reason code */
10488 mgmt = kzalloc(len, GFP_KERNEL);
10489 if(mgmt == NULL)
10490 {
10491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10492 "%s: memory allocation failed (%d bytes)", __func__, len);
10493 return VOS_STATUS_E_NOMEM;
10494 }
10495 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010496
10497 /* Iterate over all adapters/devices */
10498 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10499 do
10500 {
10501 if( (status == VOS_STATUS_SUCCESS) &&
10502 pAdapterNode &&
10503 pAdapterNode->pAdapter)
10504 {
10505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10506 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10507 pAdapterNode->pAdapter->dev->name,
10508 pAdapterNode->pAdapter->device_mode,
10509 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010510 /*
10511 * CFG80211 event to restart the driver
10512 *
10513 * 'cfg80211_send_unprot_deauth' sends a
10514 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10515 * of SME(Linux Kernel) state machine.
10516 *
10517 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10518 * the driver.
10519 *
10520 */
10521
10522 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010523 }
10524 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10525 pAdapterNode = pNext;
10526 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10527
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010528
10529 /* Free the allocated management frame */
10530 kfree(mgmt);
10531
Jeff Johnsone7245742012-09-05 17:12:55 -070010532 /* Retry until we unload or reach max count */
10533 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10534 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10535
10536 return status;
10537
10538}
10539/**---------------------------------------------------------------------------
10540 *
10541 * \brief wlan_hdd_restart_timer_cb
10542 *
10543 * Restart timer callback. An internal function.
10544 *
10545 * \param - User data:
10546 *
10547 * \return - None
10548 *
10549 * --------------------------------------------------------------------------*/
10550
10551void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10552{
10553 hdd_context_t *pHddCtx = usrDataForCallback;
10554 wlan_hdd_framework_restart(pHddCtx);
10555 return;
10556
10557}
10558
10559
10560/**---------------------------------------------------------------------------
10561 *
10562 * \brief wlan_hdd_restart_driver
10563 *
10564 * This function sends an event to supplicant to restart the WLAN driver.
10565 *
10566 * This function is called from vos_wlanRestart.
10567 *
10568 * \param - pHddCtx
10569 *
10570 * \return - VOS_STATUS_SUCCESS: Success
10571 * VOS_STATUS_E_EMPTY: Adapter is Empty
10572 * VOS_STATUS_E_ALREADY: Request already in progress
10573
10574 * --------------------------------------------------------------------------*/
10575VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10576{
10577 VOS_STATUS status = VOS_STATUS_SUCCESS;
10578
10579 /* A tight check to make sure reentrancy */
10580 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10581 {
Mihir Shetefd528652014-06-23 19:07:50 +053010582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010583 "%s: WLAN restart is already in progress", __func__);
10584
10585 return VOS_STATUS_E_ALREADY;
10586 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010587 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010588#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010589 wcnss_reset_intr();
10590#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010591
Jeff Johnsone7245742012-09-05 17:12:55 -070010592 return status;
10593}
10594
Mihir Shetee1093ba2014-01-21 20:13:32 +053010595/**---------------------------------------------------------------------------
10596 *
10597 * \brief wlan_hdd_init_channels
10598 *
10599 * This function is used to initialize the channel list in CSR
10600 *
10601 * This function is called from hdd_wlan_startup
10602 *
10603 * \param - pHddCtx: HDD context
10604 *
10605 * \return - VOS_STATUS_SUCCESS: Success
10606 * VOS_STATUS_E_FAULT: Failure reported by SME
10607
10608 * --------------------------------------------------------------------------*/
10609static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10610{
10611 eHalStatus status;
10612
10613 status = sme_InitChannels(pHddCtx->hHal);
10614 if (HAL_STATUS_SUCCESS(status))
10615 {
10616 return VOS_STATUS_SUCCESS;
10617 }
10618 else
10619 {
10620 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10621 __func__, status);
10622 return VOS_STATUS_E_FAULT;
10623 }
10624}
10625
Mihir Shete04206452014-11-20 17:50:58 +053010626#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010627VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010628{
10629 eHalStatus status;
10630
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010631 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010632 if (HAL_STATUS_SUCCESS(status))
10633 {
10634 return VOS_STATUS_SUCCESS;
10635 }
10636 else
10637 {
10638 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10639 __func__, status);
10640 return VOS_STATUS_E_FAULT;
10641 }
10642}
Mihir Shete04206452014-11-20 17:50:58 +053010643#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010644/*
10645 * API to find if there is any STA or P2P-Client is connected
10646 */
10647VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10648{
10649 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10650}
Jeff Johnsone7245742012-09-05 17:12:55 -070010651
Agarwal Ashish57e84372014-12-05 18:26:53 +053010652/*
10653 * API to find if there is any session connected
10654 */
10655VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
10656{
10657 return sme_is_any_session_connected(pHddCtx->hHal);
10658}
10659
10660
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010661int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10662{
10663 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10664 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010665 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010666
10667 pScanInfo = &pHddCtx->scan_info;
10668 if (pScanInfo->mScanPending)
10669 {
10670 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010671 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010672 eCSR_SCAN_ABORT_DEFAULT);
10673
10674 status = wait_for_completion_interruptible_timeout(
10675 &pScanInfo->abortscan_event_var,
10676 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010677 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010678 {
10679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010680 "%s: Timeout or Interrupt occurred while waiting for abort"
10681 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010682 return -ETIMEDOUT;
10683 }
10684 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010685 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010686}
10687
c_hpothu225aa7c2014-10-22 17:45:13 +053010688VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10689{
10690 hdd_adapter_t *pAdapter;
10691 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10692 VOS_STATUS vosStatus;
10693
10694 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10695 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10696 {
10697 pAdapter = pAdapterNode->pAdapter;
10698 if (NULL != pAdapter)
10699 {
10700 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10701 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10702 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10703 {
10704 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10705 pAdapter->device_mode);
10706 if (VOS_STATUS_SUCCESS !=
10707 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10708 {
10709 hddLog(LOGE, FL("failed to abort ROC"));
10710 return VOS_STATUS_E_FAILURE;
10711 }
10712 }
10713 }
10714 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10715 pAdapterNode = pNext;
10716 }
10717 return VOS_STATUS_SUCCESS;
10718}
Jeff Johnson295189b2012-06-20 16:38:30 -070010719//Register the module init/exit functions
10720module_init(hdd_module_init);
10721module_exit(hdd_module_exit);
10722
10723MODULE_LICENSE("Dual BSD/GPL");
10724MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10725MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10726
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010727module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10728 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010729
Jeff Johnson76052702013-04-16 13:55:05 -070010730module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010731 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010732
10733module_param(enable_dfs_chan_scan, int,
10734 S_IRUSR | S_IRGRP | S_IROTH);
10735
10736module_param(enable_11d, int,
10737 S_IRUSR | S_IRGRP | S_IROTH);
10738
10739module_param(country_code, charp,
10740 S_IRUSR | S_IRGRP | S_IROTH);