blob: 324702c7c5474df0383d9cf43b9af35963356ef3 [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
Satyanarayana Dash72806012014-12-02 14:30:08 +05301967void hdd_FWStatisCB( VOS_STATUS status, void *fwStats, void *data )
1968{
1969 fwStatsContext_t *fwStatsCtx;
1970 fwStatsResult_t *fwStatsResult;
1971 hdd_adapter_t *pAdapter;
1972
1973 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1974
1975 if (NULL == data)
1976 {
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);
1985 fwStatsCtx = (fwStatsContext_t *) data;
1986 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;
2002 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStats))
2003 {
2004 fwStatsResult = (fwStatsResult_t *)fwStats;
2005 switch( fwStatsResult->type )
2006 {
2007 case FW_UBSP_STATS:
2008 {
2009 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(fwStatsResult_t));
2010
2011 hddLog(VOS_TRACE_LEVEL_INFO,
2012 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
2013 pAdapter->fwStatsRsp.hddFwStatsData.ubspStats.ubsp_enter_cnt,
2014 pAdapter->fwStatsRsp.hddFwStatsData.ubspStats.ubsp_jump_ddr_cnt);
2015 }
2016 break;
2017 default:
2018 {
2019 hddLog(VOS_TRACE_LEVEL_ERROR,
2020 FL(" No handling for stats type %d"),fwStatsResult->type);
2021 }
2022 }
2023 }
2024 complete(&(fwStatsCtx->completion));
2025 spin_unlock(&hdd_context_lock);
2026 return;
2027}
2028
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302029static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2030{
2031 int ret = 0;
2032
2033 if (!pCfg || !command || !extra || !len)
2034 {
2035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2036 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2037 ret = -EINVAL;
2038 return ret;
2039 }
2040
2041 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2042 {
2043 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2044 (int)pCfg->nActiveMaxChnTime);
2045 return ret;
2046 }
2047 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2048 {
2049 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2050 (int)pCfg->nActiveMinChnTime);
2051 return ret;
2052 }
2053 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2054 {
2055 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2056 (int)pCfg->nPassiveMaxChnTime);
2057 return ret;
2058 }
2059 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2060 {
2061 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2062 (int)pCfg->nPassiveMinChnTime);
2063 return ret;
2064 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302065 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2066 {
2067 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2068 (int)pCfg->nActiveMaxChnTime);
2069 return ret;
2070 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302071 else
2072 {
2073 ret = -EINVAL;
2074 }
2075
2076 return ret;
2077}
2078
2079static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2080{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302081 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302082 hdd_config_t *pCfg;
2083 tANI_U8 *value = command;
2084 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302085 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302086
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302087 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2088 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302089 {
2090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2091 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2092 ret = -EINVAL;
2093 return ret;
2094 }
2095
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302096 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2097 sme_GetConfigParam(hHal, &smeConfig);
2098
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302099 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2100 {
2101 value = value + 24;
2102 temp = kstrtou32(value, 10, &val);
2103 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2104 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2105 {
2106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2107 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2108 ret = -EFAULT;
2109 return ret;
2110 }
2111 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302112 smeConfig.csrConfig.nActiveMaxChnTime = val;
2113 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302114 }
2115 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2116 {
2117 value = value + 24;
2118 temp = kstrtou32(value, 10, &val);
2119 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2120 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2121 {
2122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2123 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2124 ret = -EFAULT;
2125 return ret;
2126 }
2127 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302128 smeConfig.csrConfig.nActiveMinChnTime = val;
2129 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302130 }
2131 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2132 {
2133 value = value + 25;
2134 temp = kstrtou32(value, 10, &val);
2135 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2136 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2137 {
2138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2139 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2140 ret = -EFAULT;
2141 return ret;
2142 }
2143 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302144 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2145 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302146 }
2147 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2148 {
2149 value = value + 25;
2150 temp = kstrtou32(value, 10, &val);
2151 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2152 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2153 {
2154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2155 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2156 ret = -EFAULT;
2157 return ret;
2158 }
2159 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302160 smeConfig.csrConfig.nPassiveMinChnTime = val;
2161 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302162 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302163 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2164 {
2165 value = value + 13;
2166 temp = kstrtou32(value, 10, &val);
2167 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2168 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2169 {
2170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2171 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2172 ret = -EFAULT;
2173 return ret;
2174 }
2175 pCfg->nActiveMaxChnTime = val;
2176 smeConfig.csrConfig.nActiveMaxChnTime = val;
2177 sme_UpdateConfig(hHal, &smeConfig);
2178 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302179 else
2180 {
2181 ret = -EINVAL;
2182 }
2183
2184 return ret;
2185}
2186
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002187static int hdd_driver_command(hdd_adapter_t *pAdapter,
2188 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002189{
Jeff Johnson295189b2012-06-20 16:38:30 -07002190 hdd_priv_data_t priv_data;
2191 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302192 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2193 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002194 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302195 int status;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002196 /*
2197 * Note that valid pointers are provided by caller
2198 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002199
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002200 /* copy to local struct to avoid numerous changes to legacy code */
2201 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002202
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002203 if (priv_data.total_len <= 0 ||
2204 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002205 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002206 hddLog(VOS_TRACE_LEVEL_WARN,
2207 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2208 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002209 ret = -EINVAL;
2210 goto exit;
2211 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302212 status = wlan_hdd_validate_context(pHddCtx);
2213 if (0 != status)
2214 {
2215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2216 "%s: HDD context is not valid", __func__);
2217 return status;
2218 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002219 /* Allocate +1 for '\0' */
2220 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002221 if (!command)
2222 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002223 hddLog(VOS_TRACE_LEVEL_ERROR,
2224 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002225 ret = -ENOMEM;
2226 goto exit;
2227 }
2228
2229 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2230 {
2231 ret = -EFAULT;
2232 goto exit;
2233 }
2234
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002235 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002236 command[priv_data.total_len] = '\0';
2237
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002238 /* at one time the following block of code was conditional. braces
2239 * have been retained to avoid re-indenting the legacy code
2240 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002241 {
2242 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2243
2244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002245 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002246
2247 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2248 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302249 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2250 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2251 pAdapter->sessionId, (unsigned)
2252 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2253 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2254 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2255 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002256 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2257 sizeof(tSirMacAddr)))
2258 {
2259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002260 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002261 ret = -EFAULT;
2262 }
2263 }
Amar Singhal0974e402013-02-12 14:27:46 -08002264 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002265 {
Amar Singhal0974e402013-02-12 14:27:46 -08002266 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002267
Jeff Johnson295189b2012-06-20 16:38:30 -07002268 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002269
2270 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002271 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002273 "%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 -07002274 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002275 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302276 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302277 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002278 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002279 }
Kiet Lamf040f472013-11-20 21:15:23 +05302280 else if(strncmp(command, "SETWMMPS", 8) == 0)
2281 {
2282 tANI_U8 *ptr = command;
2283 ret = hdd_wmmps_helper(pAdapter, ptr);
2284 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002285 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2286 {
2287 char *country_code;
2288
2289 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002290
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002291 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002292 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002293#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302294 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002295#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002296 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2297 (void *)(tSmeChangeCountryCallback)
2298 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302299 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002300 if (eHAL_STATUS_SUCCESS == ret)
2301 {
2302 ret = wait_for_completion_interruptible_timeout(
2303 &pAdapter->change_country_code,
2304 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2305 if (0 >= ret)
2306 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002307 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302308 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002309 }
2310 }
2311 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002312 {
2313 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002314 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002315 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002316 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002317
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002318 }
2319 /*
2320 command should be a string having format
2321 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2322 */
Amar Singhal0974e402013-02-12 14:27:46 -08002323 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002324 {
Amar Singhal0974e402013-02-12 14:27:46 -08002325 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002326
2327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002328 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002329
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002330 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002331 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002332 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2333 {
2334 int suspend = 0;
2335 tANI_U8 *ptr = (tANI_U8*)command + 15;
2336
2337 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302338 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2339 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2340 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002341 hdd_set_wlan_suspend_mode(suspend);
2342 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002343#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2344 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2345 {
2346 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002347 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002348 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2349 eHalStatus status = eHAL_STATUS_SUCCESS;
2350
2351 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2352 value = value + 15;
2353
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002354 /* Convert the value from ascii to integer */
2355 ret = kstrtos8(value, 10, &rssi);
2356 if (ret < 0)
2357 {
2358 /* If the input value is greater than max value of datatype, then also
2359 kstrtou8 fails */
2360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2361 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002362 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002363 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2364 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2365 ret = -EINVAL;
2366 goto exit;
2367 }
2368
Srinivas Girigowdade697412013-02-14 16:31:48 -08002369 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002370
Srinivas Girigowdade697412013-02-14 16:31:48 -08002371 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2372 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2373 {
2374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2375 "Neighbor lookup threshold value %d is out of range"
2376 " (Min: %d Max: %d)", lookUpThreshold,
2377 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2378 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2379 ret = -EINVAL;
2380 goto exit;
2381 }
2382
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302383 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2384 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2385 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2387 "%s: Received Command to Set Roam trigger"
2388 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2389
2390 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2391 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2392 if (eHAL_STATUS_SUCCESS != status)
2393 {
2394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2395 "%s: Failed to set roam trigger, try again", __func__);
2396 ret = -EPERM;
2397 goto exit;
2398 }
2399
2400 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302401 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002402 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2403 }
2404 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2405 {
2406 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2407 int rssi = (-1) * lookUpThreshold;
2408 char extra[32];
2409 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302410 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2411 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2412 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002413 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002414 if (copy_to_user(priv_data.buf, &extra, len + 1))
2415 {
2416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2417 "%s: failed to copy data to user buffer", __func__);
2418 ret = -EFAULT;
2419 goto exit;
2420 }
2421 }
2422 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2423 {
2424 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002425 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002426 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002427
Srinivas Girigowdade697412013-02-14 16:31:48 -08002428 /* input refresh period is in terms of seconds */
2429 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2430 value = value + 18;
2431 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002432 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002433 if (ret < 0)
2434 {
2435 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002436 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002438 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002439 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002440 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2441 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002442 ret = -EINVAL;
2443 goto exit;
2444 }
2445
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002446 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2447 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002448 {
2449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002450 "Roam scan period value %d is out of range"
2451 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002452 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2453 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002454 ret = -EINVAL;
2455 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302456 }
2457 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2458 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2459 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002460 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002461
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2463 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002464 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002465
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002466 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2467 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002468 }
2469 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2470 {
2471 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2472 char extra[32];
2473 tANI_U8 len = 0;
2474
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302475 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2476 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2477 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002478 len = scnprintf(extra, sizeof(extra), "%s %d",
2479 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002480 /* Returned value is in units of seconds */
2481 if (copy_to_user(priv_data.buf, &extra, len + 1))
2482 {
2483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2484 "%s: failed to copy data to user buffer", __func__);
2485 ret = -EFAULT;
2486 goto exit;
2487 }
2488 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002489 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2490 {
2491 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002492 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002493 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002494
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002495 /* input refresh period is in terms of seconds */
2496 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2497 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002498
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002499 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002500 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002501 if (ret < 0)
2502 {
2503 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002504 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002506 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002507 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002508 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2509 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2510 ret = -EINVAL;
2511 goto exit;
2512 }
2513
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002514 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2515 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2516 {
2517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2518 "Neighbor scan results refresh period value %d is out of range"
2519 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2520 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2521 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2522 ret = -EINVAL;
2523 goto exit;
2524 }
2525 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2526
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2528 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002529 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002530
2531 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2532 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2533 }
2534 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2535 {
2536 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2537 char extra[32];
2538 tANI_U8 len = 0;
2539
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002540 len = scnprintf(extra, sizeof(extra), "%s %d",
2541 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002542 /* Returned value is in units of seconds */
2543 if (copy_to_user(priv_data.buf, &extra, len + 1))
2544 {
2545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2546 "%s: failed to copy data to user buffer", __func__);
2547 ret = -EFAULT;
2548 goto exit;
2549 }
2550 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002551#ifdef FEATURE_WLAN_LFR
2552 /* SETROAMMODE */
2553 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2554 {
2555 tANI_U8 *value = command;
2556 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2557
2558 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2559 value = value + SIZE_OF_SETROAMMODE + 1;
2560
2561 /* Convert the value from ascii to integer */
2562 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2563 if (ret < 0)
2564 {
2565 /* If the input value is greater than max value of datatype, then also
2566 kstrtou8 fails */
2567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2568 "%s: kstrtou8 failed range [%d - %d]", __func__,
2569 CFG_LFR_FEATURE_ENABLED_MIN,
2570 CFG_LFR_FEATURE_ENABLED_MAX);
2571 ret = -EINVAL;
2572 goto exit;
2573 }
2574 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2575 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2576 {
2577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2578 "Roam Mode value %d is out of range"
2579 " (Min: %d Max: %d)", roamMode,
2580 CFG_LFR_FEATURE_ENABLED_MIN,
2581 CFG_LFR_FEATURE_ENABLED_MAX);
2582 ret = -EINVAL;
2583 goto exit;
2584 }
2585
2586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2587 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2588 /*
2589 * Note that
2590 * SETROAMMODE 0 is to enable LFR while
2591 * SETROAMMODE 1 is to disable LFR, but
2592 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2593 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2594 */
2595 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2596 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2597 else
2598 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2599
2600 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2601 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2602 }
2603 /* GETROAMMODE */
2604 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2605 {
2606 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2607 char extra[32];
2608 tANI_U8 len = 0;
2609
2610 /*
2611 * roamMode value shall be inverted because the sementics is different.
2612 */
2613 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2614 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2615 else
2616 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2617
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002618 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002619 if (copy_to_user(priv_data.buf, &extra, len + 1))
2620 {
2621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2622 "%s: failed to copy data to user buffer", __func__);
2623 ret = -EFAULT;
2624 goto exit;
2625 }
2626 }
2627#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002628#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002629#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002630 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2631 {
2632 tANI_U8 *value = command;
2633 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2634
2635 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2636 value = value + 13;
2637 /* Convert the value from ascii to integer */
2638 ret = kstrtou8(value, 10, &roamRssiDiff);
2639 if (ret < 0)
2640 {
2641 /* If the input value is greater than max value of datatype, then also
2642 kstrtou8 fails */
2643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2644 "%s: kstrtou8 failed range [%d - %d]", __func__,
2645 CFG_ROAM_RSSI_DIFF_MIN,
2646 CFG_ROAM_RSSI_DIFF_MAX);
2647 ret = -EINVAL;
2648 goto exit;
2649 }
2650
2651 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2652 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2653 {
2654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2655 "Roam rssi diff value %d is out of range"
2656 " (Min: %d Max: %d)", roamRssiDiff,
2657 CFG_ROAM_RSSI_DIFF_MIN,
2658 CFG_ROAM_RSSI_DIFF_MAX);
2659 ret = -EINVAL;
2660 goto exit;
2661 }
2662
2663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2664 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2665
2666 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2667 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2668 }
2669 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2670 {
2671 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2672 char extra[32];
2673 tANI_U8 len = 0;
2674
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302675 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2676 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2677 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002678 len = scnprintf(extra, sizeof(extra), "%s %d",
2679 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002680 if (copy_to_user(priv_data.buf, &extra, len + 1))
2681 {
2682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2683 "%s: failed to copy data to user buffer", __func__);
2684 ret = -EFAULT;
2685 goto exit;
2686 }
2687 }
2688#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002689#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002690 else if (strncmp(command, "GETBAND", 7) == 0)
2691 {
2692 int band = -1;
2693 char extra[32];
2694 tANI_U8 len = 0;
2695 hdd_getBand_helper(pHddCtx, &band);
2696
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302697 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2698 TRACE_CODE_HDD_GETBAND_IOCTL,
2699 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002700 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002701 if (copy_to_user(priv_data.buf, &extra, len + 1))
2702 {
2703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2704 "%s: failed to copy data to user buffer", __func__);
2705 ret = -EFAULT;
2706 goto exit;
2707 }
2708 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002709 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2710 {
2711 tANI_U8 *value = command;
2712 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2713 tANI_U8 numChannels = 0;
2714 eHalStatus status = eHAL_STATUS_SUCCESS;
2715
2716 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2717 if (eHAL_STATUS_SUCCESS != status)
2718 {
2719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2720 "%s: Failed to parse channel list information", __func__);
2721 ret = -EINVAL;
2722 goto exit;
2723 }
2724
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302725 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2726 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2727 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002728 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2729 {
2730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2731 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2732 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2733 ret = -EINVAL;
2734 goto exit;
2735 }
2736 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2737 numChannels);
2738 if (eHAL_STATUS_SUCCESS != status)
2739 {
2740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2741 "%s: Failed to update channel list information", __func__);
2742 ret = -EINVAL;
2743 goto exit;
2744 }
2745 }
2746 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2747 {
2748 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2749 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002750 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002751 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002752 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002753
2754 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2755 ChannelList, &numChannels ))
2756 {
2757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2758 "%s: failed to get roam scan channel list", __func__);
2759 ret = -EFAULT;
2760 goto exit;
2761 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302762 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2763 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2764 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002765 /* output channel list is of the format
2766 [Number of roam scan channels][Channel1][Channel2]... */
2767 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002768 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002769 for (j = 0; (j < numChannels); j++)
2770 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002771 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2772 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002773 }
2774
2775 if (copy_to_user(priv_data.buf, &extra, len + 1))
2776 {
2777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2778 "%s: failed to copy data to user buffer", __func__);
2779 ret = -EFAULT;
2780 goto exit;
2781 }
2782 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002783 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2784 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002785 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002786 char extra[32];
2787 tANI_U8 len = 0;
2788
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002789 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002790 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002791 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002792 hdd_is_okc_mode_enabled(pHddCtx) &&
2793 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2794 {
2795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002796 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002797 " hence this operation is not permitted!", __func__);
2798 ret = -EPERM;
2799 goto exit;
2800 }
2801
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002802 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002803 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002804 if (copy_to_user(priv_data.buf, &extra, len + 1))
2805 {
2806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2807 "%s: failed to copy data to user buffer", __func__);
2808 ret = -EFAULT;
2809 goto exit;
2810 }
2811 }
2812 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2813 {
2814 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2815 char extra[32];
2816 tANI_U8 len = 0;
2817
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002818 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002819 then this operation is not permitted (return FAILURE) */
2820 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002821 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002822 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2823 {
2824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002825 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002826 " hence this operation is not permitted!", __func__);
2827 ret = -EPERM;
2828 goto exit;
2829 }
2830
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002831 len = scnprintf(extra, sizeof(extra), "%s %d",
2832 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002833 if (copy_to_user(priv_data.buf, &extra, len + 1))
2834 {
2835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2836 "%s: failed to copy data to user buffer", __func__);
2837 ret = -EFAULT;
2838 goto exit;
2839 }
2840 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002841 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002842 {
2843 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2844 char extra[32];
2845 tANI_U8 len = 0;
2846
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002847 len = scnprintf(extra, sizeof(extra), "%s %d",
2848 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002849 if (copy_to_user(priv_data.buf, &extra, len + 1))
2850 {
2851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2852 "%s: failed to copy data to user buffer", __func__);
2853 ret = -EFAULT;
2854 goto exit;
2855 }
2856 }
2857 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2858 {
2859 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2860 char extra[32];
2861 tANI_U8 len = 0;
2862
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002863 len = scnprintf(extra, sizeof(extra), "%s %d",
2864 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002865 if (copy_to_user(priv_data.buf, &extra, len + 1))
2866 {
2867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2868 "%s: failed to copy data to user buffer", __func__);
2869 ret = -EFAULT;
2870 goto exit;
2871 }
2872 }
2873 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2874 {
2875 tANI_U8 *value = command;
2876 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2877
2878 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2879 value = value + 26;
2880 /* Convert the value from ascii to integer */
2881 ret = kstrtou8(value, 10, &minTime);
2882 if (ret < 0)
2883 {
2884 /* If the input value is greater than max value of datatype, then also
2885 kstrtou8 fails */
2886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2887 "%s: kstrtou8 failed range [%d - %d]", __func__,
2888 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2889 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2890 ret = -EINVAL;
2891 goto exit;
2892 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002893 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2894 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2895 {
2896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2897 "scan min channel time value %d is out of range"
2898 " (Min: %d Max: %d)", minTime,
2899 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2900 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2901 ret = -EINVAL;
2902 goto exit;
2903 }
2904
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302905 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2906 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2907 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2909 "%s: Received Command to change channel min time = %d", __func__, minTime);
2910
2911 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2912 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2913 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002914 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2915 {
2916 tANI_U8 *value = command;
2917 tANI_U8 channel = 0;
2918 tANI_U8 dwellTime = 0;
2919 tANI_U8 bufLen = 0;
2920 tANI_U8 *buf = NULL;
2921 tSirMacAddr targetApBssid;
2922 eHalStatus status = eHAL_STATUS_SUCCESS;
2923 struct ieee80211_channel chan;
2924 tANI_U8 finalLen = 0;
2925 tANI_U8 *finalBuf = NULL;
2926 tANI_U8 temp = 0;
2927 u64 cookie;
2928 hdd_station_ctx_t *pHddStaCtx = NULL;
2929 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2930
2931 /* if not associated, no need to send action frame */
2932 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2933 {
2934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2935 ret = -EINVAL;
2936 goto exit;
2937 }
2938
2939 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2940 &dwellTime, &buf, &bufLen);
2941 if (eHAL_STATUS_SUCCESS != status)
2942 {
2943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2944 "%s: Failed to parse send action frame data", __func__);
2945 ret = -EINVAL;
2946 goto exit;
2947 }
2948
2949 /* if the target bssid is different from currently associated AP,
2950 then no need to send action frame */
2951 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2952 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2953 {
2954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2955 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002956 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002957 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002958 goto exit;
2959 }
2960
2961 /* if the channel number is different from operating channel then
2962 no need to send action frame */
2963 if (channel != pHddStaCtx->conn_info.operationChannel)
2964 {
2965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2966 "%s: channel(%d) is different from operating channel(%d)",
2967 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2968 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002969 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002970 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002971 goto exit;
2972 }
2973 chan.center_freq = sme_ChnToFreq(channel);
2974
2975 finalLen = bufLen + 24;
2976 finalBuf = vos_mem_malloc(finalLen);
2977 if (NULL == finalBuf)
2978 {
2979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2980 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002981 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002982 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002983 goto exit;
2984 }
2985 vos_mem_zero(finalBuf, finalLen);
2986
2987 /* Fill subtype */
2988 temp = SIR_MAC_MGMT_ACTION << 4;
2989 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2990
2991 /* Fill type */
2992 temp = SIR_MAC_MGMT_FRAME;
2993 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2994
2995 /* Fill destination address (bssid of the AP) */
2996 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2997
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002998 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002999 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3000
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003001 /* Fill BSSID (AP mac address) */
3002 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003003
3004 /* Fill received buffer from 24th address */
3005 vos_mem_copy(finalBuf + 24, buf, bufLen);
3006
Jeff Johnson11c33152013-04-16 17:52:40 -07003007 /* done with the parsed buffer */
3008 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003009 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003010
DARAM SUDHA39eede62014-02-12 11:16:40 +05303011 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3013 &(pAdapter->wdev),
3014#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003015 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003016#endif
3017 &chan, 0,
3018#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3019 NL80211_CHAN_HT20, 1,
3020#endif
3021 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003022 1, &cookie );
3023 vos_mem_free(finalBuf);
3024 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003025 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3026 {
3027 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3028 char extra[32];
3029 tANI_U8 len = 0;
3030
3031 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003032 len = scnprintf(extra, sizeof(extra), "%s %d",
3033 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303034 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3035 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3036 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003037 if (copy_to_user(priv_data.buf, &extra, len + 1))
3038 {
3039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3040 "%s: failed to copy data to user buffer", __func__);
3041 ret = -EFAULT;
3042 goto exit;
3043 }
3044 }
3045 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3046 {
3047 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003048 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003049
3050 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3051 value = value + 19;
3052 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003053 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003054 if (ret < 0)
3055 {
3056 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003057 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003059 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003060 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3061 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3062 ret = -EINVAL;
3063 goto exit;
3064 }
3065
3066 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3067 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3068 {
3069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3070 "lfr mode value %d is out of range"
3071 " (Min: %d Max: %d)", maxTime,
3072 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3073 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3074 ret = -EINVAL;
3075 goto exit;
3076 }
3077
3078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3079 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3080
3081 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3082 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3083 }
3084 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3085 {
3086 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3087 char extra[32];
3088 tANI_U8 len = 0;
3089
3090 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003091 len = scnprintf(extra, sizeof(extra), "%s %d",
3092 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003093 if (copy_to_user(priv_data.buf, &extra, len + 1))
3094 {
3095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3096 "%s: failed to copy data to user buffer", __func__);
3097 ret = -EFAULT;
3098 goto exit;
3099 }
3100 }
3101 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3102 {
3103 tANI_U8 *value = command;
3104 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3105
3106 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3107 value = value + 16;
3108 /* Convert the value from ascii to integer */
3109 ret = kstrtou16(value, 10, &val);
3110 if (ret < 0)
3111 {
3112 /* If the input value is greater than max value of datatype, then also
3113 kstrtou16 fails */
3114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3115 "%s: kstrtou16 failed range [%d - %d]", __func__,
3116 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3117 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3118 ret = -EINVAL;
3119 goto exit;
3120 }
3121
3122 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3123 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3124 {
3125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3126 "scan home time value %d is out of range"
3127 " (Min: %d Max: %d)", val,
3128 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3129 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3130 ret = -EINVAL;
3131 goto exit;
3132 }
3133
3134 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3135 "%s: Received Command to change scan home time = %d", __func__, val);
3136
3137 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3138 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3139 }
3140 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3141 {
3142 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3143 char extra[32];
3144 tANI_U8 len = 0;
3145
3146 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003147 len = scnprintf(extra, sizeof(extra), "%s %d",
3148 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003149 if (copy_to_user(priv_data.buf, &extra, len + 1))
3150 {
3151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3152 "%s: failed to copy data to user buffer", __func__);
3153 ret = -EFAULT;
3154 goto exit;
3155 }
3156 }
3157 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3158 {
3159 tANI_U8 *value = command;
3160 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3161
3162 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3163 value = value + 17;
3164 /* Convert the value from ascii to integer */
3165 ret = kstrtou8(value, 10, &val);
3166 if (ret < 0)
3167 {
3168 /* If the input value is greater than max value of datatype, then also
3169 kstrtou8 fails */
3170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3171 "%s: kstrtou8 failed range [%d - %d]", __func__,
3172 CFG_ROAM_INTRA_BAND_MIN,
3173 CFG_ROAM_INTRA_BAND_MAX);
3174 ret = -EINVAL;
3175 goto exit;
3176 }
3177
3178 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3179 (val > CFG_ROAM_INTRA_BAND_MAX))
3180 {
3181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3182 "intra band mode value %d is out of range"
3183 " (Min: %d Max: %d)", val,
3184 CFG_ROAM_INTRA_BAND_MIN,
3185 CFG_ROAM_INTRA_BAND_MAX);
3186 ret = -EINVAL;
3187 goto exit;
3188 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3190 "%s: Received Command to change intra band = %d", __func__, val);
3191
3192 pHddCtx->cfg_ini->nRoamIntraBand = val;
3193 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3194 }
3195 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3196 {
3197 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3198 char extra[32];
3199 tANI_U8 len = 0;
3200
3201 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003202 len = scnprintf(extra, sizeof(extra), "%s %d",
3203 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003204 if (copy_to_user(priv_data.buf, &extra, len + 1))
3205 {
3206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3207 "%s: failed to copy data to user buffer", __func__);
3208 ret = -EFAULT;
3209 goto exit;
3210 }
3211 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003212 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3213 {
3214 tANI_U8 *value = command;
3215 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3216
3217 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3218 value = value + 15;
3219 /* Convert the value from ascii to integer */
3220 ret = kstrtou8(value, 10, &nProbes);
3221 if (ret < 0)
3222 {
3223 /* If the input value is greater than max value of datatype, then also
3224 kstrtou8 fails */
3225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3226 "%s: kstrtou8 failed range [%d - %d]", __func__,
3227 CFG_ROAM_SCAN_N_PROBES_MIN,
3228 CFG_ROAM_SCAN_N_PROBES_MAX);
3229 ret = -EINVAL;
3230 goto exit;
3231 }
3232
3233 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3234 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3235 {
3236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3237 "NProbes value %d is out of range"
3238 " (Min: %d Max: %d)", nProbes,
3239 CFG_ROAM_SCAN_N_PROBES_MIN,
3240 CFG_ROAM_SCAN_N_PROBES_MAX);
3241 ret = -EINVAL;
3242 goto exit;
3243 }
3244
3245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3246 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3247
3248 pHddCtx->cfg_ini->nProbes = nProbes;
3249 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3250 }
3251 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3252 {
3253 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3254 char extra[32];
3255 tANI_U8 len = 0;
3256
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003257 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003258 if (copy_to_user(priv_data.buf, &extra, len + 1))
3259 {
3260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3261 "%s: failed to copy data to user buffer", __func__);
3262 ret = -EFAULT;
3263 goto exit;
3264 }
3265 }
3266 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3267 {
3268 tANI_U8 *value = command;
3269 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3270
3271 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3272 /* input value is in units of msec */
3273 value = value + 20;
3274 /* Convert the value from ascii to integer */
3275 ret = kstrtou16(value, 10, &homeAwayTime);
3276 if (ret < 0)
3277 {
3278 /* If the input value is greater than max value of datatype, then also
3279 kstrtou8 fails */
3280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3281 "%s: kstrtou8 failed range [%d - %d]", __func__,
3282 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3283 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3284 ret = -EINVAL;
3285 goto exit;
3286 }
3287
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003288 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3289 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3290 {
3291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3292 "homeAwayTime value %d is out of range"
3293 " (Min: %d Max: %d)", homeAwayTime,
3294 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3295 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3296 ret = -EINVAL;
3297 goto exit;
3298 }
3299
3300 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3301 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003302 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3303 {
3304 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3305 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3306 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003307 }
3308 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3309 {
3310 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3311 char extra[32];
3312 tANI_U8 len = 0;
3313
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003314 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003315 if (copy_to_user(priv_data.buf, &extra, len + 1))
3316 {
3317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3318 "%s: failed to copy data to user buffer", __func__);
3319 ret = -EFAULT;
3320 goto exit;
3321 }
3322 }
3323 else if (strncmp(command, "REASSOC", 7) == 0)
3324 {
3325 tANI_U8 *value = command;
3326 tANI_U8 channel = 0;
3327 tSirMacAddr targetApBssid;
3328 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003329#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3330 tCsrHandoffRequest handoffInfo;
3331#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003332 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003333 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3334
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003335 /* if not associated, no need to proceed with reassoc */
3336 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3337 {
3338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3339 ret = -EINVAL;
3340 goto exit;
3341 }
3342
3343 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3344 if (eHAL_STATUS_SUCCESS != status)
3345 {
3346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3347 "%s: Failed to parse reassoc command data", __func__);
3348 ret = -EINVAL;
3349 goto exit;
3350 }
3351
3352 /* if the target bssid is same as currently associated AP,
3353 then no need to proceed with reassoc */
3354 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3355 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3356 {
3357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3358 ret = -EINVAL;
3359 goto exit;
3360 }
3361
3362 /* Check channel number is a valid channel number */
3363 if(VOS_STATUS_SUCCESS !=
3364 wlan_hdd_validate_operation_channel(pAdapter, channel))
3365 {
3366 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003367 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003368 return -EINVAL;
3369 }
3370
3371 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003372#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3373 handoffInfo.channel = channel;
3374 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3375 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3376#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003377 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003378 else if (strncmp(command, "SETWESMODE", 10) == 0)
3379 {
3380 tANI_U8 *value = command;
3381 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3382
3383 /* Move pointer to ahead of SETWESMODE<delimiter> */
3384 value = value + 11;
3385 /* Convert the value from ascii to integer */
3386 ret = kstrtou8(value, 10, &wesMode);
3387 if (ret < 0)
3388 {
3389 /* If the input value is greater than max value of datatype, then also
3390 kstrtou8 fails */
3391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3392 "%s: kstrtou8 failed range [%d - %d]", __func__,
3393 CFG_ENABLE_WES_MODE_NAME_MIN,
3394 CFG_ENABLE_WES_MODE_NAME_MAX);
3395 ret = -EINVAL;
3396 goto exit;
3397 }
3398
3399 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3400 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3401 {
3402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3403 "WES Mode value %d is out of range"
3404 " (Min: %d Max: %d)", wesMode,
3405 CFG_ENABLE_WES_MODE_NAME_MIN,
3406 CFG_ENABLE_WES_MODE_NAME_MAX);
3407 ret = -EINVAL;
3408 goto exit;
3409 }
3410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3411 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3412
3413 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3414 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3415 }
3416 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3417 {
3418 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3419 char extra[32];
3420 tANI_U8 len = 0;
3421
Arif Hussain826d9412013-11-12 16:44:54 -08003422 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003423 if (copy_to_user(priv_data.buf, &extra, len + 1))
3424 {
3425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3426 "%s: failed to copy data to user buffer", __func__);
3427 ret = -EFAULT;
3428 goto exit;
3429 }
3430 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003431#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003432#ifdef FEATURE_WLAN_LFR
3433 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3434 {
3435 tANI_U8 *value = command;
3436 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3437
3438 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3439 value = value + 12;
3440 /* Convert the value from ascii to integer */
3441 ret = kstrtou8(value, 10, &lfrMode);
3442 if (ret < 0)
3443 {
3444 /* If the input value is greater than max value of datatype, then also
3445 kstrtou8 fails */
3446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3447 "%s: kstrtou8 failed range [%d - %d]", __func__,
3448 CFG_LFR_FEATURE_ENABLED_MIN,
3449 CFG_LFR_FEATURE_ENABLED_MAX);
3450 ret = -EINVAL;
3451 goto exit;
3452 }
3453
3454 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3455 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3456 {
3457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3458 "lfr mode value %d is out of range"
3459 " (Min: %d Max: %d)", lfrMode,
3460 CFG_LFR_FEATURE_ENABLED_MIN,
3461 CFG_LFR_FEATURE_ENABLED_MAX);
3462 ret = -EINVAL;
3463 goto exit;
3464 }
3465
3466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3467 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3468
3469 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3470 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3471 }
3472#endif
3473#ifdef WLAN_FEATURE_VOWIFI_11R
3474 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3475 {
3476 tANI_U8 *value = command;
3477 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3478
3479 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3480 value = value + 18;
3481 /* Convert the value from ascii to integer */
3482 ret = kstrtou8(value, 10, &ft);
3483 if (ret < 0)
3484 {
3485 /* If the input value is greater than max value of datatype, then also
3486 kstrtou8 fails */
3487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3488 "%s: kstrtou8 failed range [%d - %d]", __func__,
3489 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3490 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3491 ret = -EINVAL;
3492 goto exit;
3493 }
3494
3495 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3496 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3497 {
3498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3499 "ft mode value %d is out of range"
3500 " (Min: %d Max: %d)", ft,
3501 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3502 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3503 ret = -EINVAL;
3504 goto exit;
3505 }
3506
3507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3508 "%s: Received Command to change ft mode = %d", __func__, ft);
3509
3510 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3511 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3512 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303513
3514 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3515 {
3516 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303517 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303518 tSirMacAddr targetApBssid;
3519 tANI_U8 trigger = 0;
3520 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303521 tHalHandle hHal;
3522 v_U32_t roamId = 0;
3523 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303524 hdd_station_ctx_t *pHddStaCtx = NULL;
3525 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303526 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303527
3528 /* if not associated, no need to proceed with reassoc */
3529 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3530 {
3531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3532 ret = -EINVAL;
3533 goto exit;
3534 }
3535
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303536 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303537 if (eHAL_STATUS_SUCCESS != status)
3538 {
3539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3540 "%s: Failed to parse reassoc command data", __func__);
3541 ret = -EINVAL;
3542 goto exit;
3543 }
3544
3545 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303546 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303547 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3548 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3549 {
3550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3551 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3552 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303553 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3554 &modProfileFields);
3555 sme_RoamReassoc(hHal, pAdapter->sessionId,
3556 NULL, modProfileFields, &roamId, 1);
3557 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303558 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303559
3560 /* Check channel number is a valid channel number */
3561 if(VOS_STATUS_SUCCESS !=
3562 wlan_hdd_validate_operation_channel(pAdapter, channel))
3563 {
3564 hddLog(VOS_TRACE_LEVEL_ERROR,
3565 "%s: Invalid Channel [%d]", __func__, channel);
3566 return -EINVAL;
3567 }
3568
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303569 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303570
3571 /* Proceed with scan/roam */
3572 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3573 &targetApBssid[0],
3574 (tSmeFastRoamTrigger)(trigger));
3575 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003576#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003577#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003578 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3579 {
3580 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003581 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003582
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003583 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003584 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003585 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003586 hdd_is_okc_mode_enabled(pHddCtx) &&
3587 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3588 {
3589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003590 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003591 " hence this operation is not permitted!", __func__);
3592 ret = -EPERM;
3593 goto exit;
3594 }
3595
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003596 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3597 value = value + 11;
3598 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003599 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003600 if (ret < 0)
3601 {
3602 /* If the input value is greater than max value of datatype, then also
3603 kstrtou8 fails */
3604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3605 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003606 CFG_ESE_FEATURE_ENABLED_MIN,
3607 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003608 ret = -EINVAL;
3609 goto exit;
3610 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003611 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3612 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003613 {
3614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003615 "Ese mode value %d is out of range"
3616 " (Min: %d Max: %d)", eseMode,
3617 CFG_ESE_FEATURE_ENABLED_MIN,
3618 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003619 ret = -EINVAL;
3620 goto exit;
3621 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003623 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003624
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003625 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3626 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003627 }
3628#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003629 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3630 {
3631 tANI_U8 *value = command;
3632 tANI_BOOLEAN roamScanControl = 0;
3633
3634 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3635 value = value + 19;
3636 /* Convert the value from ascii to integer */
3637 ret = kstrtou8(value, 10, &roamScanControl);
3638 if (ret < 0)
3639 {
3640 /* If the input value is greater than max value of datatype, then also
3641 kstrtou8 fails */
3642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3643 "%s: kstrtou8 failed ", __func__);
3644 ret = -EINVAL;
3645 goto exit;
3646 }
3647
3648 if (0 != roamScanControl)
3649 {
3650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3651 "roam scan control invalid value = %d",
3652 roamScanControl);
3653 ret = -EINVAL;
3654 goto exit;
3655 }
3656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3657 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3658
3659 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3660 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003661#ifdef FEATURE_WLAN_OKC
3662 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3663 {
3664 tANI_U8 *value = command;
3665 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3666
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003667 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003668 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003669 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003670 hdd_is_okc_mode_enabled(pHddCtx) &&
3671 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3672 {
3673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003674 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003675 " hence this operation is not permitted!", __func__);
3676 ret = -EPERM;
3677 goto exit;
3678 }
3679
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003680 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3681 value = value + 11;
3682 /* Convert the value from ascii to integer */
3683 ret = kstrtou8(value, 10, &okcMode);
3684 if (ret < 0)
3685 {
3686 /* If the input value is greater than max value of datatype, then also
3687 kstrtou8 fails */
3688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3689 "%s: kstrtou8 failed range [%d - %d]", __func__,
3690 CFG_OKC_FEATURE_ENABLED_MIN,
3691 CFG_OKC_FEATURE_ENABLED_MAX);
3692 ret = -EINVAL;
3693 goto exit;
3694 }
3695
3696 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3697 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3698 {
3699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3700 "Okc mode value %d is out of range"
3701 " (Min: %d Max: %d)", okcMode,
3702 CFG_OKC_FEATURE_ENABLED_MIN,
3703 CFG_OKC_FEATURE_ENABLED_MAX);
3704 ret = -EINVAL;
3705 goto exit;
3706 }
3707
3708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3709 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3710
3711 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3712 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003713#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003714 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3715 {
3716 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3717 char extra[32];
3718 tANI_U8 len = 0;
3719
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003720 len = scnprintf(extra, sizeof(extra), "%s %d",
3721 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003722 if (copy_to_user(priv_data.buf, &extra, len + 1))
3723 {
3724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3725 "%s: failed to copy data to user buffer", __func__);
3726 ret = -EFAULT;
3727 goto exit;
3728 }
3729 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303730#ifdef WLAN_FEATURE_PACKET_FILTERING
3731 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3732 {
3733 tANI_U8 filterType = 0;
3734 tANI_U8 *value = command;
3735
3736 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3737 value = value + 22;
3738
3739 /* Convert the value from ascii to integer */
3740 ret = kstrtou8(value, 10, &filterType);
3741 if (ret < 0)
3742 {
3743 /* If the input value is greater than max value of datatype,
3744 * then also kstrtou8 fails
3745 */
3746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3747 "%s: kstrtou8 failed range ", __func__);
3748 ret = -EINVAL;
3749 goto exit;
3750 }
3751
3752 if (filterType != 0 && filterType != 1)
3753 {
3754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3755 "%s: Accepted Values are 0 and 1 ", __func__);
3756 ret = -EINVAL;
3757 goto exit;
3758 }
3759 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3760 pAdapter->sessionId);
3761 }
3762#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303763 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3764 {
Kiet Lamad161252014-07-22 11:23:32 -07003765 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303766 int ret;
3767
Kiet Lamad161252014-07-22 11:23:32 -07003768 dhcpPhase = command + 11;
3769 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303770 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003772 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303773
3774 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003775
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303776 ret = wlan_hdd_scan_abort(pAdapter);
3777 if (ret < 0)
3778 {
3779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3780 FL("failed to abort existing scan %d"), ret);
3781 }
3782
Kiet Lamad161252014-07-22 11:23:32 -07003783 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3784 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303785 }
Kiet Lamad161252014-07-22 11:23:32 -07003786 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303787 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003789 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303790
3791 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003792
3793 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3794 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303795 }
3796 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003797 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3798 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3800 FL("making default scan to ACTIVE"));
3801 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003802 }
3803 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3804 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3806 FL("making default scan to PASSIVE"));
3807 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003808 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303809 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3810 {
3811 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3812 char extra[32];
3813 tANI_U8 len = 0;
3814
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303815 memset(extra, 0, sizeof(extra));
3816 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3817 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303818 {
3819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3820 "%s: failed to copy data to user buffer", __func__);
3821 ret = -EFAULT;
3822 goto exit;
3823 }
3824 ret = len;
3825 }
3826 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3827 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303828 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303829 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003830 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3831 {
3832 tANI_U8 filterType = 0;
3833 tANI_U8 *value;
3834 value = command + 9;
3835
3836 /* Convert the value from ascii to integer */
3837 ret = kstrtou8(value, 10, &filterType);
3838 if (ret < 0)
3839 {
3840 /* If the input value is greater than max value of datatype,
3841 * then also kstrtou8 fails
3842 */
3843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3844 "%s: kstrtou8 failed range ", __func__);
3845 ret = -EINVAL;
3846 goto exit;
3847 }
3848 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3849 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3850 {
3851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3852 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3853 " 2-Sink ", __func__);
3854 ret = -EINVAL;
3855 goto exit;
3856 }
3857 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3858 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303859 pScanInfo = &pHddCtx->scan_info;
3860 if (filterType && pScanInfo != NULL &&
3861 pHddCtx->scan_info.mScanPending)
3862 {
3863 /*Miracast Session started. Abort Scan */
3864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3865 "%s, Aborting Scan For Miracast",__func__);
3866 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3867 eCSR_SCAN_ABORT_DEFAULT);
3868 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003869 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303870 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003871 }
Leo Chang614d2072013-08-22 14:59:44 -07003872 else if (strncmp(command, "SETMCRATE", 9) == 0)
3873 {
Leo Chang614d2072013-08-22 14:59:44 -07003874 tANI_U8 *value = command;
3875 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003876 tSirRateUpdateInd *rateUpdate;
3877 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003878
3879 /* Only valid for SAP mode */
3880 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3881 {
3882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3883 "%s: SAP mode is not running", __func__);
3884 ret = -EFAULT;
3885 goto exit;
3886 }
3887
3888 /* Move pointer to ahead of SETMCRATE<delimiter> */
3889 /* input value is in units of hundred kbps */
3890 value = value + 10;
3891 /* Convert the value from ascii to integer, decimal base */
3892 ret = kstrtouint(value, 10, &targetRate);
3893
Leo Chang1f98cbd2013-10-17 15:03:52 -07003894 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3895 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003896 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003897 hddLog(VOS_TRACE_LEVEL_ERROR,
3898 "%s: SETMCRATE indication alloc fail", __func__);
3899 ret = -EFAULT;
3900 goto exit;
3901 }
3902 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3903
3904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3905 "MC Target rate %d", targetRate);
3906 /* Ignore unicast */
3907 rateUpdate->ucastDataRate = -1;
3908 rateUpdate->mcastDataRate24GHz = targetRate;
3909 rateUpdate->mcastDataRate5GHz = targetRate;
3910 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3911 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3912 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3913 if (eHAL_STATUS_SUCCESS != status)
3914 {
3915 hddLog(VOS_TRACE_LEVEL_ERROR,
3916 "%s: SET_MC_RATE failed", __func__);
3917 vos_mem_free(rateUpdate);
3918 ret = -EFAULT;
3919 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003920 }
3921 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303922#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003923 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303924 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003925 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303926 }
3927#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003928#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003929 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3930 {
3931 tANI_U8 *value = command;
3932 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3933 tANI_U8 numChannels = 0;
3934 eHalStatus status = eHAL_STATUS_SUCCESS;
3935
3936 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3937 if (eHAL_STATUS_SUCCESS != status)
3938 {
3939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3940 "%s: Failed to parse channel list information", __func__);
3941 ret = -EINVAL;
3942 goto exit;
3943 }
3944
3945 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3946 {
3947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3948 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3949 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3950 ret = -EINVAL;
3951 goto exit;
3952 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003953 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003954 ChannelList,
3955 numChannels);
3956 if (eHAL_STATUS_SUCCESS != status)
3957 {
3958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3959 "%s: Failed to update channel list information", __func__);
3960 ret = -EINVAL;
3961 goto exit;
3962 }
3963 }
3964 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3965 {
3966 tANI_U8 *value = command;
3967 char extra[128] = {0};
3968 int len = 0;
3969 tANI_U8 tid = 0;
3970 hdd_station_ctx_t *pHddStaCtx = NULL;
3971 tAniTrafStrmMetrics tsmMetrics;
3972 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3973
3974 /* if not associated, return error */
3975 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3976 {
3977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3978 ret = -EINVAL;
3979 goto exit;
3980 }
3981
3982 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3983 value = value + 12;
3984 /* Convert the value from ascii to integer */
3985 ret = kstrtou8(value, 10, &tid);
3986 if (ret < 0)
3987 {
3988 /* If the input value is greater than max value of datatype, then also
3989 kstrtou8 fails */
3990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3991 "%s: kstrtou8 failed range [%d - %d]", __func__,
3992 TID_MIN_VALUE,
3993 TID_MAX_VALUE);
3994 ret = -EINVAL;
3995 goto exit;
3996 }
3997
3998 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3999 {
4000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4001 "tid value %d is out of range"
4002 " (Min: %d Max: %d)", tid,
4003 TID_MIN_VALUE,
4004 TID_MAX_VALUE);
4005 ret = -EINVAL;
4006 goto exit;
4007 }
4008
4009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4010 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4011
4012 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4013 {
4014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4015 "%s: failed to get tsm stats", __func__);
4016 ret = -EFAULT;
4017 goto exit;
4018 }
4019
4020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4021 "UplinkPktQueueDly(%d)\n"
4022 "UplinkPktQueueDlyHist[0](%d)\n"
4023 "UplinkPktQueueDlyHist[1](%d)\n"
4024 "UplinkPktQueueDlyHist[2](%d)\n"
4025 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304026 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004027 "UplinkPktLoss(%d)\n"
4028 "UplinkPktCount(%d)\n"
4029 "RoamingCount(%d)\n"
4030 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4031 tsmMetrics.UplinkPktQueueDlyHist[0],
4032 tsmMetrics.UplinkPktQueueDlyHist[1],
4033 tsmMetrics.UplinkPktQueueDlyHist[2],
4034 tsmMetrics.UplinkPktQueueDlyHist[3],
4035 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4036 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4037
4038 /* Output TSM stats is of the format
4039 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4040 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004041 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004042 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4043 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4044 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4045 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4046 tsmMetrics.RoamingDly);
4047
4048 if (copy_to_user(priv_data.buf, &extra, len + 1))
4049 {
4050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4051 "%s: failed to copy data to user buffer", __func__);
4052 ret = -EFAULT;
4053 goto exit;
4054 }
4055 }
4056 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4057 {
4058 tANI_U8 *value = command;
4059 tANI_U8 *cckmIe = NULL;
4060 tANI_U8 cckmIeLen = 0;
4061 eHalStatus status = eHAL_STATUS_SUCCESS;
4062
4063 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4064 if (eHAL_STATUS_SUCCESS != status)
4065 {
4066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4067 "%s: Failed to parse cckm ie data", __func__);
4068 ret = -EINVAL;
4069 goto exit;
4070 }
4071
4072 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4073 {
4074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4075 "%s: CCKM Ie input length is more than max[%d]", __func__,
4076 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004077 vos_mem_free(cckmIe);
4078 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004079 ret = -EINVAL;
4080 goto exit;
4081 }
4082 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004083 vos_mem_free(cckmIe);
4084 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004085 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004086 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4087 {
4088 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004089 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004090 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004091
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004092 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004093 if (eHAL_STATUS_SUCCESS != status)
4094 {
4095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004096 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004097 ret = -EINVAL;
4098 goto exit;
4099 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004100 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4101 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4102 hdd_indicateEseBcnReportNoResults (pAdapter,
4103 eseBcnReq.bcnReq[0].measurementToken,
4104 0x02, //BIT(1) set for measurement done
4105 0); // no BSS
4106 goto exit;
4107 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004108
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004109 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4110 if (eHAL_STATUS_SUCCESS != status)
4111 {
4112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4113 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4114 ret = -EINVAL;
4115 goto exit;
4116 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004117 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004118#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304119 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4120 {
4121 eHalStatus status;
4122 char buf[32], len;
4123 long waitRet;
4124 bcnMissRateContext_t getBcnMissRateCtx;
4125
4126 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4127
4128 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4129 {
4130 hddLog(VOS_TRACE_LEVEL_WARN,
4131 FL("GETBCNMISSRATE: STA is not in connected state"));
4132 ret = -1;
4133 goto exit;
4134 }
4135
4136 init_completion(&(getBcnMissRateCtx.completion));
4137 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4138
4139 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4140 pAdapter->sessionId,
4141 (void *)getBcnMissRateCB,
4142 (void *)(&getBcnMissRateCtx));
4143 if( eHAL_STATUS_SUCCESS != status)
4144 {
4145 hddLog(VOS_TRACE_LEVEL_INFO,
4146 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4147 ret = -EINVAL;
4148 goto exit;
4149 }
4150
4151 waitRet = wait_for_completion_interruptible_timeout
4152 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4153 if(waitRet <= 0)
4154 {
4155 hddLog(VOS_TRACE_LEVEL_ERROR,
4156 FL("failed to wait on bcnMissRateComp %d"), ret);
4157
4158 //Make magic number to zero so that callback is not called.
4159 spin_lock(&hdd_context_lock);
4160 getBcnMissRateCtx.magic = 0x0;
4161 spin_unlock(&hdd_context_lock);
4162 ret = -EINVAL;
4163 goto exit;
4164 }
4165
4166 hddLog(VOS_TRACE_LEVEL_INFO,
4167 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4168
4169 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4170 if (copy_to_user(priv_data.buf, &buf, len + 1))
4171 {
4172 hddLog(VOS_TRACE_LEVEL_ERROR,
4173 "%s: failed to copy data to user buffer", __func__);
4174 ret = -EFAULT;
4175 goto exit;
4176 }
4177 ret = len;
4178 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304179#ifdef FEATURE_WLAN_TDLS
4180 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4181 tANI_U8 *value = command;
4182 int set_value;
4183 /* Move pointer to ahead of TDLSOFFCH*/
4184 value += 26;
4185 sscanf(value, "%d", &set_value);
4186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4187 "%s: Tdls offchannel offset:%d",
4188 __func__, set_value);
4189 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4190 if (ret < 0)
4191 {
4192 ret = -EINVAL;
4193 goto exit;
4194 }
4195
4196 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4197 tANI_U8 *value = command;
4198 int set_value;
4199 /* Move pointer to ahead of tdlsoffchnmode*/
4200 value += 18;
4201 sscanf(value, "%d", &set_value);
4202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4203 "%s: Tdls offchannel mode:%d",
4204 __func__, set_value);
4205 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4206 if (ret < 0)
4207 {
4208 ret = -EINVAL;
4209 goto exit;
4210 }
4211 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4212 tANI_U8 *value = command;
4213 int set_value;
4214 /* Move pointer to ahead of TDLSOFFCH*/
4215 value += 14;
4216 sscanf(value, "%d", &set_value);
4217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4218 "%s: Tdls offchannel num: %d",
4219 __func__, set_value);
4220 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4221 if (ret < 0)
4222 {
4223 ret = -EINVAL;
4224 goto exit;
4225 }
4226 }
4227#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304228 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4229 {
4230 eHalStatus status;
4231 char *buf = NULL;
4232 char len;
4233 long waitRet;
4234 fwStatsContext_t fwStatsCtx;
4235 fwStatsResult_t *fwStatsRsp = &(pAdapter->fwStatsRsp);
4236 tANI_U8 *ptr = command;
4237 int stats = *(ptr + 11) - '0';
4238
4239 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4240 if (!IS_FEATURE_FW_STATS_ENABLE)
4241 {
4242 hddLog(VOS_TRACE_LEVEL_INFO,
4243 FL("Get Firmware stats feature not supported"));
4244 ret = -EINVAL;
4245 goto exit;
4246 }
4247
4248 if (FW_STATS_MAX <= stats || 0 >= stats)
4249 {
4250 hddLog(VOS_TRACE_LEVEL_INFO,
4251 FL(" stats %d not supported"),stats);
4252 ret = -EINVAL;
4253 goto exit;
4254 }
4255
4256 init_completion(&(fwStatsCtx.completion));
4257 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4258 fwStatsCtx.pAdapter = pAdapter;
4259 fwStatsRsp->type = 0;
4260 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
4261 (&fwStatsCtx), hdd_FWStatisCB);
4262 if (eHAL_STATUS_SUCCESS != status)
4263 {
4264 hddLog(VOS_TRACE_LEVEL_ERROR,
4265 FL(" fail to post WDA cmd status = %d"), status);
4266 ret = -EINVAL;
4267 goto exit;
4268 }
4269 waitRet = wait_for_completion_timeout
4270 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4271 if (waitRet <= 0)
4272 {
4273 hddLog(VOS_TRACE_LEVEL_ERROR,
4274 FL("failed to wait on GwtFwstats"));
4275 //Make magic number to zero so that callback is not executed.
4276 spin_lock(&hdd_context_lock);
4277 fwStatsCtx.magic = 0x0;
4278 spin_unlock(&hdd_context_lock);
4279 ret = -EINVAL;
4280 goto exit;
4281 }
4282 if (fwStatsRsp->type)
4283 {
4284 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4285 if (!buf)
4286 {
4287 hddLog(VOS_TRACE_LEVEL_ERROR,
4288 FL(" failed to allocate memory"));
4289 ret = -ENOMEM;
4290 goto exit;
4291 }
4292 switch( fwStatsRsp->type )
4293 {
4294 case FW_UBSP_STATS:
4295 {
4296 len = snprintf(buf, FW_STATE_RSP_LEN,
4297 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
4298 fwStatsRsp->hddFwStatsData.ubspStats.ubsp_enter_cnt,
4299 fwStatsRsp->hddFwStatsData.ubspStats.ubsp_jump_ddr_cnt);
4300 }
4301 break;
4302 default:
4303 {
4304 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4305 ret = -EFAULT;
4306 kfree(buf);
4307 goto exit;
4308 }
4309 }
4310 if (copy_to_user(priv_data.buf, buf, len + 1))
4311 {
4312 hddLog(VOS_TRACE_LEVEL_ERROR,
4313 FL(" failed to copy data to user buffer"));
4314 ret = -EFAULT;
4315 kfree(buf);
4316 goto exit;
4317 }
4318 ret = len;
4319 kfree(buf);
4320 }
4321 else
4322 {
4323 hddLog(VOS_TRACE_LEVEL_ERROR,
4324 FL("failed to fetch the stats"));
4325 ret = -EFAULT;
4326 goto exit;
4327 }
4328
4329 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004330 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304331 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4332 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4333 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304334 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4335 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004336 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004337 }
4338exit:
4339 if (command)
4340 {
4341 kfree(command);
4342 }
4343 return ret;
4344}
4345
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004346#ifdef CONFIG_COMPAT
4347static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4348{
4349 struct {
4350 compat_uptr_t buf;
4351 int used_len;
4352 int total_len;
4353 } compat_priv_data;
4354 hdd_priv_data_t priv_data;
4355 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004356
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004357 /*
4358 * Note that pAdapter and ifr have already been verified by caller,
4359 * and HDD context has also been validated
4360 */
4361 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4362 sizeof(compat_priv_data))) {
4363 ret = -EFAULT;
4364 goto exit;
4365 }
4366 priv_data.buf = compat_ptr(compat_priv_data.buf);
4367 priv_data.used_len = compat_priv_data.used_len;
4368 priv_data.total_len = compat_priv_data.total_len;
4369 ret = hdd_driver_command(pAdapter, &priv_data);
4370 exit:
4371 return ret;
4372}
4373#else /* CONFIG_COMPAT */
4374static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4375{
4376 /* will never be invoked */
4377 return 0;
4378}
4379#endif /* CONFIG_COMPAT */
4380
4381static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4382{
4383 hdd_priv_data_t priv_data;
4384 int ret = 0;
4385
4386 /*
4387 * Note that pAdapter and ifr have already been verified by caller,
4388 * and HDD context has also been validated
4389 */
4390 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4391 ret = -EFAULT;
4392 } else {
4393 ret = hdd_driver_command(pAdapter, &priv_data);
4394 }
4395 return ret;
4396}
4397
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304398int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004399{
4400 hdd_adapter_t *pAdapter;
4401 hdd_context_t *pHddCtx;
4402 int ret;
4403
4404 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4405 if (NULL == pAdapter) {
4406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4407 "%s: HDD adapter context is Null", __func__);
4408 ret = -ENODEV;
4409 goto exit;
4410 }
4411 if (dev != pAdapter->dev) {
4412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4413 "%s: HDD adapter/dev inconsistency", __func__);
4414 ret = -ENODEV;
4415 goto exit;
4416 }
4417
4418 if ((!ifr) || (!ifr->ifr_data)) {
4419 ret = -EINVAL;
4420 goto exit;
4421 }
4422
4423 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4424 ret = wlan_hdd_validate_context(pHddCtx);
4425 if (ret) {
Mahesh A Saptasagar5b16d0a2014-11-03 17:55:29 +05304426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004427 "%s: invalid context", __func__);
4428 ret = -EBUSY;
4429 goto exit;
4430 }
4431
4432 switch (cmd) {
4433 case (SIOCDEVPRIVATE + 1):
4434 if (is_compat_task())
4435 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4436 else
4437 ret = hdd_driver_ioctl(pAdapter, ifr);
4438 break;
4439 default:
4440 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4441 __func__, cmd);
4442 ret = -EINVAL;
4443 break;
4444 }
4445 exit:
4446 return ret;
4447}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004448
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304449int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4450{
4451 int ret;
4452
4453 vos_ssr_protect(__func__);
4454 ret = __hdd_ioctl(dev, ifr, cmd);
4455 vos_ssr_unprotect(__func__);
4456
4457 return ret;
4458}
4459
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004460#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004461/**---------------------------------------------------------------------------
4462
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004463 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004464
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004465 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004466 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4467 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4468 <space>Scan Mode N<space>Meas Duration N
4469 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4470 then take N.
4471 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4472 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4473 This function does not take care of removing duplicate channels from the list
4474
4475 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004476 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004477
4478 \return - 0 for success non-zero for failure
4479
4480 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004481static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4482 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004483{
4484 tANI_U8 *inPtr = pValue;
4485 int tempInt = 0;
4486 int j = 0, i = 0, v = 0;
4487 char buf[32];
4488
4489 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4490 /*no argument after the command*/
4491 if (NULL == inPtr)
4492 {
4493 return -EINVAL;
4494 }
4495 /*no space after the command*/
4496 else if (SPACE_ASCII_VALUE != *inPtr)
4497 {
4498 return -EINVAL;
4499 }
4500
4501 /*removing empty spaces*/
4502 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4503
4504 /*no argument followed by spaces*/
4505 if ('\0' == *inPtr) return -EINVAL;
4506
4507 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004508 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004509 if (1 != v) return -EINVAL;
4510
4511 v = kstrtos32(buf, 10, &tempInt);
4512 if ( v < 0) return -EINVAL;
4513
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004514 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004515
4516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004517 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004518
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004519 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004520 {
4521 for (i = 0; i < 4; i++)
4522 {
4523 /*inPtr pointing to the beginning of first space after number of ie fields*/
4524 inPtr = strpbrk( inPtr, " " );
4525 /*no ie data after the number of ie fields argument*/
4526 if (NULL == inPtr) return -EINVAL;
4527
4528 /*removing empty space*/
4529 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4530
4531 /*no ie data after the number of ie fields argument and spaces*/
4532 if ( '\0' == *inPtr ) return -EINVAL;
4533
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004534 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004535 if (1 != v) return -EINVAL;
4536
4537 v = kstrtos32(buf, 10, &tempInt);
4538 if (v < 0) return -EINVAL;
4539
4540 switch (i)
4541 {
4542 case 0: /* Measurement token */
4543 if (tempInt <= 0)
4544 {
4545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4546 "Invalid Measurement Token(%d)", tempInt);
4547 return -EINVAL;
4548 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004549 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004550 break;
4551
4552 case 1: /* Channel number */
4553 if ((tempInt <= 0) ||
4554 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4555 {
4556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4557 "Invalid Channel Number(%d)", tempInt);
4558 return -EINVAL;
4559 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004560 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004561 break;
4562
4563 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004564 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004565 {
4566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4567 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4568 return -EINVAL;
4569 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004570 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004571 break;
4572
4573 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004574 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4575 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004576 {
4577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4578 "Invalid Measurement Duration(%d)", tempInt);
4579 return -EINVAL;
4580 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004581 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004582 break;
4583 }
4584 }
4585 }
4586
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004587 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004588 {
4589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304590 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004591 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004592 pEseBcnReq->bcnReq[j].measurementToken,
4593 pEseBcnReq->bcnReq[j].channel,
4594 pEseBcnReq->bcnReq[j].scanMode,
4595 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004596 }
4597
4598 return VOS_STATUS_SUCCESS;
4599}
4600
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004601static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4602{
4603 struct statsContext *pStatsContext = NULL;
4604 hdd_adapter_t *pAdapter = NULL;
4605
4606 if (NULL == pContext)
4607 {
4608 hddLog(VOS_TRACE_LEVEL_ERROR,
4609 "%s: Bad param, pContext [%p]",
4610 __func__, pContext);
4611 return;
4612 }
4613
Jeff Johnson72a40512013-12-19 10:14:15 -08004614 /* there is a race condition that exists between this callback
4615 function and the caller since the caller could time out either
4616 before or while this code is executing. we use a spinlock to
4617 serialize these actions */
4618 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004619
4620 pStatsContext = pContext;
4621 pAdapter = pStatsContext->pAdapter;
4622 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4623 {
4624 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004625 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004626 hddLog(VOS_TRACE_LEVEL_WARN,
4627 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4628 __func__, pAdapter, pStatsContext->magic);
4629 return;
4630 }
4631
Jeff Johnson72a40512013-12-19 10:14:15 -08004632 /* context is valid so caller is still waiting */
4633
4634 /* paranoia: invalidate the magic */
4635 pStatsContext->magic = 0;
4636
4637 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004638 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4639 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4640 tsmMetrics.UplinkPktQueueDlyHist,
4641 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4642 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4643 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4644 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4645 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4646 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4647 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4648
Jeff Johnson72a40512013-12-19 10:14:15 -08004649 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004650 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004651
4652 /* serialization is complete */
4653 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004654}
4655
4656
4657
4658static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4659 tAniTrafStrmMetrics* pTsmMetrics)
4660{
4661 hdd_station_ctx_t *pHddStaCtx = NULL;
4662 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004663 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004664 long lrc;
4665 struct statsContext context;
4666 hdd_context_t *pHddCtx = NULL;
4667
4668 if (NULL == pAdapter)
4669 {
4670 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4671 return VOS_STATUS_E_FAULT;
4672 }
4673
4674 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4675 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4676
4677 /* we are connected prepare our callback context */
4678 init_completion(&context.completion);
4679 context.pAdapter = pAdapter;
4680 context.magic = STATS_CONTEXT_MAGIC;
4681
4682 /* query tsm stats */
4683 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4684 pHddStaCtx->conn_info.staId[ 0 ],
4685 pHddStaCtx->conn_info.bssId,
4686 &context, pHddCtx->pvosContext, tid);
4687
4688 if (eHAL_STATUS_SUCCESS != hstatus)
4689 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4691 __func__);
4692 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004693 }
4694 else
4695 {
4696 /* request was sent -- wait for the response */
4697 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4698 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004699 if (lrc <= 0)
4700 {
4701 hddLog(VOS_TRACE_LEVEL_ERROR,
4702 "%s: SME %s while retrieving statistics",
4703 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004704 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004705 }
4706 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004707
Jeff Johnson72a40512013-12-19 10:14:15 -08004708 /* either we never sent a request, we sent a request and received a
4709 response or we sent a request and timed out. if we never sent a
4710 request or if we sent a request and got a response, we want to
4711 clear the magic out of paranoia. if we timed out there is a
4712 race condition such that the callback function could be
4713 executing at the same time we are. of primary concern is if the
4714 callback function had already verified the "magic" but had not
4715 yet set the completion variable when a timeout occurred. we
4716 serialize these activities by invalidating the magic while
4717 holding a shared spinlock which will cause us to block if the
4718 callback is currently executing */
4719 spin_lock(&hdd_context_lock);
4720 context.magic = 0;
4721 spin_unlock(&hdd_context_lock);
4722
4723 if (VOS_STATUS_SUCCESS == vstatus)
4724 {
4725 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4726 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4727 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4728 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4729 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4730 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4731 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4732 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4733 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4734 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4735 }
4736 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004737}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004738#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004739
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004740#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004741void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4742{
4743 eCsrBand band = -1;
4744 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4745 switch (band)
4746 {
4747 case eCSR_BAND_ALL:
4748 *pBand = WLAN_HDD_UI_BAND_AUTO;
4749 break;
4750
4751 case eCSR_BAND_24:
4752 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4753 break;
4754
4755 case eCSR_BAND_5G:
4756 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4757 break;
4758
4759 default:
4760 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4761 *pBand = -1;
4762 break;
4763 }
4764}
4765
4766/**---------------------------------------------------------------------------
4767
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004768 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4769
4770 This function parses the send action frame data passed in the format
4771 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4772
Srinivas Girigowda56076852013-08-20 14:00:50 -07004773 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004774 \param - pTargetApBssid Pointer to target Ap bssid
4775 \param - pChannel Pointer to the Target AP channel
4776 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4777 \param - pBuf Pointer to data
4778 \param - pBufLen Pointer to data length
4779
4780 \return - 0 for success non-zero for failure
4781
4782 --------------------------------------------------------------------------*/
4783VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4784 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4785{
4786 tANI_U8 *inPtr = pValue;
4787 tANI_U8 *dataEnd;
4788 int tempInt;
4789 int j = 0;
4790 int i = 0;
4791 int v = 0;
4792 tANI_U8 tempBuf[32];
4793 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004794 /* 12 hexa decimal digits, 5 ':' and '\0' */
4795 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004796
4797 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4798 /*no argument after the command*/
4799 if (NULL == inPtr)
4800 {
4801 return -EINVAL;
4802 }
4803
4804 /*no space after the command*/
4805 else if (SPACE_ASCII_VALUE != *inPtr)
4806 {
4807 return -EINVAL;
4808 }
4809
4810 /*removing empty spaces*/
4811 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4812
4813 /*no argument followed by spaces*/
4814 if ('\0' == *inPtr)
4815 {
4816 return -EINVAL;
4817 }
4818
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004819 v = sscanf(inPtr, "%17s", macAddress);
4820 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004821 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4823 "Invalid MAC address or All hex inputs are not read (%d)", v);
4824 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004825 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004826
4827 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4828 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4829 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4830 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4831 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4832 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004833
4834 /* point to the next argument */
4835 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4836 /*no argument after the command*/
4837 if (NULL == inPtr) return -EINVAL;
4838
4839 /*removing empty spaces*/
4840 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4841
4842 /*no argument followed by spaces*/
4843 if ('\0' == *inPtr)
4844 {
4845 return -EINVAL;
4846 }
4847
4848 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004849 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004850 if (1 != v) return -EINVAL;
4851
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004852 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304853 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304854 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004855
4856 *pChannel = tempInt;
4857
4858 /* point to the next argument */
4859 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4860 /*no argument after the command*/
4861 if (NULL == inPtr) return -EINVAL;
4862 /*removing empty spaces*/
4863 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4864
4865 /*no argument followed by spaces*/
4866 if ('\0' == *inPtr)
4867 {
4868 return -EINVAL;
4869 }
4870
4871 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004872 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004873 if (1 != v) return -EINVAL;
4874
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004875 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004876 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004877
4878 *pDwellTime = tempInt;
4879
4880 /* point to the next argument */
4881 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4882 /*no argument after the command*/
4883 if (NULL == inPtr) return -EINVAL;
4884 /*removing empty spaces*/
4885 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4886
4887 /*no argument followed by spaces*/
4888 if ('\0' == *inPtr)
4889 {
4890 return -EINVAL;
4891 }
4892
4893 /* find the length of data */
4894 dataEnd = inPtr;
4895 while(('\0' != *dataEnd) )
4896 {
4897 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004898 }
Kiet Lambe150c22013-11-21 16:30:32 +05304899 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004900 if ( *pBufLen <= 0) return -EINVAL;
4901
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004902 /* Allocate the number of bytes based on the number of input characters
4903 whether it is even or odd.
4904 if the number of input characters are even, then we need N/2 byte.
4905 if the number of input characters are odd, then we need do (N+1)/2 to
4906 compensate rounding off.
4907 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4908 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4909 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004910 if (NULL == *pBuf)
4911 {
4912 hddLog(VOS_TRACE_LEVEL_FATAL,
4913 "%s: vos_mem_alloc failed ", __func__);
4914 return -EINVAL;
4915 }
4916
4917 /* the buffer received from the upper layer is character buffer,
4918 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4919 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4920 and f0 in 3rd location */
4921 for (i = 0, j = 0; j < *pBufLen; j += 2)
4922 {
Kiet Lambe150c22013-11-21 16:30:32 +05304923 if( j+1 == *pBufLen)
4924 {
4925 tempByte = hdd_parse_hex(inPtr[j]);
4926 }
4927 else
4928 {
4929 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4930 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004931 (*pBuf)[i++] = tempByte;
4932 }
4933 *pBufLen = i;
4934 return VOS_STATUS_SUCCESS;
4935}
4936
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004937/**---------------------------------------------------------------------------
4938
Srinivas Girigowdade697412013-02-14 16:31:48 -08004939 \brief hdd_parse_channellist() - HDD Parse channel list
4940
4941 This function parses the channel list passed in the format
4942 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004943 if the Number of channels (N) does not match with the actual number of channels passed
4944 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4945 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4946 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4947 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004948
4949 \param - pValue Pointer to input channel list
4950 \param - ChannelList Pointer to local output array to record channel list
4951 \param - pNumChannels Pointer to number of roam scan channels
4952
4953 \return - 0 for success non-zero for failure
4954
4955 --------------------------------------------------------------------------*/
4956VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4957{
4958 tANI_U8 *inPtr = pValue;
4959 int tempInt;
4960 int j = 0;
4961 int v = 0;
4962 char buf[32];
4963
4964 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4965 /*no argument after the command*/
4966 if (NULL == inPtr)
4967 {
4968 return -EINVAL;
4969 }
4970
4971 /*no space after the command*/
4972 else if (SPACE_ASCII_VALUE != *inPtr)
4973 {
4974 return -EINVAL;
4975 }
4976
4977 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004978 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004979
4980 /*no argument followed by spaces*/
4981 if ('\0' == *inPtr)
4982 {
4983 return -EINVAL;
4984 }
4985
4986 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004987 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004988 if (1 != v) return -EINVAL;
4989
Srinivas Girigowdade697412013-02-14 16:31:48 -08004990 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004991 if ((v < 0) ||
4992 (tempInt <= 0) ||
4993 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4994 {
4995 return -EINVAL;
4996 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004997
4998 *pNumChannels = tempInt;
4999
5000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5001 "Number of channels are: %d", *pNumChannels);
5002
5003 for (j = 0; j < (*pNumChannels); j++)
5004 {
5005 /*inPtr pointing to the beginning of first space after number of channels*/
5006 inPtr = strpbrk( inPtr, " " );
5007 /*no channel list after the number of channels argument*/
5008 if (NULL == inPtr)
5009 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005010 if (0 != j)
5011 {
5012 *pNumChannels = j;
5013 return VOS_STATUS_SUCCESS;
5014 }
5015 else
5016 {
5017 return -EINVAL;
5018 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005019 }
5020
5021 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005022 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005023
5024 /*no channel list after the number of channels argument and spaces*/
5025 if ( '\0' == *inPtr )
5026 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005027 if (0 != j)
5028 {
5029 *pNumChannels = j;
5030 return VOS_STATUS_SUCCESS;
5031 }
5032 else
5033 {
5034 return -EINVAL;
5035 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005036 }
5037
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005038 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005039 if (1 != v) return -EINVAL;
5040
Srinivas Girigowdade697412013-02-14 16:31:48 -08005041 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005042 if ((v < 0) ||
5043 (tempInt <= 0) ||
5044 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5045 {
5046 return -EINVAL;
5047 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005048 pChannelList[j] = tempInt;
5049
5050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5051 "Channel %d added to preferred channel list",
5052 pChannelList[j] );
5053 }
5054
Srinivas Girigowdade697412013-02-14 16:31:48 -08005055 return VOS_STATUS_SUCCESS;
5056}
5057
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005058
5059/**---------------------------------------------------------------------------
5060
5061 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5062
5063 This function parses the reasoc command data passed in the format
5064 REASSOC<space><bssid><space><channel>
5065
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005066 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005067 \param - pTargetApBssid Pointer to target Ap bssid
5068 \param - pChannel Pointer to the Target AP channel
5069
5070 \return - 0 for success non-zero for failure
5071
5072 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005073VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5074 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005075{
5076 tANI_U8 *inPtr = pValue;
5077 int tempInt;
5078 int v = 0;
5079 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005080 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005081 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005082
5083 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5084 /*no argument after the command*/
5085 if (NULL == inPtr)
5086 {
5087 return -EINVAL;
5088 }
5089
5090 /*no space after the command*/
5091 else if (SPACE_ASCII_VALUE != *inPtr)
5092 {
5093 return -EINVAL;
5094 }
5095
5096 /*removing empty spaces*/
5097 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5098
5099 /*no argument followed by spaces*/
5100 if ('\0' == *inPtr)
5101 {
5102 return -EINVAL;
5103 }
5104
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005105 v = sscanf(inPtr, "%17s", macAddress);
5106 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005107 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5109 "Invalid MAC address or All hex inputs are not read (%d)", v);
5110 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005111 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005112
5113 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5114 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5115 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5116 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5117 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5118 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005119
5120 /* point to the next argument */
5121 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5122 /*no argument after the command*/
5123 if (NULL == inPtr) return -EINVAL;
5124
5125 /*removing empty spaces*/
5126 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5127
5128 /*no argument followed by spaces*/
5129 if ('\0' == *inPtr)
5130 {
5131 return -EINVAL;
5132 }
5133
5134 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005135 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005136 if (1 != v) return -EINVAL;
5137
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005138 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005139 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305140 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005141 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5142 {
5143 return -EINVAL;
5144 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005145
5146 *pChannel = tempInt;
5147 return VOS_STATUS_SUCCESS;
5148}
5149
5150#endif
5151
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005152#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005153/**---------------------------------------------------------------------------
5154
5155 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5156
5157 This function parses the SETCCKM IE command
5158 SETCCKMIE<space><ie data>
5159
5160 \param - pValue Pointer to input data
5161 \param - pCckmIe Pointer to output cckm Ie
5162 \param - pCckmIeLen Pointer to output cckm ie length
5163
5164 \return - 0 for success non-zero for failure
5165
5166 --------------------------------------------------------------------------*/
5167VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5168 tANI_U8 *pCckmIeLen)
5169{
5170 tANI_U8 *inPtr = pValue;
5171 tANI_U8 *dataEnd;
5172 int j = 0;
5173 int i = 0;
5174 tANI_U8 tempByte = 0;
5175
5176 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5177 /*no argument after the command*/
5178 if (NULL == inPtr)
5179 {
5180 return -EINVAL;
5181 }
5182
5183 /*no space after the command*/
5184 else if (SPACE_ASCII_VALUE != *inPtr)
5185 {
5186 return -EINVAL;
5187 }
5188
5189 /*removing empty spaces*/
5190 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5191
5192 /*no argument followed by spaces*/
5193 if ('\0' == *inPtr)
5194 {
5195 return -EINVAL;
5196 }
5197
5198 /* find the length of data */
5199 dataEnd = inPtr;
5200 while(('\0' != *dataEnd) )
5201 {
5202 dataEnd++;
5203 ++(*pCckmIeLen);
5204 }
5205 if ( *pCckmIeLen <= 0) return -EINVAL;
5206
5207 /* Allocate the number of bytes based on the number of input characters
5208 whether it is even or odd.
5209 if the number of input characters are even, then we need N/2 byte.
5210 if the number of input characters are odd, then we need do (N+1)/2 to
5211 compensate rounding off.
5212 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5213 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5214 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5215 if (NULL == *pCckmIe)
5216 {
5217 hddLog(VOS_TRACE_LEVEL_FATAL,
5218 "%s: vos_mem_alloc failed ", __func__);
5219 return -EINVAL;
5220 }
5221 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5222 /* the buffer received from the upper layer is character buffer,
5223 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5224 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5225 and f0 in 3rd location */
5226 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5227 {
5228 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5229 (*pCckmIe)[i++] = tempByte;
5230 }
5231 *pCckmIeLen = i;
5232
5233 return VOS_STATUS_SUCCESS;
5234}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005235#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005236
Jeff Johnson295189b2012-06-20 16:38:30 -07005237/**---------------------------------------------------------------------------
5238
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005239 \brief hdd_is_valid_mac_address() - Validate MAC address
5240
5241 This function validates whether the given MAC address is valid or not
5242 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5243 where X is the hexa decimal digit character and separated by ':'
5244 This algorithm works even if MAC address is not separated by ':'
5245
5246 This code checks given input string mac contains exactly 12 hexadecimal digits.
5247 and a separator colon : appears in the input string only after
5248 an even number of hex digits.
5249
5250 \param - pMacAddr pointer to the input MAC address
5251 \return - 1 for valid and 0 for invalid
5252
5253 --------------------------------------------------------------------------*/
5254
5255v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5256{
5257 int xdigit = 0;
5258 int separator = 0;
5259 while (*pMacAddr)
5260 {
5261 if (isxdigit(*pMacAddr))
5262 {
5263 xdigit++;
5264 }
5265 else if (':' == *pMacAddr)
5266 {
5267 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5268 break;
5269
5270 ++separator;
5271 }
5272 else
5273 {
5274 separator = -1;
5275 /* Invalid MAC found */
5276 return 0;
5277 }
5278 ++pMacAddr;
5279 }
5280 return (xdigit == 12 && (separator == 5 || separator == 0));
5281}
5282
5283/**---------------------------------------------------------------------------
5284
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305285 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005286
5287 \param - dev Pointer to net_device structure
5288
5289 \return - 0 for success non-zero for failure
5290
5291 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305292int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005293{
5294 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5295 hdd_context_t *pHddCtx;
5296 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5297 VOS_STATUS status;
5298 v_BOOL_t in_standby = TRUE;
5299
5300 if (NULL == pAdapter)
5301 {
5302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305303 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005304 return -ENODEV;
5305 }
5306
5307 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305308 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5309 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005310 if (NULL == pHddCtx)
5311 {
5312 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005313 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005314 return -ENODEV;
5315 }
5316
5317 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5318 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5319 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005320 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5321 {
5322 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305323 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005324 in_standby = FALSE;
5325 break;
5326 }
5327 else
5328 {
5329 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5330 pAdapterNode = pNext;
5331 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005332 }
5333
5334 if (TRUE == in_standby)
5335 {
5336 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5337 {
5338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5339 "wlan out of power save", __func__);
5340 return -EINVAL;
5341 }
5342 }
5343
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005344 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005345 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5346 {
5347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005348 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 /* Enable TX queues only when we are connected */
5350 netif_tx_start_all_queues(dev);
5351 }
5352
5353 return 0;
5354}
5355
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305356/**---------------------------------------------------------------------------
5357
5358 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5359
5360 This is called in response to ifconfig up
5361
5362 \param - dev Pointer to net_device structure
5363
5364 \return - 0 for success non-zero for failure
5365
5366 --------------------------------------------------------------------------*/
5367int hdd_open(struct net_device *dev)
5368{
5369 int ret;
5370
5371 vos_ssr_protect(__func__);
5372 ret = __hdd_open(dev);
5373 vos_ssr_unprotect(__func__);
5374
5375 return ret;
5376}
5377
Jeff Johnson295189b2012-06-20 16:38:30 -07005378int hdd_mon_open (struct net_device *dev)
5379{
5380 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5381
5382 if(pAdapter == NULL) {
5383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005384 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005385 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005386 }
5387
5388 netif_start_queue(dev);
5389
5390 return 0;
5391}
5392/**---------------------------------------------------------------------------
5393
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305394 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005395
5396 \param - dev Pointer to net_device structure
5397
5398 \return - 0 for success non-zero for failure
5399
5400 --------------------------------------------------------------------------*/
5401
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305402int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005403{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305404 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005405 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5406 hdd_context_t *pHddCtx;
5407 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5408 VOS_STATUS status;
5409 v_BOOL_t enter_standby = TRUE;
5410
5411 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005412 if (NULL == pAdapter)
5413 {
5414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305415 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005416 return -ENODEV;
5417 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305418 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5419 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305420
5421 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5422 ret = wlan_hdd_validate_context(pHddCtx);
5423 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005424 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5426 "%s: HDD context is not valid!", __func__);
5427 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 }
5429
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305430 /* Nothing to be done if the interface is not opened */
5431 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5432 {
5433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5434 "%s: NETDEV Interface is not OPENED", __func__);
5435 return -ENODEV;
5436 }
5437
5438 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005439 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005440 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305441
5442 /* Disable TX on the interface, after this hard_start_xmit() will not
5443 * be called on that interface
5444 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305446
5447 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005448 netif_carrier_off(pAdapter->dev);
5449
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305450 /* The interface is marked as down for outside world (aka kernel)
5451 * But the driver is pretty much alive inside. The driver needs to
5452 * tear down the existing connection on the netdev (session)
5453 * cleanup the data pipes and wait until the control plane is stabilized
5454 * for this interface. The call also needs to wait until the above
5455 * mentioned actions are completed before returning to the caller.
5456 * Notice that the hdd_stop_adapter is requested not to close the session
5457 * That is intentional to be able to scan if it is a STA/P2P interface
5458 */
5459 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07005460
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305461 /* DeInit the adapter. This ensures datapath cleanup as well */
5462 hdd_deinit_adapter(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005463 /* SoftAP ifaces should never go in power save mode
5464 making sure same here. */
5465 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5466 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005467 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005468 )
5469 {
5470 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5472 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 EXIT();
5474 return 0;
5475 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305476 /* Find if any iface is up. If any iface is up then can't put device to
5477 * sleep/power save mode
5478 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5480 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5481 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005482 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5483 {
5484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305485 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005486 enter_standby = FALSE;
5487 break;
5488 }
5489 else
5490 {
5491 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5492 pAdapterNode = pNext;
5493 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 }
5495
5496 if (TRUE == enter_standby)
5497 {
5498 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5499 "entering standby", __func__);
5500 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5501 {
5502 /*log and return success*/
5503 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5504 "wlan in power save", __func__);
5505 }
5506 }
5507
5508 EXIT();
5509 return 0;
5510}
5511
5512/**---------------------------------------------------------------------------
5513
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305514 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005515
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305516 This is called in response to ifconfig down
5517
5518 \param - dev Pointer to net_device structure
5519
5520 \return - 0 for success non-zero for failure
5521-----------------------------------------------------------------------------*/
5522int hdd_stop (struct net_device *dev)
5523{
5524 int ret;
5525
5526 vos_ssr_protect(__func__);
5527 ret = __hdd_stop(dev);
5528 vos_ssr_unprotect(__func__);
5529
5530 return ret;
5531}
5532
5533/**---------------------------------------------------------------------------
5534
5535 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005536
5537 \param - dev Pointer to net_device structure
5538
5539 \return - void
5540
5541 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305542static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005543{
5544 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5545
5546 ENTER();
5547
5548 do
5549 {
5550 if (NULL == pAdapter)
5551 {
5552 hddLog(VOS_TRACE_LEVEL_FATAL,
5553 "%s: NULL pAdapter", __func__);
5554 break;
5555 }
5556
5557 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5558 {
5559 hddLog(VOS_TRACE_LEVEL_FATAL,
5560 "%s: Invalid magic", __func__);
5561 break;
5562 }
5563
5564 if (NULL == pAdapter->pHddCtx)
5565 {
5566 hddLog(VOS_TRACE_LEVEL_FATAL,
5567 "%s: NULL pHddCtx", __func__);
5568 break;
5569 }
5570
5571 if (dev != pAdapter->dev)
5572 {
5573 hddLog(VOS_TRACE_LEVEL_FATAL,
5574 "%s: Invalid device reference", __func__);
5575 /* we haven't validated all cases so let this go for now */
5576 }
5577
5578 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5579
5580 /* after uninit our adapter structure will no longer be valid */
5581 pAdapter->dev = NULL;
5582 pAdapter->magic = 0;
5583 } while (0);
5584
5585 EXIT();
5586}
5587
5588/**---------------------------------------------------------------------------
5589
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305590 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5591
5592 This is called during the netdev unregister to uninitialize all data
5593associated with the device
5594
5595 \param - dev Pointer to net_device structure
5596
5597 \return - void
5598
5599 --------------------------------------------------------------------------*/
5600static void hdd_uninit (struct net_device *dev)
5601{
5602 vos_ssr_protect(__func__);
5603 __hdd_uninit(dev);
5604 vos_ssr_unprotect(__func__);
5605}
5606
5607/**---------------------------------------------------------------------------
5608
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 \brief hdd_release_firmware() -
5610
5611 This function calls the release firmware API to free the firmware buffer.
5612
5613 \param - pFileName Pointer to the File Name.
5614 pCtx - Pointer to the adapter .
5615
5616
5617 \return - 0 for success, non zero for failure
5618
5619 --------------------------------------------------------------------------*/
5620
5621VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5622{
5623 VOS_STATUS status = VOS_STATUS_SUCCESS;
5624 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5625 ENTER();
5626
5627
5628 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5629
5630 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5631
5632 if(pHddCtx->fw) {
5633 release_firmware(pHddCtx->fw);
5634 pHddCtx->fw = NULL;
5635 }
5636 else
5637 status = VOS_STATUS_E_FAILURE;
5638 }
5639 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5640 if(pHddCtx->nv) {
5641 release_firmware(pHddCtx->nv);
5642 pHddCtx->nv = NULL;
5643 }
5644 else
5645 status = VOS_STATUS_E_FAILURE;
5646
5647 }
5648
5649 EXIT();
5650 return status;
5651}
5652
5653/**---------------------------------------------------------------------------
5654
5655 \brief hdd_request_firmware() -
5656
5657 This function reads the firmware file using the request firmware
5658 API and returns the the firmware data and the firmware file size.
5659
5660 \param - pfileName - Pointer to the file name.
5661 - pCtx - Pointer to the adapter .
5662 - ppfw_data - Pointer to the pointer of the firmware data.
5663 - pSize - Pointer to the file size.
5664
5665 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5666
5667 --------------------------------------------------------------------------*/
5668
5669
5670VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5671{
5672 int status;
5673 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5674 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5675 ENTER();
5676
5677 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5678
5679 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5680
5681 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5682 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5683 __func__, pfileName);
5684 retval = VOS_STATUS_E_FAILURE;
5685 }
5686
5687 else {
5688 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5689 *pSize = pHddCtx->fw->size;
5690 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5691 __func__, *pSize);
5692 }
5693 }
5694 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5695
5696 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5697
5698 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5699 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5700 __func__, pfileName);
5701 retval = VOS_STATUS_E_FAILURE;
5702 }
5703
5704 else {
5705 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5706 *pSize = pHddCtx->nv->size;
5707 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5708 __func__, *pSize);
5709 }
5710 }
5711
5712 EXIT();
5713 return retval;
5714}
5715/**---------------------------------------------------------------------------
5716 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5717
5718 This is the function invoked by SME to inform the result of a full power
5719 request issued by HDD
5720
5721 \param - callbackcontext - Pointer to cookie
5722 status - result of request
5723
5724 \return - None
5725
5726--------------------------------------------------------------------------*/
5727void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5728{
5729 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5730
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005731 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 if(&pHddCtx->full_pwr_comp_var)
5733 {
5734 complete(&pHddCtx->full_pwr_comp_var);
5735 }
5736}
5737
5738/**---------------------------------------------------------------------------
5739
5740 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5741
5742 This is the function invoked by SME to inform the result of BMPS
5743 request issued by HDD
5744
5745 \param - callbackcontext - Pointer to cookie
5746 status - result of request
5747
5748 \return - None
5749
5750--------------------------------------------------------------------------*/
5751void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5752{
5753
5754 struct completion *completion_var = (struct completion*) callbackContext;
5755
Arif Hussain6d2a3322013-11-17 19:50:10 -08005756 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005757 if(completion_var != NULL)
5758 {
5759 complete(completion_var);
5760 }
5761}
5762
5763/**---------------------------------------------------------------------------
5764
5765 \brief hdd_get_cfg_file_size() -
5766
5767 This function reads the configuration file using the request firmware
5768 API and returns the configuration file size.
5769
5770 \param - pCtx - Pointer to the adapter .
5771 - pFileName - Pointer to the file name.
5772 - pBufSize - Pointer to the buffer size.
5773
5774 \return - 0 for success, non zero for failure
5775
5776 --------------------------------------------------------------------------*/
5777
5778VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5779{
5780 int status;
5781 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5782
5783 ENTER();
5784
5785 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5786
5787 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5788 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5789 status = VOS_STATUS_E_FAILURE;
5790 }
5791 else {
5792 *pBufSize = pHddCtx->fw->size;
5793 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5794 release_firmware(pHddCtx->fw);
5795 pHddCtx->fw = NULL;
5796 }
5797
5798 EXIT();
5799 return VOS_STATUS_SUCCESS;
5800}
5801
5802/**---------------------------------------------------------------------------
5803
5804 \brief hdd_read_cfg_file() -
5805
5806 This function reads the configuration file using the request firmware
5807 API and returns the cfg data and the buffer size of the configuration file.
5808
5809 \param - pCtx - Pointer to the adapter .
5810 - pFileName - Pointer to the file name.
5811 - pBuffer - Pointer to the data buffer.
5812 - pBufSize - Pointer to the buffer size.
5813
5814 \return - 0 for success, non zero for failure
5815
5816 --------------------------------------------------------------------------*/
5817
5818VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5819 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5820{
5821 int status;
5822 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5823
5824 ENTER();
5825
5826 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5827
5828 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5829 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5830 return VOS_STATUS_E_FAILURE;
5831 }
5832 else {
5833 if(*pBufSize != pHddCtx->fw->size) {
5834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5835 "file size", __func__);
5836 release_firmware(pHddCtx->fw);
5837 pHddCtx->fw = NULL;
5838 return VOS_STATUS_E_FAILURE;
5839 }
5840 else {
5841 if(pBuffer) {
5842 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5843 }
5844 release_firmware(pHddCtx->fw);
5845 pHddCtx->fw = NULL;
5846 }
5847 }
5848
5849 EXIT();
5850
5851 return VOS_STATUS_SUCCESS;
5852}
5853
5854/**---------------------------------------------------------------------------
5855
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305856 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005857
5858 This function sets the user specified mac address using
5859 the command ifconfig wlanX hw ether <mac adress>.
5860
5861 \param - dev - Pointer to the net device.
5862 - addr - Pointer to the sockaddr.
5863 \return - 0 for success, non zero for failure
5864
5865 --------------------------------------------------------------------------*/
5866
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305867static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005868{
5869 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5870 struct sockaddr *psta_mac_addr = addr;
5871 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5872
5873 ENTER();
5874
5875 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5877
5878 EXIT();
5879 return halStatus;
5880}
5881
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305882/**---------------------------------------------------------------------------
5883
5884 \brief hdd_set_mac_address() -
5885
5886 Wrapper function to protect __hdd_set_mac_address() function from ssr
5887
5888 \param - dev - Pointer to the net device.
5889 - addr - Pointer to the sockaddr.
5890 \return - 0 for success, non zero for failure
5891
5892 --------------------------------------------------------------------------*/
5893static int hdd_set_mac_address(struct net_device *dev, void *addr)
5894{
5895 int ret;
5896
5897 vos_ssr_protect(__func__);
5898 ret = __hdd_set_mac_address(dev, addr);
5899 vos_ssr_unprotect(__func__);
5900
5901 return ret;
5902}
5903
Jeff Johnson295189b2012-06-20 16:38:30 -07005904tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5905{
5906 int i;
5907 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5908 {
Abhishek Singheb183782014-02-06 13:37:21 +05305909 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 break;
5911 }
5912
5913 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5914 return NULL;
5915
5916 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5917 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5918}
5919
5920void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5921{
5922 int i;
5923 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5924 {
5925 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5926 {
5927 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5928 break;
5929 }
5930 }
5931 return;
5932}
5933
5934#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5935 static struct net_device_ops wlan_drv_ops = {
5936 .ndo_open = hdd_open,
5937 .ndo_stop = hdd_stop,
5938 .ndo_uninit = hdd_uninit,
5939 .ndo_start_xmit = hdd_hard_start_xmit,
5940 .ndo_tx_timeout = hdd_tx_timeout,
5941 .ndo_get_stats = hdd_stats,
5942 .ndo_do_ioctl = hdd_ioctl,
5943 .ndo_set_mac_address = hdd_set_mac_address,
5944 .ndo_select_queue = hdd_select_queue,
5945#ifdef WLAN_FEATURE_PACKET_FILTERING
5946#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5947 .ndo_set_rx_mode = hdd_set_multicast_list,
5948#else
5949 .ndo_set_multicast_list = hdd_set_multicast_list,
5950#endif //LINUX_VERSION_CODE
5951#endif
5952 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 static struct net_device_ops wlan_mon_drv_ops = {
5954 .ndo_open = hdd_mon_open,
5955 .ndo_stop = hdd_stop,
5956 .ndo_uninit = hdd_uninit,
5957 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5958 .ndo_tx_timeout = hdd_tx_timeout,
5959 .ndo_get_stats = hdd_stats,
5960 .ndo_do_ioctl = hdd_ioctl,
5961 .ndo_set_mac_address = hdd_set_mac_address,
5962 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005963
5964#endif
5965
5966void hdd_set_station_ops( struct net_device *pWlanDev )
5967{
5968#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 pWlanDev->netdev_ops = &wlan_drv_ops;
5970#else
5971 pWlanDev->open = hdd_open;
5972 pWlanDev->stop = hdd_stop;
5973 pWlanDev->uninit = hdd_uninit;
5974 pWlanDev->hard_start_xmit = NULL;
5975 pWlanDev->tx_timeout = hdd_tx_timeout;
5976 pWlanDev->get_stats = hdd_stats;
5977 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 pWlanDev->set_mac_address = hdd_set_mac_address;
5979#endif
5980}
5981
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005982static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005983{
5984 struct net_device *pWlanDev = NULL;
5985 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 /*
5987 * cfg80211 initialization and registration....
5988 */
5989 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5990
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 if(pWlanDev != NULL)
5992 {
5993
5994 //Save the pointer to the net_device in the HDD adapter
5995 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5996
Jeff Johnson295189b2012-06-20 16:38:30 -07005997 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5998
5999 pAdapter->dev = pWlanDev;
6000 pAdapter->pHddCtx = pHddCtx;
6001 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306002 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006003
6004 init_completion(&pAdapter->session_open_comp_var);
6005 init_completion(&pAdapter->session_close_comp_var);
6006 init_completion(&pAdapter->disconnect_comp_var);
6007 init_completion(&pAdapter->linkup_event_var);
6008 init_completion(&pAdapter->cancel_rem_on_chan_var);
6009 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306010 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6012 init_completion(&pAdapter->offchannel_tx_event);
6013#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006015#ifdef FEATURE_WLAN_TDLS
6016 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006017 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006018 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306019 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006020#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 init_completion(&pHddCtx->mc_sus_event_var);
6022 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306023 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006024 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006025 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006026
Rajeev79dbe4c2013-10-05 11:03:42 +05306027#ifdef FEATURE_WLAN_BATCH_SCAN
6028 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6029 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6030 pAdapter->pBatchScanRsp = NULL;
6031 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006032 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006033 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306034 mutex_init(&pAdapter->hdd_batch_scan_lock);
6035#endif
6036
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 pAdapter->isLinkUpSvcNeeded = FALSE;
6038 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6039 //Init the net_device structure
6040 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6041
6042 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6043 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6044 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6045 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6046
6047 hdd_set_station_ops( pAdapter->dev );
6048
6049 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6051 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6052 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006053 /* set pWlanDev's parent to underlying device */
6054 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006055
6056 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006057 }
6058
6059 return pAdapter;
6060}
6061
6062VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6063{
6064 struct net_device *pWlanDev = pAdapter->dev;
6065 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6066 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6067 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6068
6069 if( rtnl_lock_held )
6070 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006071 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6073 {
6074 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6075 return VOS_STATUS_E_FAILURE;
6076 }
6077 }
6078 if (register_netdevice(pWlanDev))
6079 {
6080 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6081 return VOS_STATUS_E_FAILURE;
6082 }
6083 }
6084 else
6085 {
6086 if(register_netdev(pWlanDev))
6087 {
6088 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6089 return VOS_STATUS_E_FAILURE;
6090 }
6091 }
6092 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6093
6094 return VOS_STATUS_SUCCESS;
6095}
6096
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006097static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006098{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006099 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006100
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006101 if (NULL == pAdapter)
6102 {
6103 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6104 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006106
6107 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6108 {
6109 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6110 return eHAL_STATUS_NOT_INITIALIZED;
6111 }
6112
6113 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6114
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006115#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006116 /* need to make sure all of our scheduled work has completed.
6117 * This callback is called from MC thread context, so it is safe to
6118 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006119 *
6120 * Even though this is called from MC thread context, if there is a faulty
6121 * work item in the system, that can hang this call forever. So flushing
6122 * this global work queue is not safe; and now we make sure that
6123 * individual work queues are stopped correctly. But the cancel work queue
6124 * is a GPL only API, so the proprietary version of the driver would still
6125 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006126 */
6127 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006128#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006129
6130 /* We can be blocked while waiting for scheduled work to be
6131 * flushed, and the adapter structure can potentially be freed, in
6132 * which case the magic will have been reset. So make sure the
6133 * magic is still good, and hence the adapter structure is still
6134 * valid, before signaling completion */
6135 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6136 {
6137 complete(&pAdapter->session_close_comp_var);
6138 }
6139
Jeff Johnson295189b2012-06-20 16:38:30 -07006140 return eHAL_STATUS_SUCCESS;
6141}
6142
6143VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6144{
6145 struct net_device *pWlanDev = pAdapter->dev;
6146 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6147 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6148 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6149 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306150 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006151
6152 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006153 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006154 //Open a SME session for future operation
6155 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006156 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006157 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6158 {
6159 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006160 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006161 halStatus, halStatus );
6162 status = VOS_STATUS_E_FAILURE;
6163 goto error_sme_open;
6164 }
6165
6166 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306167 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006168 &pAdapter->session_open_comp_var,
6169 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306170 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006171 {
6172 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306173 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006174 status = VOS_STATUS_E_FAILURE;
6175 goto error_sme_open;
6176 }
6177
6178 // Register wireless extensions
6179 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6180 {
6181 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006182 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 halStatus, halStatus );
6184 status = VOS_STATUS_E_FAILURE;
6185 goto error_register_wext;
6186 }
6187 //Safe to register the hard_start_xmit function again
6188#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6189 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6190#else
6191 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6192#endif
6193
6194 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306195 hddLog(VOS_TRACE_LEVEL_INFO,
6196 "%s: Set HDD connState to eConnectionState_NotConnected",
6197 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6199
6200 //Set the default operation channel
6201 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6202
6203 /* Make the default Auth Type as OPEN*/
6204 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6205
6206 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6207 {
6208 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006209 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006210 status, status );
6211 goto error_init_txrx;
6212 }
6213
6214 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6215
6216 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6217 {
6218 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006219 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006220 status, status );
6221 goto error_wmm_init;
6222 }
6223
6224 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6225
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006226#ifdef FEATURE_WLAN_TDLS
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306227 if(0 != wlan_hdd_sta_tdls_init(pAdapter))
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006228 {
6229 status = VOS_STATUS_E_FAILURE;
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306230 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006231 goto error_tdls_init;
6232 }
6233 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
6234#endif
6235
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 return VOS_STATUS_SUCCESS;
6237
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006238#ifdef FEATURE_WLAN_TDLS
6239error_tdls_init:
6240 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6241 hdd_wmm_adapter_close(pAdapter);
6242#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006243error_wmm_init:
6244 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6245 hdd_deinit_tx_rx(pAdapter);
6246error_init_txrx:
6247 hdd_UnregisterWext(pWlanDev);
6248error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006249 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 {
6251 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006252 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006254 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006255 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306256 unsigned long rc;
6257
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306259 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006260 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006261 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306262 if (rc <= 0)
6263 hddLog(VOS_TRACE_LEVEL_ERROR,
6264 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006265 }
6266}
6267error_sme_open:
6268 return status;
6269}
6270
Jeff Johnson295189b2012-06-20 16:38:30 -07006271void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6272{
6273 hdd_cfg80211_state_t *cfgState;
6274
6275 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6276
6277 if( NULL != cfgState->buf )
6278 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306279 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6281 rc = wait_for_completion_interruptible_timeout(
6282 &pAdapter->tx_action_cnf_event,
6283 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306284 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306287 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6288 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006289 }
6290 }
6291 return;
6292}
Jeff Johnson295189b2012-06-20 16:38:30 -07006293
6294void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6295{
6296 ENTER();
6297 switch ( pAdapter->device_mode )
6298 {
6299 case WLAN_HDD_INFRA_STATION:
6300 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006301 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 {
6303 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6304 {
6305 hdd_deinit_tx_rx( pAdapter );
6306 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6307 }
6308
6309 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6310 {
6311 hdd_wmm_adapter_close( pAdapter );
6312 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6313 }
6314
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006316#ifdef FEATURE_WLAN_TDLS
6317 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
6318 {
6319 wlan_hdd_tdls_exit(pAdapter);
6320 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
6321 }
6322#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006323
6324 break;
6325 }
6326
6327 case WLAN_HDD_SOFTAP:
6328 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306330
6331 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6332 {
6333 hdd_wmm_adapter_close( pAdapter );
6334 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6335 }
6336
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006338
6339 hdd_unregister_hostapd(pAdapter);
6340 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006341 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 break;
6343 }
6344
6345 case WLAN_HDD_MONITOR:
6346 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006347 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6349 {
6350 hdd_deinit_tx_rx( pAdapter );
6351 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6352 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 if(NULL != pAdapterforTx)
6354 {
6355 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6356 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 break;
6358 }
6359
6360
6361 default:
6362 break;
6363 }
6364
6365 EXIT();
6366}
6367
6368void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6369{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006370 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306371
6372 ENTER();
6373 if (NULL == pAdapter)
6374 {
6375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6376 "%s: HDD adapter is Null", __func__);
6377 return;
6378 }
6379
6380 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006381
Rajeev79dbe4c2013-10-05 11:03:42 +05306382#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306383 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6384 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006385 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306386 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6387 )
6388 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006389 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306390 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006391 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6392 {
6393 hdd_deinit_batch_scan(pAdapter);
6394 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306395 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006396 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306397#endif
6398
Jeff Johnson295189b2012-06-20 16:38:30 -07006399 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6400 if( rtnl_held )
6401 {
6402 unregister_netdevice(pWlanDev);
6403 }
6404 else
6405 {
6406 unregister_netdev(pWlanDev);
6407 }
6408 // note that the pAdapter is no longer valid at this point
6409 // since the memory has been reclaimed
6410 }
6411
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306412 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006413}
6414
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006415void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6416{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306417 VOS_STATUS status;
6418 hdd_adapter_t *pAdapter = NULL;
6419 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006420
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306421 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006422
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306423 /*loop through all adapters.*/
6424 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006425 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306426 pAdapter = pAdapterNode->pAdapter;
6427 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6428 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006429
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306430 { // we skip this registration for modes other than STA and P2P client modes.
6431 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6432 pAdapterNode = pNext;
6433 continue;
6434 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006435
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306436 //Apply Dynamic DTIM For P2P
6437 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6438 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6439 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6440 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6441 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6442 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6443 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6444 (eConnectionState_Associated ==
6445 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6446 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6447 {
6448 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006449
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306450 powerRequest.uIgnoreDTIM = 1;
6451 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6452
6453 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6454 {
6455 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6456 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6457 }
6458 else
6459 {
6460 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6461 }
6462
6463 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6464 * specified during Enter/Exit BMPS when LCD off*/
6465 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6466 NULL, eANI_BOOLEAN_FALSE);
6467 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6468 NULL, eANI_BOOLEAN_FALSE);
6469
6470 /* switch to the DTIM specified in cfg.ini */
6471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6472 "Switch to DTIM %d", powerRequest.uListenInterval);
6473 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6474 break;
6475
6476 }
6477
6478 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6479 pAdapterNode = pNext;
6480 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006481}
6482
6483void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6484{
6485 /*Switch back to DTIM 1*/
6486 tSirSetPowerParamsReq powerRequest = { 0 };
6487
6488 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6489 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006490 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006491
6492 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6493 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6494 NULL, eANI_BOOLEAN_FALSE);
6495 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6496 NULL, eANI_BOOLEAN_FALSE);
6497
6498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6499 "Switch to DTIM%d",powerRequest.uListenInterval);
6500 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6501
6502}
6503
Jeff Johnson295189b2012-06-20 16:38:30 -07006504VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6505{
6506 VOS_STATUS status = VOS_STATUS_SUCCESS;
6507
6508 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6509 {
6510 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6511 }
6512
6513 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6514 {
6515 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6516 }
6517
6518 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6519 {
6520 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6521 }
6522
6523 return status;
6524}
6525
6526VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6527{
6528 hdd_adapter_t *pAdapter = NULL;
6529 eHalStatus halStatus;
6530 VOS_STATUS status = VOS_STATUS_E_INVAL;
6531 v_BOOL_t disableBmps = FALSE;
6532 v_BOOL_t disableImps = FALSE;
6533
6534 switch(session_type)
6535 {
6536 case WLAN_HDD_INFRA_STATION:
6537 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 case WLAN_HDD_P2P_CLIENT:
6539 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006540 //Exit BMPS -> Is Sta/P2P Client is already connected
6541 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6542 if((NULL != pAdapter)&&
6543 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6544 {
6545 disableBmps = TRUE;
6546 }
6547
6548 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6549 if((NULL != pAdapter)&&
6550 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6551 {
6552 disableBmps = TRUE;
6553 }
6554
6555 //Exit both Bmps and Imps incase of Go/SAP Mode
6556 if((WLAN_HDD_SOFTAP == session_type) ||
6557 (WLAN_HDD_P2P_GO == session_type))
6558 {
6559 disableBmps = TRUE;
6560 disableImps = TRUE;
6561 }
6562
6563 if(TRUE == disableImps)
6564 {
6565 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6566 {
6567 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6568 }
6569 }
6570
6571 if(TRUE == disableBmps)
6572 {
6573 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6574 {
6575 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6576
6577 if(eHAL_STATUS_SUCCESS != halStatus)
6578 {
6579 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006580 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006581 VOS_ASSERT(0);
6582 return status;
6583 }
6584 }
6585
6586 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6587 {
6588 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6589
6590 if(eHAL_STATUS_SUCCESS != halStatus)
6591 {
6592 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006593 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 VOS_ASSERT(0);
6595 return status;
6596 }
6597 }
6598 }
6599
6600 if((TRUE == disableBmps) ||
6601 (TRUE == disableImps))
6602 {
6603 /* Now, get the chip into Full Power now */
6604 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6605 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6606 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6607
6608 if(halStatus != eHAL_STATUS_SUCCESS)
6609 {
6610 if(halStatus == eHAL_STATUS_PMC_PENDING)
6611 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306612 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006613 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306614 ret = wait_for_completion_interruptible_timeout(
6615 &pHddCtx->full_pwr_comp_var,
6616 msecs_to_jiffies(1000));
6617 if (ret <= 0)
6618 {
6619 hddLog(VOS_TRACE_LEVEL_ERROR,
6620 "%s: wait on full_pwr_comp_var failed %ld",
6621 __func__, ret);
6622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006623 }
6624 else
6625 {
6626 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006627 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006628 VOS_ASSERT(0);
6629 return status;
6630 }
6631 }
6632
6633 status = VOS_STATUS_SUCCESS;
6634 }
6635
6636 break;
6637 }
6638 return status;
6639}
6640
6641hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006642 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006643 tANI_U8 rtnl_held )
6644{
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05306645 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006646 hdd_adapter_t *pAdapter = NULL;
6647 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6648 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6649 VOS_STATUS exitbmpsStatus;
6650
Arif Hussain6d2a3322013-11-17 19:50:10 -08006651 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006652
Nirav Shah436658f2014-02-28 17:05:45 +05306653 if(macAddr == NULL)
6654 {
6655 /* Not received valid macAddr */
6656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6657 "%s:Unable to add virtual intf: Not able to get"
6658 "valid mac address",__func__);
6659 return NULL;
6660 }
6661
Jeff Johnson295189b2012-06-20 16:38:30 -07006662 //Disable BMPS incase of Concurrency
6663 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6664
6665 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6666 {
6667 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306668 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006669 VOS_ASSERT(0);
6670 return NULL;
6671 }
6672
6673 switch(session_type)
6674 {
6675 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006676 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006677 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006678 {
6679 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6680
6681 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306682 {
6683 hddLog(VOS_TRACE_LEVEL_FATAL,
6684 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006685 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306686 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006687
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306688#ifdef FEATURE_WLAN_TDLS
6689 /* A Mutex Lock is introduced while changing/initializing the mode to
6690 * protect the concurrent access for the Adapters by TDLS module.
6691 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306692 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306693#endif
6694
Jeff Johnsone7245742012-09-05 17:12:55 -07006695 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6696 NL80211_IFTYPE_P2P_CLIENT:
6697 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006698
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306700#ifdef FEATURE_WLAN_TDLS
6701 mutex_unlock(&pHddCtx->tdls_lock);
6702#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306703
6704 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006705 if( VOS_STATUS_SUCCESS != status )
6706 goto err_free_netdev;
6707
6708 status = hdd_register_interface( pAdapter, rtnl_held );
6709 if( VOS_STATUS_SUCCESS != status )
6710 {
6711 hdd_deinit_adapter(pHddCtx, pAdapter);
6712 goto err_free_netdev;
6713 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306714
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306715 // Workqueue which gets scheduled in IPv4 notification callback.
6716 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05306717 // Register IPv4 notifier to notify if any change in IP
6718 // So that we can reconfigure the offload parameters
6719 pAdapter->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
6720 ret = register_inetaddr_notifier(&pAdapter->ipv4_notifier);
6721 if (ret)
6722 {
6723 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
6724 }
6725 else
6726 {
6727 hddLog(LOG1, FL("Registered IPv4 notifier"));
6728 pAdapter->ipv4_notifier_registered = true;
6729 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306730
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306731#ifdef WLAN_NS_OFFLOAD
6732 // Workqueue which gets scheduled in IPv6 notification callback.
6733 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Eranna83b0ef72014-11-19 16:56:20 +05306734 // Register IPv6 notifier to notify if any change in IP
6735 // So that we can reconfigure the offload parameters
6736 pAdapter->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
6737 ret = register_inet6addr_notifier(&pAdapter->ipv6_notifier);
6738 if (ret)
6739 {
6740 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
6741 }
6742 else
6743 {
6744 hddLog(LOG1, FL("Registered IPv6 notifier"));
6745 pAdapter->ipv6_notifier_registered = true;
6746 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306747#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006748 //Stop the Interface TX queue.
6749 netif_tx_disable(pAdapter->dev);
6750 //netif_tx_disable(pWlanDev);
6751 netif_carrier_off(pAdapter->dev);
6752
6753 break;
6754 }
6755
Jeff Johnson295189b2012-06-20 16:38:30 -07006756 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 case WLAN_HDD_SOFTAP:
6758 {
6759 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6760 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306761 {
6762 hddLog(VOS_TRACE_LEVEL_FATAL,
6763 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306765 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006766
Jeff Johnson295189b2012-06-20 16:38:30 -07006767 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6768 NL80211_IFTYPE_AP:
6769 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006770 pAdapter->device_mode = session_type;
6771
6772 status = hdd_init_ap_mode(pAdapter);
6773 if( VOS_STATUS_SUCCESS != status )
6774 goto err_free_netdev;
6775
6776 status = hdd_register_hostapd( pAdapter, rtnl_held );
6777 if( VOS_STATUS_SUCCESS != status )
6778 {
6779 hdd_deinit_adapter(pHddCtx, pAdapter);
6780 goto err_free_netdev;
6781 }
6782
6783 netif_tx_disable(pAdapter->dev);
6784 netif_carrier_off(pAdapter->dev);
6785
6786 hdd_set_conparam( 1 );
6787 break;
6788 }
6789 case WLAN_HDD_MONITOR:
6790 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6792 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306793 {
6794 hddLog(VOS_TRACE_LEVEL_FATAL,
6795 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006796 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306797 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006798
6799 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6800 pAdapter->device_mode = session_type;
6801 status = hdd_register_interface( pAdapter, rtnl_held );
6802#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6803 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6804#else
6805 pAdapter->dev->open = hdd_mon_open;
6806 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6807#endif
6808 hdd_init_tx_rx( pAdapter );
6809 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6810 //Set adapter to be used for data tx. It will use either GO or softap.
6811 pAdapter->sessionCtx.monitor.pAdapterForTx =
6812 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006813 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6814 {
6815 pAdapter->sessionCtx.monitor.pAdapterForTx =
6816 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6817 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 /* This workqueue will be used to transmit management packet over
6819 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006820 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6821 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6822 return NULL;
6823 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006824
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6826 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006827 }
6828 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006829 case WLAN_HDD_FTM:
6830 {
6831 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6832
6833 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306834 {
6835 hddLog(VOS_TRACE_LEVEL_FATAL,
6836 FL("failed to allocate adapter for session %d"), session_type);
6837 return NULL;
6838 }
6839
Jeff Johnson295189b2012-06-20 16:38:30 -07006840 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6841 * message while loading driver in FTM mode. */
6842 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6843 pAdapter->device_mode = session_type;
6844 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306845
6846 hdd_init_tx_rx( pAdapter );
6847
6848 //Stop the Interface TX queue.
6849 netif_tx_disable(pAdapter->dev);
6850 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 }
6852 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 default:
6854 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306855 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6856 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006857 VOS_ASSERT(0);
6858 return NULL;
6859 }
6860 }
6861
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 if( VOS_STATUS_SUCCESS == status )
6863 {
6864 //Add it to the hdd's session list.
6865 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6866 if( NULL == pHddAdapterNode )
6867 {
6868 status = VOS_STATUS_E_NOMEM;
6869 }
6870 else
6871 {
6872 pHddAdapterNode->pAdapter = pAdapter;
6873 status = hdd_add_adapter_back ( pHddCtx,
6874 pHddAdapterNode );
6875 }
6876 }
6877
6878 if( VOS_STATUS_SUCCESS != status )
6879 {
6880 if( NULL != pAdapter )
6881 {
6882 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6883 pAdapter = NULL;
6884 }
6885 if( NULL != pHddAdapterNode )
6886 {
6887 vos_mem_free( pHddAdapterNode );
6888 }
6889
6890 goto resume_bmps;
6891 }
6892
6893 if(VOS_STATUS_SUCCESS == status)
6894 {
6895 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6896
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006897 //Initialize the WoWL service
6898 if(!hdd_init_wowl(pAdapter))
6899 {
6900 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6901 goto err_free_netdev;
6902 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006904 return pAdapter;
6905
6906err_free_netdev:
6907 free_netdev(pAdapter->dev);
6908 wlan_hdd_release_intf_addr( pHddCtx,
6909 pAdapter->macAddressCurrent.bytes );
6910
6911resume_bmps:
6912 //If bmps disabled enable it
6913 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6914 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306915 if (pHddCtx->hdd_wlan_suspended)
6916 {
6917 hdd_set_pwrparams(pHddCtx);
6918 }
6919 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 }
6921 return NULL;
6922}
6923
6924VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6925 tANI_U8 rtnl_held )
6926{
6927 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6928 VOS_STATUS status;
6929
6930 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6931 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306932 {
6933 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6934 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006935 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306936 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006937
6938 while ( pCurrent->pAdapter != pAdapter )
6939 {
6940 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6941 if( VOS_STATUS_SUCCESS != status )
6942 break;
6943
6944 pCurrent = pNext;
6945 }
6946 pAdapterNode = pCurrent;
6947 if( VOS_STATUS_SUCCESS == status )
6948 {
6949 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6950 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306951
6952#ifdef FEATURE_WLAN_TDLS
6953
6954 /* A Mutex Lock is introduced while changing/initializing the mode to
6955 * protect the concurrent access for the Adapters by TDLS module.
6956 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306957 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306958#endif
6959
Jeff Johnson295189b2012-06-20 16:38:30 -07006960 hdd_remove_adapter( pHddCtx, pAdapterNode );
6961 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006962 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006963
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306964#ifdef FEATURE_WLAN_TDLS
6965 mutex_unlock(&pHddCtx->tdls_lock);
6966#endif
6967
Jeff Johnson295189b2012-06-20 16:38:30 -07006968
6969 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306970 if ((!vos_concurrent_open_sessions_running()) &&
6971 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6972 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006973 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306974 if (pHddCtx->hdd_wlan_suspended)
6975 {
6976 hdd_set_pwrparams(pHddCtx);
6977 }
6978 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 }
6980
6981 return VOS_STATUS_SUCCESS;
6982 }
6983
6984 return VOS_STATUS_E_FAILURE;
6985}
6986
6987VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6988{
6989 hdd_adapter_list_node_t *pHddAdapterNode;
6990 VOS_STATUS status;
6991
6992 ENTER();
6993
6994 do
6995 {
6996 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6997 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6998 {
6999 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7000 vos_mem_free( pHddAdapterNode );
7001 }
7002 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7003
7004 EXIT();
7005
7006 return VOS_STATUS_SUCCESS;
7007}
7008
7009void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7010{
7011 v_U8_t addIE[1] = {0};
7012
7013 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7014 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7015 eANI_BOOLEAN_FALSE) )
7016 {
7017 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007018 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007019 }
7020
7021 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7022 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7023 eANI_BOOLEAN_FALSE) )
7024 {
7025 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007026 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007027 }
7028
7029 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7030 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7031 eANI_BOOLEAN_FALSE) )
7032 {
7033 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007034 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 }
7036}
7037
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307038VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7039 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007040{
7041 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7042 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307043 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307045 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307046 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007047
7048 ENTER();
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307049 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 switch(pAdapter->device_mode)
7051 {
7052 case WLAN_HDD_INFRA_STATION:
7053 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007054 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307055 {
7056 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7057 if( hdd_connIsConnected(pstation) ||
7058 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 {
7060 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7061 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7062 pAdapter->sessionId,
7063 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7064 else
7065 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7066 pAdapter->sessionId,
7067 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7068 //success implies disconnect command got queued up successfully
7069 if(halStatus == eHAL_STATUS_SUCCESS)
7070 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307071 ret = wait_for_completion_interruptible_timeout(
7072 &pAdapter->disconnect_comp_var,
7073 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7074 if (ret <= 0)
7075 {
7076 hddLog(VOS_TRACE_LEVEL_ERROR,
7077 "%s: wait on disconnect_comp_var failed %ld",
7078 __func__, ret);
7079 }
7080 }
7081 else
7082 {
7083 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7084 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 }
7086 memset(&wrqu, '\0', sizeof(wrqu));
7087 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7088 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7089 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7090 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307091 else if(pstation->conn_info.connState ==
7092 eConnectionState_Disconnecting)
7093 {
7094 ret = wait_for_completion_interruptible_timeout(
7095 &pAdapter->disconnect_comp_var,
7096 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7097 if (ret <= 0)
7098 {
7099 hddLog(VOS_TRACE_LEVEL_ERROR,
7100 FL("wait on disconnect_comp_var failed %ld"), ret);
7101 }
7102 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307103 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307105 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307106 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007107 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307108 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7109 {
7110 while (pAdapter->is_roc_inprogress)
7111 {
7112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7113 "%s: ROC in progress for session %d!!!",
7114 __func__, pAdapter->sessionId);
7115 // waiting for ROC to expire
7116 msleep(500);
7117 /* In GO present case , if retry exceeds 3,
7118 it means something went wrong. */
7119 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7120 {
7121 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7122 "%s: ROC completion is not received.!!!", __func__);
7123 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
7124 pAdapter->sessionId);
7125 wait_for_completion_interruptible_timeout(
7126 &pAdapter->cancel_rem_on_chan_var,
7127 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7128 break;
7129 }
7130 }
7131 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307132#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307133#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307134 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7135#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307136 if (pAdapter->ipv6_notifier_registered)
7137 {
7138 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
7139 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
7140 pAdapter->ipv6_notifier_registered = false;
7141 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307142#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05307143 if (pAdapter->ipv4_notifier_registered)
7144 {
7145 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
7146 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
7147 pAdapter->ipv4_notifier_registered = false;
7148 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307149#ifdef WLAN_OPEN_SOURCE
7150 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7151#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307152 /* It is possible that the caller of this function does not
7153 * wish to close the session
7154 */
7155 if (VOS_TRUE == bCloseSession &&
7156 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007157 {
7158 INIT_COMPLETION(pAdapter->session_close_comp_var);
7159 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307160 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7161 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007162 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307163 unsigned long ret;
7164
Jeff Johnson295189b2012-06-20 16:38:30 -07007165 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307166 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307167 &pAdapter->session_close_comp_var,
7168 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307169 if ( 0 >= ret)
7170 {
7171 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307172 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307173 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007174 }
7175 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307176 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007177 break;
7178
7179 case WLAN_HDD_SOFTAP:
7180 case WLAN_HDD_P2P_GO:
7181 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307182 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7183 while (pAdapter->is_roc_inprogress) {
7184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7185 "%s: ROC in progress for session %d!!!",
7186 __func__, pAdapter->sessionId);
7187 msleep(500);
7188 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7190 "%s: ROC completion is not received.!!!", __func__);
7191 WLANSAP_CancelRemainOnChannel(
7192 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7193 wait_for_completion_interruptible_timeout(
7194 &pAdapter->cancel_rem_on_chan_var,
7195 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7196 break;
7197 }
7198 }
7199 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 mutex_lock(&pHddCtx->sap_lock);
7201 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7202 {
7203 VOS_STATUS status;
7204 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7205
7206 //Stop Bss.
7207 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7208 if (VOS_IS_STATUS_SUCCESS(status))
7209 {
7210 hdd_hostapd_state_t *pHostapdState =
7211 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7212
7213 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7214
7215 if (!VOS_IS_STATUS_SUCCESS(status))
7216 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307217 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7218 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 }
7220 }
7221 else
7222 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007223 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007224 }
7225 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307226 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007227
7228 if (eHAL_STATUS_FAILURE ==
7229 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7230 0, NULL, eANI_BOOLEAN_FALSE))
7231 {
7232 hddLog(LOGE,
7233 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007234 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007235 }
7236
7237 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7238 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7239 eANI_BOOLEAN_FALSE) )
7240 {
7241 hddLog(LOGE,
7242 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7243 }
7244
7245 // Reset WNI_CFG_PROBE_RSP Flags
7246 wlan_hdd_reset_prob_rspies(pAdapter);
7247 kfree(pAdapter->sessionCtx.ap.beacon);
7248 pAdapter->sessionCtx.ap.beacon = NULL;
7249 }
7250 mutex_unlock(&pHddCtx->sap_lock);
7251 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007252
Jeff Johnson295189b2012-06-20 16:38:30 -07007253 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007254#ifdef WLAN_OPEN_SOURCE
7255 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7256#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007258
Jeff Johnson295189b2012-06-20 16:38:30 -07007259 default:
7260 break;
7261 }
7262
7263 EXIT();
7264 return VOS_STATUS_SUCCESS;
7265}
7266
7267VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7268{
7269 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7270 VOS_STATUS status;
7271 hdd_adapter_t *pAdapter;
7272
7273 ENTER();
7274
7275 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7276
7277 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7278 {
7279 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007280
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307281 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007282
7283 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7284 pAdapterNode = pNext;
7285 }
7286
7287 EXIT();
7288
7289 return VOS_STATUS_SUCCESS;
7290}
7291
Rajeev Kumarf999e582014-01-09 17:33:29 -08007292
7293#ifdef FEATURE_WLAN_BATCH_SCAN
7294/**---------------------------------------------------------------------------
7295
7296 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7297 structures
7298
7299 \param - pAdapter Pointer to HDD adapter
7300
7301 \return - None
7302
7303 --------------------------------------------------------------------------*/
7304void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7305{
7306 tHddBatchScanRsp *pNode;
7307 tHddBatchScanRsp *pPrev;
7308
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307309 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007310 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307311 hddLog(VOS_TRACE_LEVEL_ERROR,
7312 "%s: Adapter context is Null", __func__);
7313 return;
7314 }
7315
7316 pNode = pAdapter->pBatchScanRsp;
7317 while (pNode)
7318 {
7319 pPrev = pNode;
7320 pNode = pNode->pNext;
7321 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007322 }
7323
7324 pAdapter->pBatchScanRsp = NULL;
7325 pAdapter->numScanList = 0;
7326 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7327 pAdapter->prev_batch_id = 0;
7328
7329 return;
7330}
7331#endif
7332
7333
Jeff Johnson295189b2012-06-20 16:38:30 -07007334VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7335{
7336 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7337 VOS_STATUS status;
7338 hdd_adapter_t *pAdapter;
7339
7340 ENTER();
7341
7342 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7343
7344 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7345 {
7346 pAdapter = pAdapterNode->pAdapter;
7347 netif_tx_disable(pAdapter->dev);
7348 netif_carrier_off(pAdapter->dev);
7349
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007350 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7351
Jeff Johnson295189b2012-06-20 16:38:30 -07007352 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307353
7354 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7355
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307356 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7357 {
7358 hdd_wmm_adapter_close( pAdapter );
7359 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007361
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307362 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7363 {
7364 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7365 }
7366
Rajeev Kumarf999e582014-01-09 17:33:29 -08007367#ifdef FEATURE_WLAN_BATCH_SCAN
7368 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7369 {
7370 hdd_deinit_batch_scan(pAdapter);
7371 }
7372#endif
7373
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7375 pAdapterNode = pNext;
7376 }
7377
7378 EXIT();
7379
7380 return VOS_STATUS_SUCCESS;
7381}
7382
7383VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7384{
7385 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7386 VOS_STATUS status;
7387 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307388 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007389
7390 ENTER();
7391
7392 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7393
7394 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7395 {
7396 pAdapter = pAdapterNode->pAdapter;
7397
Kumar Anand82c009f2014-05-29 00:29:42 -07007398 hdd_wmm_init( pAdapter );
7399
Jeff Johnson295189b2012-06-20 16:38:30 -07007400 switch(pAdapter->device_mode)
7401 {
7402 case WLAN_HDD_INFRA_STATION:
7403 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007404 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307405
7406 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7407
Jeff Johnson295189b2012-06-20 16:38:30 -07007408 hdd_init_station_mode(pAdapter);
7409 /* Open the gates for HDD to receive Wext commands */
7410 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007411 pHddCtx->scan_info.mScanPending = FALSE;
7412 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007413
7414 //Trigger the initial scan
7415 hdd_wlan_initial_scan(pAdapter);
7416
7417 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307418 if (eConnectionState_Associated == connState ||
7419 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007420 {
7421 union iwreq_data wrqu;
7422 memset(&wrqu, '\0', sizeof(wrqu));
7423 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7424 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7425 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007426 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007427
Jeff Johnson295189b2012-06-20 16:38:30 -07007428 /* indicate disconnected event to nl80211 */
7429 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7430 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307432 else if (eConnectionState_Connecting == connState)
7433 {
7434 /*
7435 * Indicate connect failure to supplicant if we were in the
7436 * process of connecting
7437 */
7438 cfg80211_connect_result(pAdapter->dev, NULL,
7439 NULL, 0, NULL, 0,
7440 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7441 GFP_KERNEL);
7442 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007443 break;
7444
7445 case WLAN_HDD_SOFTAP:
7446 /* softAP can handle SSR */
7447 break;
7448
7449 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007452 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007453 break;
7454
7455 case WLAN_HDD_MONITOR:
7456 /* monitor interface start */
7457 break;
7458 default:
7459 break;
7460 }
7461
7462 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7463 pAdapterNode = pNext;
7464 }
7465
7466 EXIT();
7467
7468 return VOS_STATUS_SUCCESS;
7469}
7470
7471VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7472{
7473 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7474 hdd_adapter_t *pAdapter;
7475 VOS_STATUS status;
7476 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307477 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007478
7479 ENTER();
7480
7481 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7482
7483 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7484 {
7485 pAdapter = pAdapterNode->pAdapter;
7486
7487 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7488 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7489 {
7490 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7491 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7492
Abhishek Singhf4669da2014-05-26 15:07:49 +05307493 hddLog(VOS_TRACE_LEVEL_INFO,
7494 "%s: Set HDD connState to eConnectionState_NotConnected",
7495 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007496 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7497 init_completion(&pAdapter->disconnect_comp_var);
7498 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7499 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7500
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307501 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007502 &pAdapter->disconnect_comp_var,
7503 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307504 if (0 >= ret)
7505 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7506 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007507
7508 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7509 pHddCtx->isAmpAllowed = VOS_FALSE;
7510 sme_RoamConnect(pHddCtx->hHal,
7511 pAdapter->sessionId, &(pWextState->roamProfile),
7512 &roamId);
7513 }
7514
7515 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7516 pAdapterNode = pNext;
7517 }
7518
7519 EXIT();
7520
7521 return VOS_STATUS_SUCCESS;
7522}
7523
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007524void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7525{
7526 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7527 VOS_STATUS status;
7528 hdd_adapter_t *pAdapter;
7529 hdd_station_ctx_t *pHddStaCtx;
7530 hdd_ap_ctx_t *pHddApCtx;
7531 hdd_hostapd_state_t * pHostapdState;
7532 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7533 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7534 const char *p2pMode = "DEV";
7535 const char *ccMode = "Standalone";
7536 int n;
7537
7538 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7539 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7540 {
7541 pAdapter = pAdapterNode->pAdapter;
7542 switch (pAdapter->device_mode) {
7543 case WLAN_HDD_INFRA_STATION:
7544 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7545 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7546 staChannel = pHddStaCtx->conn_info.operationChannel;
7547 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7548 }
7549 break;
7550 case WLAN_HDD_P2P_CLIENT:
7551 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7552 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7553 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7554 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7555 p2pMode = "CLI";
7556 }
7557 break;
7558 case WLAN_HDD_P2P_GO:
7559 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7560 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7561 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7562 p2pChannel = pHddApCtx->operatingChannel;
7563 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7564 }
7565 p2pMode = "GO";
7566 break;
7567 case WLAN_HDD_SOFTAP:
7568 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7569 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7570 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7571 apChannel = pHddApCtx->operatingChannel;
7572 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7573 }
7574 break;
7575 default:
7576 break;
7577 }
7578 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7579 pAdapterNode = pNext;
7580 }
7581 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7582 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7583 }
7584 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7585 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7586 if (p2pChannel > 0) {
7587 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7588 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7589 }
7590 if (apChannel > 0) {
7591 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7592 apChannel, MAC_ADDR_ARRAY(apBssid));
7593 }
7594
7595 if (p2pChannel > 0 && apChannel > 0) {
7596 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7597 }
7598}
7599
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007600bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007601{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007602 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007603}
7604
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007605/* Once SSR is disabled then it cannot be set. */
7606void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007607{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007608 if (HDD_SSR_DISABLED == isSsrRequired)
7609 return;
7610
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 isSsrRequired = value;
7612}
7613
7614VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7615 hdd_adapter_list_node_t** ppAdapterNode)
7616{
7617 VOS_STATUS status;
7618 spin_lock(&pHddCtx->hddAdapters.lock);
7619 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7620 (hdd_list_node_t**) ppAdapterNode );
7621 spin_unlock(&pHddCtx->hddAdapters.lock);
7622 return status;
7623}
7624
7625VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7626 hdd_adapter_list_node_t* pAdapterNode,
7627 hdd_adapter_list_node_t** pNextAdapterNode)
7628{
7629 VOS_STATUS status;
7630 spin_lock(&pHddCtx->hddAdapters.lock);
7631 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7632 (hdd_list_node_t*) pAdapterNode,
7633 (hdd_list_node_t**)pNextAdapterNode );
7634
7635 spin_unlock(&pHddCtx->hddAdapters.lock);
7636 return status;
7637}
7638
7639VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7640 hdd_adapter_list_node_t* pAdapterNode)
7641{
7642 VOS_STATUS status;
7643 spin_lock(&pHddCtx->hddAdapters.lock);
7644 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7645 &pAdapterNode->node );
7646 spin_unlock(&pHddCtx->hddAdapters.lock);
7647 return status;
7648}
7649
7650VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7651 hdd_adapter_list_node_t** ppAdapterNode)
7652{
7653 VOS_STATUS status;
7654 spin_lock(&pHddCtx->hddAdapters.lock);
7655 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7656 (hdd_list_node_t**) ppAdapterNode );
7657 spin_unlock(&pHddCtx->hddAdapters.lock);
7658 return status;
7659}
7660
7661VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7662 hdd_adapter_list_node_t* pAdapterNode)
7663{
7664 VOS_STATUS status;
7665 spin_lock(&pHddCtx->hddAdapters.lock);
7666 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7667 (hdd_list_node_t*) pAdapterNode );
7668 spin_unlock(&pHddCtx->hddAdapters.lock);
7669 return status;
7670}
7671
7672VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7673 hdd_adapter_list_node_t* pAdapterNode)
7674{
7675 VOS_STATUS status;
7676 spin_lock(&pHddCtx->hddAdapters.lock);
7677 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7678 (hdd_list_node_t*) pAdapterNode );
7679 spin_unlock(&pHddCtx->hddAdapters.lock);
7680 return status;
7681}
7682
7683hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7684 tSirMacAddr macAddr )
7685{
7686 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7687 hdd_adapter_t *pAdapter;
7688 VOS_STATUS status;
7689
7690 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7691
7692 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7693 {
7694 pAdapter = pAdapterNode->pAdapter;
7695
7696 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7697 macAddr, sizeof(tSirMacAddr) ) )
7698 {
7699 return pAdapter;
7700 }
7701 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7702 pAdapterNode = pNext;
7703 }
7704
7705 return NULL;
7706
7707}
7708
7709hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7710{
7711 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7712 hdd_adapter_t *pAdapter;
7713 VOS_STATUS status;
7714
7715 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7716
7717 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7718 {
7719 pAdapter = pAdapterNode->pAdapter;
7720
7721 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7722 IFNAMSIZ ) )
7723 {
7724 return pAdapter;
7725 }
7726 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7727 pAdapterNode = pNext;
7728 }
7729
7730 return NULL;
7731
7732}
7733
7734hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7735{
7736 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7737 hdd_adapter_t *pAdapter;
7738 VOS_STATUS status;
7739
7740 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7741
7742 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7743 {
7744 pAdapter = pAdapterNode->pAdapter;
7745
7746 if( pAdapter && (mode == pAdapter->device_mode) )
7747 {
7748 return pAdapter;
7749 }
7750 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7751 pAdapterNode = pNext;
7752 }
7753
7754 return NULL;
7755
7756}
7757
7758//Remove this function later
7759hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7760{
7761 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7762 hdd_adapter_t *pAdapter;
7763 VOS_STATUS status;
7764
7765 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7766
7767 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7768 {
7769 pAdapter = pAdapterNode->pAdapter;
7770
7771 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7772 {
7773 return pAdapter;
7774 }
7775
7776 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7777 pAdapterNode = pNext;
7778 }
7779
7780 return NULL;
7781
7782}
7783
Jeff Johnson295189b2012-06-20 16:38:30 -07007784/**---------------------------------------------------------------------------
7785
7786 \brief hdd_set_monitor_tx_adapter() -
7787
7788 This API initializes the adapter to be used while transmitting on monitor
7789 adapter.
7790
7791 \param - pHddCtx - Pointer to the HDD context.
7792 pAdapter - Adapter that will used for TX. This can be NULL.
7793 \return - None.
7794 --------------------------------------------------------------------------*/
7795void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7796{
7797 hdd_adapter_t *pMonAdapter;
7798
7799 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7800
7801 if( NULL != pMonAdapter )
7802 {
7803 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7804 }
7805}
Jeff Johnson295189b2012-06-20 16:38:30 -07007806/**---------------------------------------------------------------------------
7807
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307808 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007809
7810 This API returns the operating channel of the requested device mode
7811
7812 \param - pHddCtx - Pointer to the HDD context.
7813 - mode - Device mode for which operating channel is required
7814 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7815 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7816 \return - channel number. "0" id the requested device is not found OR it is not connected.
7817 --------------------------------------------------------------------------*/
7818v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7819{
7820 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7821 VOS_STATUS status;
7822 hdd_adapter_t *pAdapter;
7823 v_U8_t operatingChannel = 0;
7824
7825 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7826
7827 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7828 {
7829 pAdapter = pAdapterNode->pAdapter;
7830
7831 if( mode == pAdapter->device_mode )
7832 {
7833 switch(pAdapter->device_mode)
7834 {
7835 case WLAN_HDD_INFRA_STATION:
7836 case WLAN_HDD_P2P_CLIENT:
7837 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7838 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7839 break;
7840 case WLAN_HDD_SOFTAP:
7841 case WLAN_HDD_P2P_GO:
7842 /*softap connection info */
7843 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7844 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7845 break;
7846 default:
7847 break;
7848 }
7849
7850 break; //Found the device of interest. break the loop
7851 }
7852
7853 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7854 pAdapterNode = pNext;
7855 }
7856 return operatingChannel;
7857}
7858
7859#ifdef WLAN_FEATURE_PACKET_FILTERING
7860/**---------------------------------------------------------------------------
7861
7862 \brief hdd_set_multicast_list() -
7863
7864 This used to set the multicast address list.
7865
7866 \param - dev - Pointer to the WLAN device.
7867 - skb - Pointer to OS packet (sk_buff).
7868 \return - success/fail
7869
7870 --------------------------------------------------------------------------*/
7871static void hdd_set_multicast_list(struct net_device *dev)
7872{
7873 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007874 int mc_count;
7875 int i = 0;
7876 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307877
7878 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007879 {
7880 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307881 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 return;
7883 }
7884
7885 if (dev->flags & IFF_ALLMULTI)
7886 {
7887 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007888 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307889 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 }
7891 else
7892 {
7893 mc_count = netdev_mc_count(dev);
7894 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007895 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007896 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7897 {
7898 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007899 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307900 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 return;
7902 }
7903
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307904 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007905
7906 netdev_for_each_mc_addr(ha, dev) {
7907 if (i == mc_count)
7908 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307909 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7910 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007911 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007912 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307913 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007914 i++;
7915 }
7916 }
7917 return;
7918}
7919#endif
7920
7921/**---------------------------------------------------------------------------
7922
7923 \brief hdd_select_queue() -
7924
7925 This function is registered with the Linux OS for network
7926 core to decide which queue to use first.
7927
7928 \param - dev - Pointer to the WLAN device.
7929 - skb - Pointer to OS packet (sk_buff).
7930 \return - ac, Queue Index/access category corresponding to UP in IP header
7931
7932 --------------------------------------------------------------------------*/
7933v_U16_t hdd_select_queue(struct net_device *dev,
7934 struct sk_buff *skb)
7935{
7936 return hdd_wmm_select_queue(dev, skb);
7937}
7938
7939
7940/**---------------------------------------------------------------------------
7941
7942 \brief hdd_wlan_initial_scan() -
7943
7944 This function triggers the initial scan
7945
7946 \param - pAdapter - Pointer to the HDD adapter.
7947
7948 --------------------------------------------------------------------------*/
7949void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7950{
7951 tCsrScanRequest scanReq;
7952 tCsrChannelInfo channelInfo;
7953 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007954 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007955 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7956
7957 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7958 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7959 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7960
7961 if(sme_Is11dSupported(pHddCtx->hHal))
7962 {
7963 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7964 if ( HAL_STATUS_SUCCESS( halStatus ) )
7965 {
7966 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7967 if( !scanReq.ChannelInfo.ChannelList )
7968 {
7969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7970 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007971 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 return;
7973 }
7974 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7975 channelInfo.numOfChannels);
7976 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7977 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007978 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007979 }
7980
7981 scanReq.scanType = eSIR_PASSIVE_SCAN;
7982 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7983 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7984 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7985 }
7986 else
7987 {
7988 scanReq.scanType = eSIR_ACTIVE_SCAN;
7989 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7990 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7991 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7992 }
7993
7994 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7995 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7996 {
7997 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7998 __func__, halStatus );
7999 }
8000
8001 if(sme_Is11dSupported(pHddCtx->hHal))
8002 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8003}
8004
Jeff Johnson295189b2012-06-20 16:38:30 -07008005/**---------------------------------------------------------------------------
8006
8007 \brief hdd_full_power_callback() - HDD full power callback function
8008
8009 This is the function invoked by SME to inform the result of a full power
8010 request issued by HDD
8011
8012 \param - callbackcontext - Pointer to cookie
8013 \param - status - result of request
8014
8015 \return - None
8016
8017 --------------------------------------------------------------------------*/
8018static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8019{
Jeff Johnson72a40512013-12-19 10:14:15 -08008020 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008021
8022 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308023 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008024
8025 if (NULL == callbackContext)
8026 {
8027 hddLog(VOS_TRACE_LEVEL_ERROR,
8028 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008029 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008030 return;
8031 }
8032
Jeff Johnson72a40512013-12-19 10:14:15 -08008033 /* there is a race condition that exists between this callback
8034 function and the caller since the caller could time out either
8035 before or while this code is executing. we use a spinlock to
8036 serialize these actions */
8037 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008038
8039 if (POWER_CONTEXT_MAGIC != pContext->magic)
8040 {
8041 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008042 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008043 hddLog(VOS_TRACE_LEVEL_WARN,
8044 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008045 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008046 return;
8047 }
8048
Jeff Johnson72a40512013-12-19 10:14:15 -08008049 /* context is valid so caller is still waiting */
8050
8051 /* paranoia: invalidate the magic */
8052 pContext->magic = 0;
8053
8054 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008055 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008056
8057 /* serialization is complete */
8058 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008059}
8060
8061/**---------------------------------------------------------------------------
8062
8063 \brief hdd_wlan_exit() - HDD WLAN exit function
8064
8065 This is the driver exit point (invoked during rmmod)
8066
8067 \param - pHddCtx - Pointer to the HDD Context
8068
8069 \return - None
8070
8071 --------------------------------------------------------------------------*/
8072void hdd_wlan_exit(hdd_context_t *pHddCtx)
8073{
8074 eHalStatus halStatus;
8075 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8076 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308077 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008078 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008079 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008080 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308081 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008082
8083 ENTER();
8084
Jeff Johnson88ba7742013-02-27 14:36:02 -08008085 if (VOS_FTM_MODE != hdd_get_conparam())
8086 {
8087 // Unloading, restart logic is no more required.
8088 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008089
c_hpothu5ab05e92014-06-13 17:34:05 +05308090 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8091 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308093 pAdapter = pAdapterNode->pAdapter;
8094 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008095 {
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308096 /* Disable TX on the interface, after this hard_start_xmit() will
8097 * not be called on that interface
8098 */
8099 netif_tx_disable(pAdapter->dev);
8100
8101 /* Mark the interface status as "down" for outside world */
8102 netif_carrier_off(pAdapter->dev);
8103
8104 /* DeInit the adapter. This ensures that all data packets
8105 * are freed.
8106 */
8107 hdd_deinit_adapter(pHddCtx, pAdapter);
8108
c_hpothu5ab05e92014-06-13 17:34:05 +05308109 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8110 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8111 {
8112 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8113 hdd_UnregisterWext(pAdapter->dev);
8114 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308115
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308117 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8118 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008119 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308120 // Cancel any outstanding scan requests. We are about to close all
8121 // of our adapters, but an adapter structure is what SME passes back
8122 // to our callback function. Hence if there are any outstanding scan
8123 // requests then there is a race condition between when the adapter
8124 // is closed and when the callback is invoked.We try to resolve that
8125 // race condition here by canceling any outstanding scans before we
8126 // close the adapters.
8127 // Note that the scans may be cancelled in an asynchronous manner,
8128 // so ideally there needs to be some kind of synchronization. Rather
8129 // than introduce a new synchronization here, we will utilize the
8130 // fact that we are about to Request Full Power, and since that is
8131 // synchronized, the expectation is that by the time Request Full
8132 // Power has completed all scans will be cancelled.
8133 if (pHddCtx->scan_info.mScanPending)
8134 {
8135 hddLog(VOS_TRACE_LEVEL_INFO,
8136 FL("abort scan mode: %d sessionId: %d"),
8137 pAdapter->device_mode,
8138 pAdapter->sessionId);
8139 hdd_abort_mac_scan(pHddCtx,
8140 pHddCtx->scan_info.sessionId,
8141 eCSR_SCAN_ABORT_DEFAULT);
8142 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008143 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308144 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008145 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308146 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08008147 wlan_hdd_ftm_close(pHddCtx);
8148 goto free_hdd_ctx;
8149 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308150
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 /* DeRegister with platform driver as client for Suspend/Resume */
8152 vosStatus = hddDeregisterPmOps(pHddCtx);
8153 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8154 {
8155 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8156 VOS_ASSERT(0);
8157 }
8158
8159 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8160 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8161 {
8162 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8163 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008164
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008165 //Stop the traffic monitor timer
8166 if ( VOS_TIMER_STATE_RUNNING ==
8167 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8168 {
8169 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8170 }
8171
8172 // Destroy the traffic monitor timer
8173 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8174 &pHddCtx->tx_rx_trafficTmr)))
8175 {
8176 hddLog(VOS_TRACE_LEVEL_ERROR,
8177 "%s: Cannot deallocate Traffic monitor timer", __func__);
8178 }
8179
Jeff Johnson295189b2012-06-20 16:38:30 -07008180 //Disable IMPS/BMPS as we do not want the device to enter any power
8181 //save mode during shutdown
8182 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8183 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8184 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8185
8186 //Ensure that device is in full power as we will touch H/W during vos_Stop
8187 init_completion(&powerContext.completion);
8188 powerContext.magic = POWER_CONTEXT_MAGIC;
8189
8190 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8191 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8192
8193 if (eHAL_STATUS_SUCCESS != halStatus)
8194 {
8195 if (eHAL_STATUS_PMC_PENDING == halStatus)
8196 {
8197 /* request was sent -- wait for the response */
8198 lrc = wait_for_completion_interruptible_timeout(
8199 &powerContext.completion,
8200 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 if (lrc <= 0)
8202 {
8203 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008204 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 }
8206 }
8207 else
8208 {
8209 hddLog(VOS_TRACE_LEVEL_ERROR,
8210 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008211 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008212 /* continue -- need to clean up as much as possible */
8213 }
8214 }
8215
Jeff Johnson72a40512013-12-19 10:14:15 -08008216 /* either we never sent a request, we sent a request and received a
8217 response or we sent a request and timed out. if we never sent a
8218 request or if we sent a request and got a response, we want to
8219 clear the magic out of paranoia. if we timed out there is a
8220 race condition such that the callback function could be
8221 executing at the same time we are. of primary concern is if the
8222 callback function had already verified the "magic" but had not
8223 yet set the completion variable when a timeout occurred. we
8224 serialize these activities by invalidating the magic while
8225 holding a shared spinlock which will cause us to block if the
8226 callback is currently executing */
8227 spin_lock(&hdd_context_lock);
8228 powerContext.magic = 0;
8229 spin_unlock(&hdd_context_lock);
8230
Yue Ma0d4891e2013-08-06 17:01:45 -07008231 hdd_debugfs_exit(pHddCtx);
8232
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 // Unregister the Net Device Notifier
8234 unregister_netdevice_notifier(&hdd_netdev_notifier);
8235
Jeff Johnson295189b2012-06-20 16:38:30 -07008236 hdd_stop_all_adapters( pHddCtx );
8237
Jeff Johnson295189b2012-06-20 16:38:30 -07008238#ifdef WLAN_BTAMP_FEATURE
8239 vosStatus = WLANBAP_Stop(pVosContext);
8240 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8241 {
8242 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8243 "%s: Failed to stop BAP",__func__);
8244 }
8245#endif //WLAN_BTAMP_FEATURE
8246
8247 //Stop all the modules
8248 vosStatus = vos_stop( pVosContext );
8249 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8250 {
8251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8252 "%s: Failed to stop VOSS",__func__);
8253 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8254 }
8255
Jeff Johnson295189b2012-06-20 16:38:30 -07008256 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008257 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008258
8259 //Close the scheduler before calling vos_close to make sure no thread is
8260 // scheduled after the each module close is called i.e after all the data
8261 // structures are freed.
8262 vosStatus = vos_sched_close( pVosContext );
8263 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8264 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8265 "%s: Failed to close VOSS Scheduler",__func__);
8266 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8267 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008268#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008269#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8270 /* Destroy the wake lock */
8271 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8272#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008273 /* Destroy the wake lock */
8274 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008275#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008276
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308277#ifdef CONFIG_ENABLE_LINUX_REG
8278 vosStatus = vos_nv_close();
8279 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8280 {
8281 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8282 "%s: Failed to close NV", __func__);
8283 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8284 }
8285#endif
8286
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 //Close VOSS
8288 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8289 vos_close(pVosContext);
8290
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 //Close Watchdog
8292 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8293 vos_watchdog_close(pVosContext);
8294
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308295 //Clean up HDD Nlink Service
8296 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308297
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308298#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308299 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308300 {
8301 wlan_logging_sock_deactivate_svc();
8302 }
8303#endif
8304
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308305#ifdef WLAN_KD_READY_NOTIFIER
8306 nl_srv_exit(pHddCtx->ptt_pid);
8307#else
8308 nl_srv_exit();
8309#endif /* WLAN_KD_READY_NOTIFIER */
8310
8311
Jeff Johnson295189b2012-06-20 16:38:30 -07008312 hdd_close_all_adapters( pHddCtx );
8313
Jeff Johnson295189b2012-06-20 16:38:30 -07008314 /* free the power on lock from platform driver */
8315 if (free_riva_power_on_lock("wlan"))
8316 {
8317 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8318 __func__);
8319 }
8320
Jeff Johnson88ba7742013-02-27 14:36:02 -08008321free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308322
8323 //Free up dynamically allocated members inside HDD Adapter
8324 if (pHddCtx->cfg_ini)
8325 {
8326 kfree(pHddCtx->cfg_ini);
8327 pHddCtx->cfg_ini= NULL;
8328 }
8329
Leo Changf04ddad2013-09-18 13:46:38 -07008330 /* FTM mode, WIPHY did not registered
8331 If un-register here, system crash will happen */
8332 if (VOS_FTM_MODE != hdd_get_conparam())
8333 {
8334 wiphy_unregister(wiphy) ;
8335 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008336 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008337 if (hdd_is_ssr_required())
8338 {
8339 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008340 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 msleep(5000);
8342 }
8343 hdd_set_ssr_required (VOS_FALSE);
8344}
8345
8346
8347/**---------------------------------------------------------------------------
8348
8349 \brief hdd_update_config_from_nv() - Function to update the contents of
8350 the running configuration with parameters taken from NV storage
8351
8352 \param - pHddCtx - Pointer to the HDD global context
8353
8354 \return - VOS_STATUS_SUCCESS if successful
8355
8356 --------------------------------------------------------------------------*/
8357static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8358{
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 v_BOOL_t itemIsValid = VOS_FALSE;
8360 VOS_STATUS status;
8361 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8362 v_U8_t macLoop;
8363
8364 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8365 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8366 if(status != VOS_STATUS_SUCCESS)
8367 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008368 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008369 return VOS_STATUS_E_FAILURE;
8370 }
8371
8372 if (itemIsValid == VOS_TRUE)
8373 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008374 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008375 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8376 VOS_MAX_CONCURRENCY_PERSONA);
8377 if(status != VOS_STATUS_SUCCESS)
8378 {
8379 /* Get MAC from NV fail, not update CFG info
8380 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008381 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008382 return VOS_STATUS_E_FAILURE;
8383 }
8384
8385 /* If first MAC is not valid, treat all others are not valid
8386 * Then all MACs will be got from ini file */
8387 if(vos_is_macaddr_zero(&macFromNV[0]))
8388 {
8389 /* MAC address in NV file is not configured yet */
8390 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8391 return VOS_STATUS_E_INVAL;
8392 }
8393
8394 /* Get MAC address from NV, update CFG info */
8395 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8396 {
8397 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8398 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308399 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008400 /* This MAC is not valid, skip it
8401 * This MAC will be got from ini file */
8402 }
8403 else
8404 {
8405 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8406 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8407 VOS_MAC_ADDR_SIZE);
8408 }
8409 }
8410 }
8411 else
8412 {
8413 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8414 return VOS_STATUS_E_FAILURE;
8415 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008416
Jeff Johnson295189b2012-06-20 16:38:30 -07008417
8418 return VOS_STATUS_SUCCESS;
8419}
8420
8421/**---------------------------------------------------------------------------
8422
8423 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8424
8425 \param - pAdapter - Pointer to the HDD
8426
8427 \return - None
8428
8429 --------------------------------------------------------------------------*/
8430VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8431{
8432 eHalStatus halStatus;
8433 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308434 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008435
Jeff Johnson295189b2012-06-20 16:38:30 -07008436
8437 // Send ready indication to the HDD. This will kick off the MAC
8438 // into a 'running' state and should kick off an initial scan.
8439 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8440 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8441 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308442 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 "code %08d [x%08x]",__func__, halStatus, halStatus );
8444 return VOS_STATUS_E_FAILURE;
8445 }
8446
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308447 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8449 // And RIVA will crash
8450 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8451 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308452 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8453 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8454
8455
Jeff Johnson295189b2012-06-20 16:38:30 -07008456 return VOS_STATUS_SUCCESS;
8457}
8458
Jeff Johnson295189b2012-06-20 16:38:30 -07008459/* wake lock APIs for HDD */
8460void hdd_prevent_suspend(void)
8461{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008462#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008464#else
8465 wcnss_prevent_suspend();
8466#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008467}
8468
8469void hdd_allow_suspend(void)
8470{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008471#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008472 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008473#else
8474 wcnss_allow_suspend();
8475#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008476}
8477
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308478void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008479{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008480#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008481 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008482#else
8483 /* Do nothing as there is no API in wcnss for timeout*/
8484#endif
8485}
8486
Jeff Johnson295189b2012-06-20 16:38:30 -07008487/**---------------------------------------------------------------------------
8488
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008489 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8490 information between Host and Riva
8491
8492 This function gets reported version of FW
8493 It also finds the version of Riva headers used to compile the host
8494 It compares the above two and prints a warning if they are different
8495 It gets the SW and HW version string
8496 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8497 indicating the features they support through a bitmap
8498
8499 \param - pHddCtx - Pointer to HDD context
8500
8501 \return - void
8502
8503 --------------------------------------------------------------------------*/
8504
8505void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8506{
8507
8508 tSirVersionType versionCompiled;
8509 tSirVersionType versionReported;
8510 tSirVersionString versionString;
8511 tANI_U8 fwFeatCapsMsgSupported = 0;
8512 VOS_STATUS vstatus;
8513
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008514 memset(&versionCompiled, 0, sizeof(versionCompiled));
8515 memset(&versionReported, 0, sizeof(versionReported));
8516
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008517 /* retrieve and display WCNSS version information */
8518 do {
8519
8520 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8521 &versionCompiled);
8522 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8523 {
8524 hddLog(VOS_TRACE_LEVEL_FATAL,
8525 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008526 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008527 break;
8528 }
8529
8530 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8531 &versionReported);
8532 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8533 {
8534 hddLog(VOS_TRACE_LEVEL_FATAL,
8535 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008536 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008537 break;
8538 }
8539
8540 if ((versionCompiled.major != versionReported.major) ||
8541 (versionCompiled.minor != versionReported.minor) ||
8542 (versionCompiled.version != versionReported.version) ||
8543 (versionCompiled.revision != versionReported.revision))
8544 {
8545 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8546 "Host expected %u.%u.%u.%u\n",
8547 WLAN_MODULE_NAME,
8548 (int)versionReported.major,
8549 (int)versionReported.minor,
8550 (int)versionReported.version,
8551 (int)versionReported.revision,
8552 (int)versionCompiled.major,
8553 (int)versionCompiled.minor,
8554 (int)versionCompiled.version,
8555 (int)versionCompiled.revision);
8556 }
8557 else
8558 {
8559 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8560 WLAN_MODULE_NAME,
8561 (int)versionReported.major,
8562 (int)versionReported.minor,
8563 (int)versionReported.version,
8564 (int)versionReported.revision);
8565 }
8566
8567 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8568 versionString,
8569 sizeof(versionString));
8570 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8571 {
8572 hddLog(VOS_TRACE_LEVEL_FATAL,
8573 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008574 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008575 break;
8576 }
8577
8578 pr_info("%s: WCNSS software version %s\n",
8579 WLAN_MODULE_NAME, versionString);
8580
8581 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8582 versionString,
8583 sizeof(versionString));
8584 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8585 {
8586 hddLog(VOS_TRACE_LEVEL_FATAL,
8587 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008588 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008589 break;
8590 }
8591
8592 pr_info("%s: WCNSS hardware version %s\n",
8593 WLAN_MODULE_NAME, versionString);
8594
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008595 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8596 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008597 send the message only if it the riva is 1.1
8598 minor numbers for different riva branches:
8599 0 -> (1.0)Mainline Build
8600 1 -> (1.1)Mainline Build
8601 2->(1.04) Stability Build
8602 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008603 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008604 ((versionReported.minor>=1) && (versionReported.version>=1)))
8605 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8606 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008607
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008608 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008609 {
8610#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8611 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8612 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8613#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008614 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8615 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8616 {
8617 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8618 }
8619
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008620 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008621 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008622
8623 } while (0);
8624
8625}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308626void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8627{
8628 struct sk_buff *skb;
8629 struct nlmsghdr *nlh;
8630 tAniMsgHdr *ani_hdr;
8631
8632 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8633
8634 if(skb == NULL) {
8635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8636 "%s: alloc_skb failed", __func__);
8637 return;
8638 }
8639
8640 nlh = (struct nlmsghdr *)skb->data;
8641 nlh->nlmsg_pid = 0; /* from kernel */
8642 nlh->nlmsg_flags = 0;
8643 nlh->nlmsg_seq = 0;
8644 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8645
8646 ani_hdr = NLMSG_DATA(nlh);
8647 ani_hdr->type = type;
8648
8649 switch(type) {
8650 case WLAN_SVC_SAP_RESTART_IND:
8651 ani_hdr->length = 0;
8652 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8653 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8654 break;
8655 default:
8656 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8657 "Attempt to send unknown nlink message %d", type);
8658 kfree_skb(skb);
8659 return;
8660 }
8661
8662 nl_srv_bcast(skb);
8663
8664 return;
8665}
8666
8667
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008668
8669/**---------------------------------------------------------------------------
8670
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308671 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8672
8673 \param - pHddCtx - Pointer to the hdd context
8674
8675 \return - true if hardware supports 5GHz
8676
8677 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308678boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308679{
8680 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8681 * then hardware support 5Ghz.
8682 */
8683 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8684 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308686 return true;
8687 }
8688 else
8689 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308691 __func__);
8692 return false;
8693 }
8694}
8695
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308696/**---------------------------------------------------------------------------
8697
8698 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8699 generate function
8700
8701 This is generate the random mac address for WLAN interface
8702
8703 \param - pHddCtx - Pointer to HDD context
8704 idx - Start interface index to get auto
8705 generated mac addr.
8706 mac_addr - Mac address
8707
8708 \return - 0 for success, < 0 for failure
8709
8710 --------------------------------------------------------------------------*/
8711
8712static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8713 int idx, v_MACADDR_t mac_addr)
8714{
8715 int i;
8716 unsigned int serialno;
8717 serialno = wcnss_get_serial_number();
8718
8719 if (0 != serialno)
8720 {
8721 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8722 bytes of the serial number that can be used to generate
8723 the other 3 bytes of the MAC address. Mask off all but
8724 the lower 3 bytes (this will also make sure we don't
8725 overflow in the next step) */
8726 serialno &= 0x00FFFFFF;
8727
8728 /* we need a unique address for each session */
8729 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8730
8731 /* autogen other Mac addresses */
8732 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8733 {
8734 /* start with the entire default address */
8735 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8736 /* then replace the lower 3 bytes */
8737 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8738 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8739 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8740
8741 serialno++;
8742 hddLog(VOS_TRACE_LEVEL_ERROR,
8743 "%s: Derived Mac Addr: "
8744 MAC_ADDRESS_STR, __func__,
8745 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8746 }
8747
8748 }
8749 else
8750 {
8751 hddLog(LOGE, FL("Failed to Get Serial NO"));
8752 return -1;
8753 }
8754 return 0;
8755}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308756
8757/**---------------------------------------------------------------------------
8758
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308759 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8760 completed to flush out the scan results
8761
8762 11d scan is done during driver load and is a passive scan on all
8763 channels supported by the device, 11d scans may find some APs on
8764 frequencies which are forbidden to be used in the regulatory domain
8765 the device is operating in. If these APs are notified to the supplicant
8766 it may try to connect to these APs, thus flush out all the scan results
8767 which are present in SME after 11d scan is done.
8768
8769 \return - eHalStatus
8770
8771 --------------------------------------------------------------------------*/
8772static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8773 tANI_U32 scanId, eCsrScanStatus status)
8774{
8775 ENTER();
8776
8777 sme_ScanFlushResult(halHandle, 0);
8778
8779 EXIT();
8780
8781 return eHAL_STATUS_SUCCESS;
8782}
8783
8784/**---------------------------------------------------------------------------
8785
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 \brief hdd_wlan_startup() - HDD init function
8787
8788 This is the driver startup code executed once a WLAN device has been detected
8789
8790 \param - dev - Pointer to the underlying device
8791
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008792 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008793
8794 --------------------------------------------------------------------------*/
8795
8796int hdd_wlan_startup(struct device *dev )
8797{
8798 VOS_STATUS status;
8799 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008800 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008801 hdd_context_t *pHddCtx = NULL;
8802 v_CONTEXT_t pVosContext= NULL;
8803#ifdef WLAN_BTAMP_FEATURE
8804 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8805 WLANBAP_ConfigType btAmpConfig;
8806 hdd_config_t *pConfig;
8807#endif
8808 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308810 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008811
8812 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008813 /*
8814 * cfg80211: wiphy allocation
8815 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308816 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008817
8818 if(wiphy == NULL)
8819 {
8820 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008821 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008822 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 pHddCtx = wiphy_priv(wiphy);
8824
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 //Initialize the adapter context to zeros.
8826 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8827
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308830 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008831
8832 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8833
8834 /*Get vos context here bcoz vos_open requires it*/
8835 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8836
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008837 if(pVosContext == NULL)
8838 {
8839 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8840 goto err_free_hdd_context;
8841 }
8842
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 //Save the Global VOSS context in adapter context for future.
8844 pHddCtx->pvosContext = pVosContext;
8845
8846 //Save the adapter context in global context for future.
8847 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8848
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 pHddCtx->parent_dev = dev;
8850
8851 init_completion(&pHddCtx->full_pwr_comp_var);
8852 init_completion(&pHddCtx->standby_comp_var);
8853 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008854 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008855 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308856 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308857 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008858
8859#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008860 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008861#else
8862 init_completion(&pHddCtx->driver_crda_req);
8863#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008864
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308865 spin_lock_init(&pHddCtx->schedScan_lock);
8866
Jeff Johnson295189b2012-06-20 16:38:30 -07008867 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8868
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308869#ifdef FEATURE_WLAN_TDLS
8870 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8871 * invoked by other instances also) to protect the concurrent
8872 * access for the Adapters by TDLS module.
8873 */
8874 mutex_init(&pHddCtx->tdls_lock);
8875#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05308876 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Agarwal Ashish1f422872014-07-22 00:11:55 +05308877 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308878
Agarwal Ashish1f422872014-07-22 00:11:55 +05308879 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 // Load all config first as TL config is needed during vos_open
8881 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8882 if(pHddCtx->cfg_ini == NULL)
8883 {
8884 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8885 goto err_free_hdd_context;
8886 }
8887
8888 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8889
8890 // Read and parse the qcom_cfg.ini file
8891 status = hdd_parse_config_ini( pHddCtx );
8892 if ( VOS_STATUS_SUCCESS != status )
8893 {
8894 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8895 __func__, WLAN_INI_FILE);
8896 goto err_config;
8897 }
Arif Hussaind5218912013-12-05 01:10:55 -08008898#ifdef MEMORY_DEBUG
8899 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8900 vos_mem_init();
8901
8902 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8903 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8904#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008905
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308906 /* INI has been read, initialise the configuredMcastBcastFilter with
8907 * INI value as this will serve as the default value
8908 */
8909 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8910 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8911 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308912
8913 if (false == hdd_is_5g_supported(pHddCtx))
8914 {
8915 //5Ghz is not supported.
8916 if (1 != pHddCtx->cfg_ini->nBandCapability)
8917 {
8918 hddLog(VOS_TRACE_LEVEL_INFO,
8919 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8920 pHddCtx->cfg_ini->nBandCapability = 1;
8921 }
8922 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308923
8924 /* If SNR Monitoring is enabled, FW has to parse all beacons
8925 * for calcaluting and storing the average SNR, so set Nth beacon
8926 * filter to 1 to enable FW to parse all the beaocons
8927 */
8928 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8929 {
8930 /* The log level is deliberately set to WARN as overriding
8931 * nthBeaconFilter to 1 will increase power cosumption and this
8932 * might just prove helpful to detect the power issue.
8933 */
8934 hddLog(VOS_TRACE_LEVEL_WARN,
8935 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8936 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8937 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008938 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308939 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008941 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008942 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008943 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8944 {
8945 hddLog(VOS_TRACE_LEVEL_FATAL,
8946 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8947 goto err_config;
8948 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008949 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008950
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008951 // Update VOS trace levels based upon the cfg.ini
8952 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8953 pHddCtx->cfg_ini->vosTraceEnableBAP);
8954 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8955 pHddCtx->cfg_ini->vosTraceEnableTL);
8956 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8957 pHddCtx->cfg_ini->vosTraceEnableWDI);
8958 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8959 pHddCtx->cfg_ini->vosTraceEnableHDD);
8960 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8961 pHddCtx->cfg_ini->vosTraceEnableSME);
8962 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8963 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308964 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8965 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008966 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8967 pHddCtx->cfg_ini->vosTraceEnableWDA);
8968 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8969 pHddCtx->cfg_ini->vosTraceEnableSYS);
8970 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8971 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008972 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8973 pHddCtx->cfg_ini->vosTraceEnableSAP);
8974 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8975 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008976
Jeff Johnson295189b2012-06-20 16:38:30 -07008977 // Update WDI trace levels based upon the cfg.ini
8978 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8979 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8980 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8981 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8982 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8983 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8984 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8985 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008986
Jeff Johnson88ba7742013-02-27 14:36:02 -08008987 if (VOS_FTM_MODE == hdd_get_conparam())
8988 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8990 {
8991 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8992 goto err_free_hdd_context;
8993 }
8994 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308995
8996 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008998 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008999
Jeff Johnson88ba7742013-02-27 14:36:02 -08009000 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009001 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9002 {
9003 status = vos_watchdog_open(pVosContext,
9004 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9005
9006 if(!VOS_IS_STATUS_SUCCESS( status ))
9007 {
9008 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309009 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009010 }
9011 }
9012
9013 pHddCtx->isLogpInProgress = FALSE;
9014 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9015
Amar Singhala49cbc52013-10-08 18:37:44 -07009016#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009017 /* initialize the NV module. This is required so that
9018 we can initialize the channel information in wiphy
9019 from the NV.bin data. The channel information in
9020 wiphy needs to be initialized before wiphy registration */
9021
9022 status = vos_nv_open();
9023 if (!VOS_IS_STATUS_SUCCESS(status))
9024 {
9025 /* NV module cannot be initialized */
9026 hddLog( VOS_TRACE_LEVEL_FATAL,
9027 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309028 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009029 }
9030
9031 status = vos_init_wiphy_from_nv_bin();
9032 if (!VOS_IS_STATUS_SUCCESS(status))
9033 {
9034 /* NV module cannot be initialized */
9035 hddLog( VOS_TRACE_LEVEL_FATAL,
9036 "%s: vos_init_wiphy failed", __func__);
9037 goto err_vos_nv_close;
9038 }
9039
Amar Singhala49cbc52013-10-08 18:37:44 -07009040#endif
9041
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309042 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009043 if ( !VOS_IS_STATUS_SUCCESS( status ))
9044 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009045 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309046 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 }
9048
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9050
9051 if ( NULL == pHddCtx->hHal )
9052 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009053 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009054 goto err_vosclose;
9055 }
9056
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009057 status = vos_preStart( pHddCtx->pvosContext );
9058 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9059 {
9060 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309061 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009062 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009063
Arif Hussaineaf68602013-12-30 23:10:44 -08009064 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9065 {
9066 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9067 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9068 __func__, enable_dfs_chan_scan);
9069 }
9070 if (0 == enable_11d || 1 == enable_11d)
9071 {
9072 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9073 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9074 __func__, enable_11d);
9075 }
9076
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009077 /* Note that the vos_preStart() sequence triggers the cfg download.
9078 The cfg download must occur before we update the SME config
9079 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009080 status = hdd_set_sme_config( pHddCtx );
9081
9082 if ( VOS_STATUS_SUCCESS != status )
9083 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009084 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309085 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009086 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009087
Jeff Johnson295189b2012-06-20 16:38:30 -07009088 /* In the integrated architecture we update the configuration from
9089 the INI file and from NV before vOSS has been started so that
9090 the final contents are available to send down to the cCPU */
9091
9092 // Apply the cfg.ini to cfg.dat
9093 if (FALSE == hdd_update_config_dat(pHddCtx))
9094 {
9095 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309096 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009097 }
9098
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309099 // Get mac addr from platform driver
9100 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9101
9102 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009103 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309104 /* Store the mac addr for first interface */
9105 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9106
9107 hddLog(VOS_TRACE_LEVEL_ERROR,
9108 "%s: WLAN Mac Addr: "
9109 MAC_ADDRESS_STR, __func__,
9110 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9111
9112 /* Here, passing Arg2 as 1 because we do not want to change the
9113 last 3 bytes (means non OUI bytes) of first interface mac
9114 addr.
9115 */
9116 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9117 {
9118 hddLog(VOS_TRACE_LEVEL_ERROR,
9119 "%s: Failed to generate wlan interface mac addr "
9120 "using MAC from ini file ", __func__);
9121 }
9122 }
9123 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9124 {
9125 // Apply the NV to cfg.dat
9126 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009127#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9128 /* There was not a valid set of MAC Addresses in NV. See if the
9129 default addresses were modified by the cfg.ini settings. If so,
9130 we'll use them, but if not, we'll autogenerate a set of MAC
9131 addresses based upon the device serial number */
9132
9133 static const v_MACADDR_t default_address =
9134 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009135
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309136 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9137 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009138 {
9139 /* cfg.ini has the default address, invoke autogen logic */
9140
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309141 /* Here, passing Arg2 as 0 because we want to change the
9142 last 3 bytes (means non OUI bytes) of all the interfaces
9143 mac addr.
9144 */
9145 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9146 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309148 hddLog(VOS_TRACE_LEVEL_ERROR,
9149 "%s: Failed to generate wlan interface mac addr "
9150 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9151 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009152 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009153 }
9154 else
9155#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9156 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009157 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 "%s: Invalid MAC address in NV, using MAC from ini file "
9159 MAC_ADDRESS_STR, __func__,
9160 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9161 }
9162 }
9163 {
9164 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309165
9166 /* Set the MAC Address Currently this is used by HAL to
9167 * add self sta. Remove this once self sta is added as
9168 * part of session open.
9169 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009170 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9171 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9172 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309173
Jeff Johnson295189b2012-06-20 16:38:30 -07009174 if (!HAL_STATUS_SUCCESS( halStatus ))
9175 {
9176 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9177 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309178 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 }
9180 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009181
9182 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9183 Note: Firmware image will be read and downloaded inside vos_start API */
9184 status = vos_start( pHddCtx->pvosContext );
9185 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9186 {
9187 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309188 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 }
9190
Leo Chang6cec3e22014-01-21 15:33:49 -08009191#ifdef FEATURE_WLAN_CH_AVOID
9192 /* Plug in avoid channel notification callback
9193 * This should happen before ADD_SELF_STA
9194 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309195
9196 /* check the Channel Avoidance is enabled */
9197 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9198 {
9199 sme_AddChAvoidCallback(pHddCtx->hHal,
9200 hdd_hostapd_ch_avoid_cb);
9201 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009202#endif /* FEATURE_WLAN_CH_AVOID */
9203
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009204 /* Exchange capability info between Host and FW and also get versioning info from FW */
9205 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009206
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309207#ifdef CONFIG_ENABLE_LINUX_REG
9208 status = wlan_hdd_init_channels(pHddCtx);
9209 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9210 {
9211 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9212 __func__);
9213 goto err_vosstop;
9214 }
9215#endif
9216
Jeff Johnson295189b2012-06-20 16:38:30 -07009217 status = hdd_post_voss_start_config( pHddCtx );
9218 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9219 {
9220 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9221 __func__);
9222 goto err_vosstop;
9223 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009224
9225#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309226 wlan_hdd_cfg80211_update_reg_info( wiphy );
9227
9228 /* registration of wiphy dev with cfg80211 */
9229 if (0 > wlan_hdd_cfg80211_register(wiphy))
9230 {
9231 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9232 goto err_vosstop;
9233 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009234#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009235
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309236#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309237 /* registration of wiphy dev with cfg80211 */
9238 if (0 > wlan_hdd_cfg80211_register(wiphy))
9239 {
9240 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9241 goto err_vosstop;
9242 }
9243
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309244 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309245 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9246 {
9247 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9248 __func__);
9249 goto err_unregister_wiphy;
9250 }
9251#endif
9252
Jeff Johnson295189b2012-06-20 16:38:30 -07009253 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9254 {
9255 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9256 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9257 }
9258 else
9259 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9261 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9262 if (pAdapter != NULL)
9263 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309264 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309266 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9267 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9268 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009269
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309270 /* Generate the P2P Device Address. This consists of the device's
9271 * primary MAC address with the locally administered bit set.
9272 */
9273 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009274 }
9275 else
9276 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309277 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9278 if (p2p_dev_addr != NULL)
9279 {
9280 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9281 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9282 }
9283 else
9284 {
9285 hddLog(VOS_TRACE_LEVEL_FATAL,
9286 "%s: Failed to allocate mac_address for p2p_device",
9287 __func__);
9288 goto err_close_adapter;
9289 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009291
9292 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9293 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9294 if ( NULL == pP2pAdapter )
9295 {
9296 hddLog(VOS_TRACE_LEVEL_FATAL,
9297 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009298 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009299 goto err_close_adapter;
9300 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009301 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009303
9304 if( pAdapter == NULL )
9305 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009306 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9307 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009309
Arif Hussain66559122013-11-21 10:11:40 -08009310 if (country_code)
9311 {
9312 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009313 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009314 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9315#ifndef CONFIG_ENABLE_LINUX_REG
9316 hdd_checkandupdate_phymode(pAdapter, country_code);
9317#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009318 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9319 (void *)(tSmeChangeCountryCallback)
9320 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009321 country_code,
9322 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309323 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009324 if (eHAL_STATUS_SUCCESS == ret)
9325 {
Arif Hussaincb607082013-12-20 11:57:42 -08009326 ret = wait_for_completion_interruptible_timeout(
9327 &pAdapter->change_country_code,
9328 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9329
9330 if (0 >= ret)
9331 {
9332 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9333 "%s: SME while setting country code timed out", __func__);
9334 }
Arif Hussain66559122013-11-21 10:11:40 -08009335 }
9336 else
9337 {
Arif Hussaincb607082013-12-20 11:57:42 -08009338 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9339 "%s: SME Change Country code from module param fail ret=%d",
9340 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009341 }
9342 }
9343
Jeff Johnson295189b2012-06-20 16:38:30 -07009344#ifdef WLAN_BTAMP_FEATURE
9345 vStatus = WLANBAP_Open(pVosContext);
9346 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9347 {
9348 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9349 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009350 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 }
9352
9353 vStatus = BSL_Init(pVosContext);
9354 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9355 {
9356 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9357 "%s: Failed to Init BSL",__func__);
9358 goto err_bap_close;
9359 }
9360 vStatus = WLANBAP_Start(pVosContext);
9361 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9362 {
9363 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9364 "%s: Failed to start TL",__func__);
9365 goto err_bap_close;
9366 }
9367
9368 pConfig = pHddCtx->cfg_ini;
9369 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9370 status = WLANBAP_SetConfig(&btAmpConfig);
9371
9372#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009373
Mihir Shete9c238772014-10-15 14:35:16 +05309374 /*
9375 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9376 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9377 * which is greater than 0xf. So the below check is safe to make
9378 * sure that there is no entry for UapsdMask in the ini
9379 */
9380 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9381 {
9382 if(IS_DYNAMIC_WMM_PS_ENABLED)
9383 {
9384 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9385 __func__);
9386 pHddCtx->cfg_ini->UapsdMask =
9387 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9388 }
9389 else
9390 {
9391 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9392 __func__);
9393 pHddCtx->cfg_ini->UapsdMask =
9394 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9395 }
9396 }
9397
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009398#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9399 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9400 {
9401 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9402 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9403 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9404 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9405 }
9406#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009407
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309408 wlan_hdd_tdls_init(pHddCtx);
9409
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309410 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9411
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 /* Register with platform driver as client for Suspend/Resume */
9413 status = hddRegisterPmOps(pHddCtx);
9414 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9415 {
9416 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9417#ifdef WLAN_BTAMP_FEATURE
9418 goto err_bap_stop;
9419#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009420 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009421#endif //WLAN_BTAMP_FEATURE
9422 }
9423
Yue Ma0d4891e2013-08-06 17:01:45 -07009424 /* Open debugfs interface */
9425 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9426 {
9427 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9428 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009429 }
9430
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 /* Register TM level change handler function to the platform */
9432 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9433 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9434 {
9435 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9436 goto err_unregister_pmops;
9437 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009438
9439 /* register for riva power on lock to platform driver */
9440 if (req_riva_power_on_lock("wlan"))
9441 {
9442 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9443 __func__);
9444 goto err_unregister_pmops;
9445 }
9446
Jeff Johnson295189b2012-06-20 16:38:30 -07009447 // register net device notifier for device change notification
9448 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9449
9450 if(ret < 0)
9451 {
9452 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9453 goto err_free_power_on_lock;
9454 }
9455
9456 //Initialize the nlink service
9457 if(nl_srv_init() != 0)
9458 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309459 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009460 goto err_reg_netdev;
9461 }
9462
Leo Chang4ce1cc52013-10-21 18:27:15 -07009463#ifdef WLAN_KD_READY_NOTIFIER
9464 pHddCtx->kd_nl_init = 1;
9465#endif /* WLAN_KD_READY_NOTIFIER */
9466
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 //Initialize the BTC service
9468 if(btc_activate_service(pHddCtx) != 0)
9469 {
9470 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9471 goto err_nl_srv;
9472 }
9473
9474#ifdef PTT_SOCK_SVC_ENABLE
9475 //Initialize the PTT service
9476 if(ptt_sock_activate_svc(pHddCtx) != 0)
9477 {
9478 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9479 goto err_nl_srv;
9480 }
9481#endif
9482
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309483#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9484 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9485 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309486 if(wlan_logging_sock_activate_svc(
9487 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9488 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9489 {
9490 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9491 " failed", __func__);
9492 goto err_nl_srv;
9493 }
9494 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9495 //EAPOL and DHCP
9496 pHddCtx->cfg_ini->enableDhcpDebug = CFG_DEBUG_DHCP_ENABLE;
9497 pHddCtx->cfg_ini->gEnableDebugLog = VOS_PKT_PROTO_TYPE_EAPOL;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309498 }
9499#endif
9500
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009503 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009504 /* Action frame registered in one adapter which will
9505 * applicable to all interfaces
9506 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309507 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009509
9510 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309511 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009512
Jeff Johnson295189b2012-06-20 16:38:30 -07009513
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009514#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009515#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9516 /* Initialize the wake lcok */
9517 wake_lock_init(&pHddCtx->rx_wake_lock,
9518 WAKE_LOCK_SUSPEND,
9519 "qcom_rx_wakelock");
9520#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009521 /* Initialize the wake lcok */
9522 wake_lock_init(&pHddCtx->sap_wake_lock,
9523 WAKE_LOCK_SUSPEND,
9524 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009525#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009526
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009527 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9528 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009529
Katya Nigam5c306ea2014-06-19 15:39:54 +05309530 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9532 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309533
9534#ifdef FEATURE_WLAN_SCAN_PNO
9535 /*SME must send channel update configuration to RIVA*/
9536 sme_UpdateChannelConfig(pHddCtx->hHal);
9537#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309538 /* Send the update default channel list to the FW*/
9539 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309540#ifndef CONFIG_ENABLE_LINUX_REG
9541 /*updating wiphy so that regulatory user hints can be processed*/
9542 if (wiphy)
9543 {
9544 regulatory_hint(wiphy, "00");
9545 }
9546#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009547 // Initialize the restart logic
9548 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309549
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009550 //Register the traffic monitor timer now
9551 if ( pHddCtx->cfg_ini->dynSplitscan)
9552 {
9553 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9554 VOS_TIMER_TYPE_SW,
9555 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9556 (void *)pHddCtx);
9557 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309558#ifdef WLAN_FEATURE_EXTSCAN
9559 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9560 wlan_hdd_cfg80211_extscan_callback,
9561 pHddCtx);
9562#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 goto success;
9564
9565err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009566#ifdef WLAN_KD_READY_NOTIFIER
9567 nl_srv_exit(pHddCtx->ptt_pid);
9568#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009570#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009571err_reg_netdev:
9572 unregister_netdevice_notifier(&hdd_netdev_notifier);
9573
9574err_free_power_on_lock:
9575 free_riva_power_on_lock("wlan");
9576
9577err_unregister_pmops:
9578 hddDevTmUnregisterNotifyCallback(pHddCtx);
9579 hddDeregisterPmOps(pHddCtx);
9580
Yue Ma0d4891e2013-08-06 17:01:45 -07009581 hdd_debugfs_exit(pHddCtx);
9582
Jeff Johnson295189b2012-06-20 16:38:30 -07009583#ifdef WLAN_BTAMP_FEATURE
9584err_bap_stop:
9585 WLANBAP_Stop(pVosContext);
9586#endif
9587
9588#ifdef WLAN_BTAMP_FEATURE
9589err_bap_close:
9590 WLANBAP_Close(pVosContext);
9591#endif
9592
Jeff Johnson295189b2012-06-20 16:38:30 -07009593err_close_adapter:
9594 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309595#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309596err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309597#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309598 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009599err_vosstop:
9600 vos_stop(pVosContext);
9601
Amar Singhala49cbc52013-10-08 18:37:44 -07009602err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009603 status = vos_sched_close( pVosContext );
9604 if (!VOS_IS_STATUS_SUCCESS(status)) {
9605 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9606 "%s: Failed to close VOSS Scheduler", __func__);
9607 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9608 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009609 vos_close(pVosContext );
9610
Amar Singhal0a402232013-10-11 20:57:16 -07009611err_vos_nv_close:
9612
c_hpothue6a36282014-03-19 12:27:38 +05309613#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009614 vos_nv_close();
9615
c_hpothu70f8d812014-03-22 22:59:23 +05309616#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009617
9618err_wdclose:
9619 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9620 vos_watchdog_close(pVosContext);
9621
Jeff Johnson295189b2012-06-20 16:38:30 -07009622err_config:
9623 kfree(pHddCtx->cfg_ini);
9624 pHddCtx->cfg_ini= NULL;
9625
9626err_free_hdd_context:
9627 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 wiphy_free(wiphy) ;
9629 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 VOS_BUG(1);
9631
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009632 if (hdd_is_ssr_required())
9633 {
9634 /* WDI timeout had happened during load, so SSR is needed here */
9635 subsystem_restart("wcnss");
9636 msleep(5000);
9637 }
9638 hdd_set_ssr_required (VOS_FALSE);
9639
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009640 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009641
9642success:
9643 EXIT();
9644 return 0;
9645}
9646
9647/**---------------------------------------------------------------------------
9648
Jeff Johnson32d95a32012-09-10 13:15:23 -07009649 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009650
Jeff Johnson32d95a32012-09-10 13:15:23 -07009651 This is the driver entry point - called in different timeline depending
9652 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009653
9654 \param - None
9655
9656 \return - 0 for success, non zero for failure
9657
9658 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009659static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009660{
9661 VOS_STATUS status;
9662 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 struct device *dev = NULL;
9664 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009665#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9666 int max_retries = 0;
9667#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009668
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309669#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9670 wlan_logging_sock_init_svc();
9671#endif
9672
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 ENTER();
9674
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009675#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009677#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009678
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309679 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9681 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9682
Jeff Johnson295189b2012-06-20 16:38:30 -07009683#ifdef ANI_BUS_TYPE_PCI
9684
9685 dev = wcnss_wlan_get_device();
9686
9687#endif // ANI_BUS_TYPE_PCI
9688
9689#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009690
9691#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9692 /* wait until WCNSS driver downloads NV */
9693 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9694 msleep(1000);
9695 }
9696 if (max_retries >= 5) {
9697 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309698#ifdef WLAN_OPEN_SOURCE
9699 wake_lock_destroy(&wlan_wake_lock);
9700#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309701
9702#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9703 wlan_logging_sock_deinit_svc();
9704#endif
9705
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009706 return -ENODEV;
9707 }
9708#endif
9709
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 dev = wcnss_wlan_get_device();
9711#endif // ANI_BUS_TYPE_PLATFORM
9712
9713
9714 do {
9715 if (NULL == dev) {
9716 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9717 ret_status = -1;
9718 break;
9719 }
9720
Jeff Johnson295189b2012-06-20 16:38:30 -07009721#ifdef TIMER_MANAGER
9722 vos_timer_manager_init();
9723#endif
9724
9725 /* Preopen VOSS so that it is ready to start at least SAL */
9726 status = vos_preOpen(&pVosContext);
9727
9728 if (!VOS_IS_STATUS_SUCCESS(status))
9729 {
9730 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9731 ret_status = -1;
9732 break;
9733 }
9734
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009735#ifndef MODULE
9736 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9737 */
9738 hdd_set_conparam((v_UINT_t)con_mode);
9739#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009740
9741 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009742 if (hdd_wlan_startup(dev))
9743 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009744 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009745 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 vos_preClose( &pVosContext );
9747 ret_status = -1;
9748 break;
9749 }
9750
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 } while (0);
9752
9753 if (0 != ret_status)
9754 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009755#ifdef TIMER_MANAGER
9756 vos_timer_exit();
9757#endif
9758#ifdef MEMORY_DEBUG
9759 vos_mem_exit();
9760#endif
9761
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009762#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009764#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309765
9766#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9767 wlan_logging_sock_deinit_svc();
9768#endif
9769
Jeff Johnson295189b2012-06-20 16:38:30 -07009770 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9771 }
9772 else
9773 {
9774 //Send WLAN UP indication to Nlink Service
9775 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9776
9777 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 }
9779
9780 EXIT();
9781
9782 return ret_status;
9783}
9784
Jeff Johnson32d95a32012-09-10 13:15:23 -07009785/**---------------------------------------------------------------------------
9786
9787 \brief hdd_module_init() - Init Function
9788
9789 This is the driver entry point (invoked when module is loaded using insmod)
9790
9791 \param - None
9792
9793 \return - 0 for success, non zero for failure
9794
9795 --------------------------------------------------------------------------*/
9796#ifdef MODULE
9797static int __init hdd_module_init ( void)
9798{
9799 return hdd_driver_init();
9800}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009801#else /* #ifdef MODULE */
9802static int __init hdd_module_init ( void)
9803{
9804 /* Driver initialization is delayed to fwpath_changed_handler */
9805 return 0;
9806}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009807#endif /* #ifdef MODULE */
9808
Jeff Johnson295189b2012-06-20 16:38:30 -07009809
9810/**---------------------------------------------------------------------------
9811
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009812 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009813
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009814 This is the driver exit point (invoked when module is unloaded using rmmod
9815 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009816
9817 \param - None
9818
9819 \return - None
9820
9821 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009822static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009823{
9824 hdd_context_t *pHddCtx = NULL;
9825 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309826 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309827 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009828
9829 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9830
9831 //Get the global vos context
9832 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9833
9834 if(!pVosContext)
9835 {
9836 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9837 goto done;
9838 }
9839
9840 //Get the HDD context.
9841 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9842
9843 if(!pHddCtx)
9844 {
9845 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9846 }
9847 else
9848 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309849 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9850
c_hpothu8adb97b2014-12-08 19:38:20 +05309851 if ((pHddCtx->isLogpInProgress) &&
9852 (FALSE == vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309853 {
c_hpothu8adb97b2014-12-08 19:38:20 +05309854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9855 "%s:SSR in Progress; block rmmod !!!", __func__);
9856 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9857 msecs_to_jiffies(30000));
9858 if(!rc)
9859 {
9860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9861 "%s:SSR timedout, fatal error", __func__);
9862 VOS_BUG(0);
9863 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009865
c_hpothu8adb97b2014-12-08 19:38:20 +05309866 rtnl_lock();
9867 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
9868 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9869 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -07009870
c_hpothu8adb97b2014-12-08 19:38:20 +05309871 /* Driver Need to send country code 00 in below condition
9872 * 1) If gCountryCodePriority is set to 1; and last country
9873 * code set is through 11d. This needs to be done in case
9874 * when NV country code is 00.
9875 * This Needs to be done as when kernel store last country
9876 * code and if stored country code is not through 11d,
9877 * in sme_HandleChangeCountryCodeByUser we will disable 11d
9878 * in next load/unload as soon as we get any country through
9879 * 11d. In sme_HandleChangeCountryCodeByUser
9880 * pMsg->countryCode will be last countryCode and
9881 * pMac->scan.countryCode11d will be country through 11d so
9882 * due to mismatch driver will disable 11d.
9883 *
9884 */
Agarwal Ashish8db39882014-07-30 21:56:07 +05309885
c_hpothu8adb97b2014-12-08 19:38:20 +05309886 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309887 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +05309888 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +05309889 {
9890 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309891 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +05309892 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9893 }
Agarwal Ashish5e414792014-06-08 15:25:23 +05309894
c_hpothu8adb97b2014-12-08 19:38:20 +05309895 //Do all the cleanup before deregistering the driver
9896 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 }
9898
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 vos_preClose( &pVosContext );
9900
9901#ifdef TIMER_MANAGER
9902 vos_timer_exit();
9903#endif
9904#ifdef MEMORY_DEBUG
9905 vos_mem_exit();
9906#endif
9907
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309908#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9909 wlan_logging_sock_deinit_svc();
9910#endif
9911
Jeff Johnson295189b2012-06-20 16:38:30 -07009912done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009913#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009914 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009915#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309916
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9918}
9919
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009920/**---------------------------------------------------------------------------
9921
9922 \brief hdd_module_exit() - Exit function
9923
9924 This is the driver exit point (invoked when module is unloaded using rmmod)
9925
9926 \param - None
9927
9928 \return - None
9929
9930 --------------------------------------------------------------------------*/
9931static void __exit hdd_module_exit(void)
9932{
9933 hdd_driver_exit();
9934}
9935
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009936#ifdef MODULE
9937static int fwpath_changed_handler(const char *kmessage,
9938 struct kernel_param *kp)
9939{
Jeff Johnson76052702013-04-16 13:55:05 -07009940 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009941}
9942
9943static int con_mode_handler(const char *kmessage,
9944 struct kernel_param *kp)
9945{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009946 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009947}
9948#else /* #ifdef MODULE */
9949/**---------------------------------------------------------------------------
9950
Jeff Johnson76052702013-04-16 13:55:05 -07009951 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009952
Jeff Johnson76052702013-04-16 13:55:05 -07009953 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009954 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009955 - invoked when module parameter fwpath is modified from userspace to signal
9956 initializing the WLAN driver or when con_mode is modified from userspace
9957 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009958
9959 \return - 0 for success, non zero for failure
9960
9961 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009962static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009963{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009964 int ret_status;
9965
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009966 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009967 ret_status = hdd_driver_init();
9968 wlan_hdd_inited = ret_status ? 0 : 1;
9969 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009970 }
9971
9972 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009973
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009974 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009975
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009976 ret_status = hdd_driver_init();
9977 wlan_hdd_inited = ret_status ? 0 : 1;
9978 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009979}
9980
Jeff Johnson295189b2012-06-20 16:38:30 -07009981/**---------------------------------------------------------------------------
9982
Jeff Johnson76052702013-04-16 13:55:05 -07009983 \brief fwpath_changed_handler() - Handler Function
9984
9985 Handle changes to the fwpath parameter
9986
9987 \return - 0 for success, non zero for failure
9988
9989 --------------------------------------------------------------------------*/
9990static int fwpath_changed_handler(const char *kmessage,
9991 struct kernel_param *kp)
9992{
9993 int ret;
9994
9995 ret = param_set_copystring(kmessage, kp);
9996 if (0 == ret)
9997 ret = kickstart_driver();
9998 return ret;
9999}
10000
10001/**---------------------------------------------------------------------------
10002
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010003 \brief con_mode_handler() -
10004
10005 Handler function for module param con_mode when it is changed by userspace
10006 Dynamically linked - do nothing
10007 Statically linked - exit and init driver, as in rmmod and insmod
10008
Jeff Johnson76052702013-04-16 13:55:05 -070010009 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010010
Jeff Johnson76052702013-04-16 13:55:05 -070010011 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010012
10013 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010014static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010015{
Jeff Johnson76052702013-04-16 13:55:05 -070010016 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010017
Jeff Johnson76052702013-04-16 13:55:05 -070010018 ret = param_set_int(kmessage, kp);
10019 if (0 == ret)
10020 ret = kickstart_driver();
10021 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010022}
10023#endif /* #ifdef MODULE */
10024
10025/**---------------------------------------------------------------------------
10026
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 \brief hdd_get_conparam() -
10028
10029 This is the driver exit point (invoked when module is unloaded using rmmod)
10030
10031 \param - None
10032
10033 \return - tVOS_CON_MODE
10034
10035 --------------------------------------------------------------------------*/
10036tVOS_CON_MODE hdd_get_conparam ( void )
10037{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010038#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010040#else
10041 return (tVOS_CON_MODE)curr_con_mode;
10042#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010043}
10044void hdd_set_conparam ( v_UINT_t newParam )
10045{
10046 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010047#ifndef MODULE
10048 curr_con_mode = con_mode;
10049#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010050}
10051/**---------------------------------------------------------------------------
10052
10053 \brief hdd_softap_sta_deauth() - function
10054
10055 This to take counter measure to handle deauth req from HDD
10056
10057 \param - pAdapter - Pointer to the HDD
10058
10059 \param - enable - boolean value
10060
10061 \return - None
10062
10063 --------------------------------------------------------------------------*/
10064
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010065VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10066 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010067{
Jeff Johnson295189b2012-06-20 16:38:30 -070010068 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010069 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010070
10071 ENTER();
10072
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010073 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10074 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010075
10076 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010077 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010078 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010079
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010080 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010081
10082 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010083 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010084}
10085
10086/**---------------------------------------------------------------------------
10087
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010088 \brief hdd_del_all_sta() - function
10089
10090 This function removes all the stations associated on stopping AP/P2P GO.
10091
10092 \param - pAdapter - Pointer to the HDD
10093
10094 \return - None
10095
10096 --------------------------------------------------------------------------*/
10097
10098int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10099{
10100 v_U16_t i;
10101 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010102 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10103 ptSapContext pSapCtx = NULL;
10104 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10105 if(pSapCtx == NULL){
10106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10107 FL("psapCtx is NULL"));
10108 return 1;
10109 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010110 ENTER();
10111
10112 hddLog(VOS_TRACE_LEVEL_INFO,
10113 "%s: Delete all STAs associated.",__func__);
10114 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10115 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10116 )
10117 {
10118 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10119 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010120 if ((pSapCtx->aStaInfo[i].isUsed) &&
10121 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010122 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010123 struct tagCsrDelStaParams delStaParams;
10124
10125 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010126 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010127 eCsrForcedDeauthSta, SIR_MAC_MGMT_DEAUTH >> 4,
10128 &delStaParams);
10129 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010130 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010131 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010132 }
10133 }
10134 }
10135
10136 EXIT();
10137 return 0;
10138}
10139
10140/**---------------------------------------------------------------------------
10141
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 \brief hdd_softap_sta_disassoc() - function
10143
10144 This to take counter measure to handle deauth req from HDD
10145
10146 \param - pAdapter - Pointer to the HDD
10147
10148 \param - enable - boolean value
10149
10150 \return - None
10151
10152 --------------------------------------------------------------------------*/
10153
10154void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10155{
10156 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10157
10158 ENTER();
10159
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010160 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010161
10162 //Ignore request to disassoc bcmc station
10163 if( pDestMacAddress[0] & 0x1 )
10164 return;
10165
10166 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10167}
10168
10169void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10170{
10171 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10172
10173 ENTER();
10174
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010175 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010176
10177 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10178}
10179
Jeff Johnson295189b2012-06-20 16:38:30 -070010180/**---------------------------------------------------------------------------
10181 *
10182 * \brief hdd_get__concurrency_mode() -
10183 *
10184 *
10185 * \param - None
10186 *
10187 * \return - CONCURRENCY MODE
10188 *
10189 * --------------------------------------------------------------------------*/
10190tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10191{
10192 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10193 hdd_context_t *pHddCtx;
10194
10195 if (NULL != pVosContext)
10196 {
10197 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10198 if (NULL != pHddCtx)
10199 {
10200 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10201 }
10202 }
10203
10204 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010205 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010206 return VOS_STA;
10207}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010208v_BOOL_t
10209wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10210{
10211 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010212
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010213 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10214 if (pAdapter == NULL)
10215 {
10216 hddLog(VOS_TRACE_LEVEL_INFO,
10217 FL("GO doesn't exist"));
10218 return TRUE;
10219 }
10220 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10221 {
10222 hddLog(VOS_TRACE_LEVEL_INFO,
10223 FL("GO started"));
10224 return TRUE;
10225 }
10226 else
10227 /* wait till GO changes its interface to p2p device */
10228 hddLog(VOS_TRACE_LEVEL_INFO,
10229 FL("Del_bss called, avoid apps suspend"));
10230 return FALSE;
10231
10232}
Jeff Johnson295189b2012-06-20 16:38:30 -070010233/* Decide whether to allow/not the apps power collapse.
10234 * Allow apps power collapse if we are in connected state.
10235 * if not, allow only if we are in IMPS */
10236v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10237{
10238 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010239 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010240 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010241 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10242 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10243 hdd_adapter_t *pAdapter = NULL;
10244 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010245 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010246
Jeff Johnson295189b2012-06-20 16:38:30 -070010247 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10248 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010249
Yathish9f22e662012-12-10 14:21:35 -080010250 concurrent_state = hdd_get_concurrency_mode();
10251
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010252 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10253 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10254 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010255#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010256
Yathish9f22e662012-12-10 14:21:35 -080010257 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010258 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010259 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10260 return TRUE;
10261#endif
10262
Jeff Johnson295189b2012-06-20 16:38:30 -070010263 /*loop through all adapters. TBD fix for Concurrency */
10264 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10265 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10266 {
10267 pAdapter = pAdapterNode->pAdapter;
10268 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10269 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10270 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010271 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010272 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -080010273 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010274 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10275 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010276 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010277 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010278 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10279 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010280 return FALSE;
10281 }
10282 }
10283 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10284 pAdapterNode = pNext;
10285 }
10286 return TRUE;
10287}
10288
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010289/* Decides whether to send suspend notification to Riva
10290 * if any adapter is in BMPS; then it is required */
10291v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10292{
10293 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10294 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10295
10296 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10297 {
10298 return TRUE;
10299 }
10300 return FALSE;
10301}
10302
Jeff Johnson295189b2012-06-20 16:38:30 -070010303void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10304{
10305 switch(mode)
10306 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010307 case VOS_STA_MODE:
10308 case VOS_P2P_CLIENT_MODE:
10309 case VOS_P2P_GO_MODE:
10310 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010311 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010312 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010313 break;
10314 default:
10315 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010316 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010317 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10318 "Number of open sessions for mode %d = %d"),
10319 pHddCtx->concurrency_mode, mode,
10320 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010321}
10322
10323
10324void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10325{
10326 switch(mode)
10327 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010328 case VOS_STA_MODE:
10329 case VOS_P2P_CLIENT_MODE:
10330 case VOS_P2P_GO_MODE:
10331 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010332 pHddCtx->no_of_open_sessions[mode]--;
10333 if (!(pHddCtx->no_of_open_sessions[mode]))
10334 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010335 break;
10336 default:
10337 break;
10338 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010339 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10340 "Number of open sessions for mode %d = %d"),
10341 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10342
10343}
10344/**---------------------------------------------------------------------------
10345 *
10346 * \brief wlan_hdd_incr_active_session()
10347 *
10348 * This function increments the number of active sessions
10349 * maintained per device mode
10350 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10351 * Incase of SAP/P2P GO upon bss start it is incremented
10352 *
10353 * \param pHddCtx - HDD Context
10354 * \param mode - device mode
10355 *
10356 * \return - None
10357 *
10358 * --------------------------------------------------------------------------*/
10359void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10360{
10361 switch (mode) {
10362 case VOS_STA_MODE:
10363 case VOS_P2P_CLIENT_MODE:
10364 case VOS_P2P_GO_MODE:
10365 case VOS_STA_SAP_MODE:
10366 pHddCtx->no_of_active_sessions[mode]++;
10367 break;
10368 default:
10369 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10370 break;
10371 }
10372 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10373 mode,
10374 pHddCtx->no_of_active_sessions[mode]);
10375}
10376
10377/**---------------------------------------------------------------------------
10378 *
10379 * \brief wlan_hdd_decr_active_session()
10380 *
10381 * This function decrements the number of active sessions
10382 * maintained per device mode
10383 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10384 * Incase of SAP/P2P GO upon bss stop it is decremented
10385 *
10386 * \param pHddCtx - HDD Context
10387 * \param mode - device mode
10388 *
10389 * \return - None
10390 *
10391 * --------------------------------------------------------------------------*/
10392void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10393{
10394 switch (mode) {
10395 case VOS_STA_MODE:
10396 case VOS_P2P_CLIENT_MODE:
10397 case VOS_P2P_GO_MODE:
10398 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010399 if (pHddCtx->no_of_active_sessions[mode] > 0)
10400 pHddCtx->no_of_active_sessions[mode]--;
10401 else
10402 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10403 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010404 break;
10405 default:
10406 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10407 break;
10408 }
10409 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10410 mode,
10411 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010412}
10413
Jeff Johnsone7245742012-09-05 17:12:55 -070010414/**---------------------------------------------------------------------------
10415 *
10416 * \brief wlan_hdd_restart_init
10417 *
10418 * This function initalizes restart timer/flag. An internal function.
10419 *
10420 * \param - pHddCtx
10421 *
10422 * \return - None
10423 *
10424 * --------------------------------------------------------------------------*/
10425
10426static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10427{
10428 /* Initialize */
10429 pHddCtx->hdd_restart_retries = 0;
10430 atomic_set(&pHddCtx->isRestartInProgress, 0);
10431 vos_timer_init(&pHddCtx->hdd_restart_timer,
10432 VOS_TIMER_TYPE_SW,
10433 wlan_hdd_restart_timer_cb,
10434 pHddCtx);
10435}
10436/**---------------------------------------------------------------------------
10437 *
10438 * \brief wlan_hdd_restart_deinit
10439 *
10440 * This function cleans up the resources used. An internal function.
10441 *
10442 * \param - pHddCtx
10443 *
10444 * \return - None
10445 *
10446 * --------------------------------------------------------------------------*/
10447
10448static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10449{
10450
10451 VOS_STATUS vos_status;
10452 /* Block any further calls */
10453 atomic_set(&pHddCtx->isRestartInProgress, 1);
10454 /* Cleanup */
10455 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10456 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010457 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010458 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10459 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010460 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010461
10462}
10463
10464/**---------------------------------------------------------------------------
10465 *
10466 * \brief wlan_hdd_framework_restart
10467 *
10468 * This function uses a cfg80211 API to start a framework initiated WLAN
10469 * driver module unload/load.
10470 *
10471 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10472 *
10473 *
10474 * \param - pHddCtx
10475 *
10476 * \return - VOS_STATUS_SUCCESS: Success
10477 * VOS_STATUS_E_EMPTY: Adapter is Empty
10478 * VOS_STATUS_E_NOMEM: No memory
10479
10480 * --------------------------------------------------------------------------*/
10481
10482static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10483{
10484 VOS_STATUS status = VOS_STATUS_SUCCESS;
10485 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010486 int len = (sizeof (struct ieee80211_mgmt));
10487 struct ieee80211_mgmt *mgmt = NULL;
10488
10489 /* Prepare the DEAUTH managment frame with reason code */
10490 mgmt = kzalloc(len, GFP_KERNEL);
10491 if(mgmt == NULL)
10492 {
10493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10494 "%s: memory allocation failed (%d bytes)", __func__, len);
10495 return VOS_STATUS_E_NOMEM;
10496 }
10497 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010498
10499 /* Iterate over all adapters/devices */
10500 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10501 do
10502 {
10503 if( (status == VOS_STATUS_SUCCESS) &&
10504 pAdapterNode &&
10505 pAdapterNode->pAdapter)
10506 {
10507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10508 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10509 pAdapterNode->pAdapter->dev->name,
10510 pAdapterNode->pAdapter->device_mode,
10511 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010512 /*
10513 * CFG80211 event to restart the driver
10514 *
10515 * 'cfg80211_send_unprot_deauth' sends a
10516 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10517 * of SME(Linux Kernel) state machine.
10518 *
10519 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10520 * the driver.
10521 *
10522 */
10523
10524 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010525 }
10526 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10527 pAdapterNode = pNext;
10528 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10529
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010530
10531 /* Free the allocated management frame */
10532 kfree(mgmt);
10533
Jeff Johnsone7245742012-09-05 17:12:55 -070010534 /* Retry until we unload or reach max count */
10535 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10536 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10537
10538 return status;
10539
10540}
10541/**---------------------------------------------------------------------------
10542 *
10543 * \brief wlan_hdd_restart_timer_cb
10544 *
10545 * Restart timer callback. An internal function.
10546 *
10547 * \param - User data:
10548 *
10549 * \return - None
10550 *
10551 * --------------------------------------------------------------------------*/
10552
10553void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10554{
10555 hdd_context_t *pHddCtx = usrDataForCallback;
10556 wlan_hdd_framework_restart(pHddCtx);
10557 return;
10558
10559}
10560
10561
10562/**---------------------------------------------------------------------------
10563 *
10564 * \brief wlan_hdd_restart_driver
10565 *
10566 * This function sends an event to supplicant to restart the WLAN driver.
10567 *
10568 * This function is called from vos_wlanRestart.
10569 *
10570 * \param - pHddCtx
10571 *
10572 * \return - VOS_STATUS_SUCCESS: Success
10573 * VOS_STATUS_E_EMPTY: Adapter is Empty
10574 * VOS_STATUS_E_ALREADY: Request already in progress
10575
10576 * --------------------------------------------------------------------------*/
10577VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10578{
10579 VOS_STATUS status = VOS_STATUS_SUCCESS;
10580
10581 /* A tight check to make sure reentrancy */
10582 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10583 {
Mihir Shetefd528652014-06-23 19:07:50 +053010584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010585 "%s: WLAN restart is already in progress", __func__);
10586
10587 return VOS_STATUS_E_ALREADY;
10588 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010589 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010590#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010591 wcnss_reset_intr();
10592#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010593
Jeff Johnsone7245742012-09-05 17:12:55 -070010594 return status;
10595}
10596
Mihir Shetee1093ba2014-01-21 20:13:32 +053010597/**---------------------------------------------------------------------------
10598 *
10599 * \brief wlan_hdd_init_channels
10600 *
10601 * This function is used to initialize the channel list in CSR
10602 *
10603 * This function is called from hdd_wlan_startup
10604 *
10605 * \param - pHddCtx: HDD context
10606 *
10607 * \return - VOS_STATUS_SUCCESS: Success
10608 * VOS_STATUS_E_FAULT: Failure reported by SME
10609
10610 * --------------------------------------------------------------------------*/
10611static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10612{
10613 eHalStatus status;
10614
10615 status = sme_InitChannels(pHddCtx->hHal);
10616 if (HAL_STATUS_SUCCESS(status))
10617 {
10618 return VOS_STATUS_SUCCESS;
10619 }
10620 else
10621 {
10622 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10623 __func__, status);
10624 return VOS_STATUS_E_FAULT;
10625 }
10626}
10627
Mihir Shete04206452014-11-20 17:50:58 +053010628#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010629VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010630{
10631 eHalStatus status;
10632
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010633 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010634 if (HAL_STATUS_SUCCESS(status))
10635 {
10636 return VOS_STATUS_SUCCESS;
10637 }
10638 else
10639 {
10640 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10641 __func__, status);
10642 return VOS_STATUS_E_FAULT;
10643 }
10644}
Mihir Shete04206452014-11-20 17:50:58 +053010645#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010646/*
10647 * API to find if there is any STA or P2P-Client is connected
10648 */
10649VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10650{
10651 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10652}
Jeff Johnsone7245742012-09-05 17:12:55 -070010653
Agarwal Ashish57e84372014-12-05 18:26:53 +053010654/*
10655 * API to find if there is any session connected
10656 */
10657VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
10658{
10659 return sme_is_any_session_connected(pHddCtx->hHal);
10660}
10661
10662
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010663int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10664{
10665 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10666 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010667 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010668
10669 pScanInfo = &pHddCtx->scan_info;
10670 if (pScanInfo->mScanPending)
10671 {
10672 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010673 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010674 eCSR_SCAN_ABORT_DEFAULT);
10675
10676 status = wait_for_completion_interruptible_timeout(
10677 &pScanInfo->abortscan_event_var,
10678 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010679 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010680 {
10681 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010682 "%s: Timeout or Interrupt occurred while waiting for abort"
10683 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010684 return -ETIMEDOUT;
10685 }
10686 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010687 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010688}
10689
c_hpothu225aa7c2014-10-22 17:45:13 +053010690VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10691{
10692 hdd_adapter_t *pAdapter;
10693 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10694 VOS_STATUS vosStatus;
10695
10696 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10697 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10698 {
10699 pAdapter = pAdapterNode->pAdapter;
10700 if (NULL != pAdapter)
10701 {
10702 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10703 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10704 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10705 {
10706 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10707 pAdapter->device_mode);
10708 if (VOS_STATUS_SUCCESS !=
10709 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10710 {
10711 hddLog(LOGE, FL("failed to abort ROC"));
10712 return VOS_STATUS_E_FAILURE;
10713 }
10714 }
10715 }
10716 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10717 pAdapterNode = pNext;
10718 }
10719 return VOS_STATUS_SUCCESS;
10720}
Jeff Johnson295189b2012-06-20 16:38:30 -070010721//Register the module init/exit functions
10722module_init(hdd_module_init);
10723module_exit(hdd_module_exit);
10724
10725MODULE_LICENSE("Dual BSD/GPL");
10726MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10727MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10728
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010729module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10730 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010731
Jeff Johnson76052702013-04-16 13:55:05 -070010732module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010733 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010734
10735module_param(enable_dfs_chan_scan, int,
10736 S_IRUSR | S_IRGRP | S_IROTH);
10737
10738module_param(enable_11d, int,
10739 S_IRUSR | S_IRGRP | S_IROTH);
10740
10741module_param(country_code, charp,
10742 S_IRUSR | S_IRGRP | S_IROTH);