blob: 5d7678e34c2196312fef267cbf8dd9d930c8a577 [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>
69#include <vos_power.h>
70#include <linux/etherdevice.h>
71#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070072#ifdef ANI_BUS_TYPE_PLATFORM
73#include <linux/wcnss_wlan.h>
74#endif //ANI_BUS_TYPE_PLATFORM
75#ifdef ANI_BUS_TYPE_PCI
76#include "wcnss_wlan.h"
77#endif /* ANI_BUS_TYPE_PCI */
78#include <wlan_hdd_tx_rx.h>
79#include <palTimer.h>
80#include <wniApi.h>
81#include <wlan_nlink_srv.h>
82#include <wlan_btc_svc.h>
83#include <wlan_hdd_cfg.h>
84#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053085#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070086#include <wlan_hdd_wowl.h>
87#include <wlan_hdd_misc.h>
88#include <wlan_hdd_wext.h>
89#ifdef WLAN_BTAMP_FEATURE
90#include <bap_hdd_main.h>
91#include <bapInternal.h>
92#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053093#include "wlan_hdd_trace.h"
94#include "vos_types.h"
95#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include <linux/wireless.h>
97#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053098#include <linux/inetdevice.h>
99#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "wlan_hdd_cfg80211.h"
101#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700102#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700103int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700104#include "sapApi.h"
105#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700106#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
108#include <soc/qcom/subsystem_restart.h>
109#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530111#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700112#include <wlan_hdd_hostapd.h>
113#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_hdd_dev_pwr.h"
116#ifdef WLAN_BTAMP_FEATURE
117#include "bap_hdd_misc.h"
118#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700120#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800121#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530122#ifdef FEATURE_WLAN_TDLS
123#include "wlan_hdd_tdls.h"
124#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700125#include "wlan_hdd_debugfs.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
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +0530191static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx);
Atul Mittal1d722422014-03-19 11:15:07 +0530192/*
193 * Maximum buffer size used for returning the data back to user space
194 */
195#define WLAN_MAX_BUF_SIZE 1024
196#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700197/*
198 * Driver miracast parameters 0-Disabled
199 * 1-Source, 2-Sink
200 */
201#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
202#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
203
c_hpothu92367912014-05-01 15:18:17 +0530204//wait time for beacon miss rate.
205#define BCN_MISS_RATE_TIME 500
206
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800207#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700208static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700211static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700212
213//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700214static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
215static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
216static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
217void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800218void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700219
Jeff Johnson295189b2012-06-20 16:38:30 -0700220v_U16_t hdd_select_queue(struct net_device *dev,
221 struct sk_buff *skb);
222
223#ifdef WLAN_FEATURE_PACKET_FILTERING
224static void hdd_set_multicast_list(struct net_device *dev);
225#endif
226
227void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
228
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800229#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800230void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
231static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700232static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
233 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
234 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700235static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
236 tANI_U8 *pTargetApBssid,
237 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800238#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800239#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700240VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800241#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700242
Mihir Shetee1093ba2014-01-21 20:13:32 +0530243static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530244const char * hdd_device_modetoString(v_U8_t device_mode)
245{
246 switch(device_mode)
247 {
248 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
249 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
250 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
251 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
252 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
253 CASE_RETURN_STRING( WLAN_HDD_FTM );
254 CASE_RETURN_STRING( WLAN_HDD_IBSS );
255 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
256 default:
257 return "device_mode Unknown";
258 }
259}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530260
Jeff Johnson295189b2012-06-20 16:38:30 -0700261static int hdd_netdev_notifier_call(struct notifier_block * nb,
262 unsigned long state,
263 void *ndev)
264{
265 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700266 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700267 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700268#ifdef WLAN_BTAMP_FEATURE
269 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700270#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530271 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700272
273 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700274 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700275 (strncmp(dev->name, "p2p", 3)))
276 return NOTIFY_DONE;
277
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700279 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700280
Jeff Johnson27cee452013-03-27 11:10:24 -0700281 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800283 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700284 VOS_ASSERT(0);
285 return NOTIFY_DONE;
286 }
287
Jeff Johnson27cee452013-03-27 11:10:24 -0700288 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
289 if (NULL == pHddCtx)
290 {
291 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
292 VOS_ASSERT(0);
293 return NOTIFY_DONE;
294 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800295 if (pHddCtx->isLogpInProgress)
296 return NOTIFY_DONE;
297
Jeff Johnson27cee452013-03-27 11:10:24 -0700298
299 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
300 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700301
302 switch (state) {
303 case NETDEV_REGISTER:
304 break;
305
306 case NETDEV_UNREGISTER:
307 break;
308
309 case NETDEV_UP:
310 break;
311
312 case NETDEV_DOWN:
313 break;
314
315 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700316 if(TRUE == pAdapter->isLinkUpSvcNeeded)
317 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 break;
319
320 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530321 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530322 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530323 {
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
325 "%s: Timeout occurred while waiting for abortscan %ld",
326 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 }
328 else
329 {
330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530331 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700332 }
333#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700335 status = WLANBAP_StopAmp();
336 if(VOS_STATUS_SUCCESS != status )
337 {
338 pHddCtx->isAmpAllowed = VOS_TRUE;
339 hddLog(VOS_TRACE_LEVEL_FATAL,
340 "%s: Failed to stop AMP", __func__);
341 }
342 else
343 {
344 //a state m/c implementation in PAL is TBD to avoid this delay
345 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700346 if ( pHddCtx->isAmpAllowed )
347 {
348 WLANBAP_DeregisterFromHCI();
349 pHddCtx->isAmpAllowed = VOS_FALSE;
350 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700351 }
352#endif //WLAN_BTAMP_FEATURE
353 break;
354
355 default:
356 break;
357 }
358
359 return NOTIFY_DONE;
360}
361
362struct notifier_block hdd_netdev_notifier = {
363 .notifier_call = hdd_netdev_notifier_call,
364};
365
366/*---------------------------------------------------------------------------
367 * Function definitions
368 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700369void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
370void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700371//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700372static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700373#ifndef MODULE
374/* current con_mode - used only for statically linked driver
375 * con_mode is changed by userspace to indicate a mode change which will
376 * result in calling the module exit and init functions. The module
377 * exit function will clean up based on the value of con_mode prior to it
378 * being changed by userspace. So curr_con_mode records the current con_mode
379 * for exit when con_mode becomes the next mode for init
380 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700381static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700382#endif
383
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800384/**---------------------------------------------------------------------------
385
386 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
387
388 Called immediately after the cfg.ini is read in order to configure
389 the desired trace levels.
390
391 \param - moduleId - module whose trace level is being configured
392 \param - bitmask - bitmask of log levels to be enabled
393
394 \return - void
395
396 --------------------------------------------------------------------------*/
397static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
398{
399 wpt_tracelevel level;
400
401 /* if the bitmask is the default value, then a bitmask was not
402 specified in cfg.ini, so leave the logging level alone (it
403 will remain at the "compiled in" default value) */
404 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
405 {
406 return;
407 }
408
409 /* a mask was specified. start by disabling all logging */
410 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
411
412 /* now cycle through the bitmask until all "set" bits are serviced */
413 level = VOS_TRACE_LEVEL_FATAL;
414 while (0 != bitmask)
415 {
416 if (bitmask & 1)
417 {
418 vos_trace_setValue(moduleId, level, 1);
419 }
420 level++;
421 bitmask >>= 1;
422 }
423}
424
425
Jeff Johnson295189b2012-06-20 16:38:30 -0700426/**---------------------------------------------------------------------------
427
428 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
429
430 Called immediately after the cfg.ini is read in order to configure
431 the desired trace levels in the WDI.
432
433 \param - moduleId - module whose trace level is being configured
434 \param - bitmask - bitmask of log levels to be enabled
435
436 \return - void
437
438 --------------------------------------------------------------------------*/
439static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
440{
441 wpt_tracelevel level;
442
443 /* if the bitmask is the default value, then a bitmask was not
444 specified in cfg.ini, so leave the logging level alone (it
445 will remain at the "compiled in" default value) */
446 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
447 {
448 return;
449 }
450
451 /* a mask was specified. start by disabling all logging */
452 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
453
454 /* now cycle through the bitmask until all "set" bits are serviced */
455 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
456 while (0 != bitmask)
457 {
458 if (bitmask & 1)
459 {
460 wpalTraceSetLevel(moduleId, level, 1);
461 }
462 level++;
463 bitmask >>= 1;
464 }
465}
Jeff Johnson295189b2012-06-20 16:38:30 -0700466
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530467/*
468 * FUNCTION: wlan_hdd_validate_context
469 * This function is used to check the HDD context
470 */
471int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
472{
473 ENTER();
474
475 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
476 {
477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
478 "%s: HDD context is Null", __func__);
479 return -ENODEV;
480 }
481
482 if (pHddCtx->isLogpInProgress)
483 {
484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
485 "%s: LOGP in Progress. Ignore!!!", __func__);
486 return -EAGAIN;
487 }
488
Mihir Shete18156292014-03-11 15:38:30 +0530489 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530490 {
491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
492 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
493 return -EAGAIN;
494 }
495 return 0;
496}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700497#ifdef CONFIG_ENABLE_LINUX_REG
498void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
499{
500 hdd_adapter_t *pAdapter = NULL;
501 hdd_station_ctx_t *pHddStaCtx = NULL;
502 eCsrPhyMode phyMode;
503 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530504
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700505 if (NULL == pHddCtx)
506 {
507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
508 "HDD Context is null !!");
509 return ;
510 }
511
512 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
513 if (NULL == pAdapter)
514 {
515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
516 "pAdapter is null !!");
517 return ;
518 }
519
520 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
521 if (NULL == pHddStaCtx)
522 {
523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
524 "pHddStaCtx is null !!");
525 return ;
526 }
527
528 cfg_param = pHddCtx->cfg_ini;
529 if (NULL == cfg_param)
530 {
531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
532 "cfg_params not available !!");
533 return ;
534 }
535
536 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
537
538 if (!pHddCtx->isVHT80Allowed)
539 {
540 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
541 (eCSR_DOT11_MODE_11ac == phyMode) ||
542 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
543 {
544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
545 "Setting phymode to 11n!!");
546 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
547 }
548 }
549 else
550 {
551 /*New country Supports 11ac as well resetting value back from .ini*/
552 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
553 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
554 return ;
555 }
556
557 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
558 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
559 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
560 {
561 VOS_STATUS vosStatus;
562
563 // need to issue a disconnect to CSR.
564 INIT_COMPLETION(pAdapter->disconnect_comp_var);
565 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
566 pAdapter->sessionId,
567 eCSR_DISCONNECT_REASON_UNSPECIFIED );
568
569 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530570 {
571 long ret;
572
573 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700574 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530575 if (0 >= ret)
576 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
577 ret);
578 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700579
580 }
581}
582#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530583void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
584{
585 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
586 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
587 hdd_config_t *cfg_param;
588 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530589 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530590
591 if (NULL == pHddCtx)
592 {
593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
594 "HDD Context is null !!");
595 return ;
596 }
597
598 cfg_param = pHddCtx->cfg_ini;
599
600 if (NULL == cfg_param)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
603 "cfg_params not available !!");
604 return ;
605 }
606
607 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
608
609 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
610 {
611 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
612 (eCSR_DOT11_MODE_11ac == phyMode) ||
613 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
614 {
615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
616 "Setting phymode to 11n!!");
617 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
618 }
619 }
620 else
621 {
622 /*New country Supports 11ac as well resetting value back from .ini*/
623 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
624 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
625 return ;
626 }
627
628 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
629 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
630 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
631 {
632 VOS_STATUS vosStatus;
633
634 // need to issue a disconnect to CSR.
635 INIT_COMPLETION(pAdapter->disconnect_comp_var);
636 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
637 pAdapter->sessionId,
638 eCSR_DISCONNECT_REASON_UNSPECIFIED );
639
640 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530641 {
642 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530643 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530644 if (ret <= 0)
645 {
646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
647 "wait on disconnect_comp_var is failed %ld", ret);
648 }
649 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530650
651 }
652}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700653#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530654
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700655void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
656{
657 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
658 hdd_config_t *cfg_param;
659
660 if (NULL == pHddCtx)
661 {
662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
663 "HDD Context is null !!");
664 return ;
665 }
666
667 cfg_param = pHddCtx->cfg_ini;
668
669 if (NULL == cfg_param)
670 {
671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
672 "cfg_params not available !!");
673 return ;
674 }
675
676 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
677 {
678 /*New country doesn't support DFS */
679 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
680 }
681 else
682 {
683 /*New country Supports DFS as well resetting value back from .ini*/
684 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
685 }
686
687}
688
Rajeev79dbe4c2013-10-05 11:03:42 +0530689#ifdef FEATURE_WLAN_BATCH_SCAN
690
691/**---------------------------------------------------------------------------
692
693 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
694 input string
695
696 This function extracts assigned integer from string in below format:
697 "STRING=10" : extracts integer 10 from this string
698
699 \param - pInPtr Pointer to input string
700 \param - base Base for string to int conversion(10 for decimal 16 for hex)
701 \param - pOutPtr Pointer to variable in which extracted integer needs to be
702 assigned
703 \param - pLastArg to tell whether it is last arguement in input string or
704 not
705
706 \return - NULL for failure cases
707 pointer to next arguement in input string for success cases
708 --------------------------------------------------------------------------*/
709static tANI_U8 *
710hdd_extract_assigned_int_from_str
711(
712 tANI_U8 *pInPtr,
713 tANI_U8 base,
714 tANI_U32 *pOutPtr,
715 tANI_U8 *pLastArg
716)
717{
718 int tempInt;
719 int v = 0;
720 char buf[32];
721 int val = 0;
722 *pLastArg = FALSE;
723
724 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
725 if (NULL == pInPtr)
726 {
727 return NULL;
728 }
729
730 pInPtr++;
731
732 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
733
734 val = sscanf(pInPtr, "%32s ", buf);
735 if (val < 0 && val > strlen(pInPtr))
736 {
737 return NULL;
738 }
739 pInPtr += val;
740 v = kstrtos32(buf, base, &tempInt);
741 if (v < 0)
742 {
743 return NULL;
744 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800745 if (tempInt < 0)
746 {
747 tempInt = 0;
748 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530749 *pOutPtr = tempInt;
750
751 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
752 if (NULL == pInPtr)
753 {
754 *pLastArg = TRUE;
755 return NULL;
756 }
757 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
758
759 return pInPtr;
760}
761
762/**---------------------------------------------------------------------------
763
764 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
765 input string
766
767 This function extracts assigned character from string in below format:
768 "STRING=A" : extracts char 'A' from this string
769
770 \param - pInPtr Pointer to input string
771 \param - pOutPtr Pointer to variable in which extracted char needs to be
772 assigned
773 \param - pLastArg to tell whether it is last arguement in input string or
774 not
775
776 \return - NULL for failure cases
777 pointer to next arguement in input string for success cases
778 --------------------------------------------------------------------------*/
779static tANI_U8 *
780hdd_extract_assigned_char_from_str
781(
782 tANI_U8 *pInPtr,
783 tANI_U8 *pOutPtr,
784 tANI_U8 *pLastArg
785)
786{
787 *pLastArg = FALSE;
788
789 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
790 if (NULL == pInPtr)
791 {
792 return NULL;
793 }
794
795 pInPtr++;
796
797 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
798
799 *pOutPtr = *pInPtr;
800
801 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
802 if (NULL == pInPtr)
803 {
804 *pLastArg = TRUE;
805 return NULL;
806 }
807 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
808
809 return pInPtr;
810}
811
812
813/**---------------------------------------------------------------------------
814
815 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
816
817 This function parses set batch scan command in below format:
818 WLS_BATCHING_SET <space> followed by below arguements
819 "SCANFREQ=XX" : Optional defaults to 30 sec
820 "MSCAN=XX" : Required number of scans to attempt to batch
821 "BESTN=XX" : Best Network (RSSI) defaults to 16
822 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
823 A. implies only 5 GHz , B. implies only 2.4GHz
824 "RTT=X" : optional defaults to 0
825 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
826 error
827
828 For example input commands:
829 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
830 translated into set batch scan with following parameters:
831 a) Frequence 60 seconds
832 b) Batch 10 scans together
833 c) Best RSSI to be 20
834 d) 5GHz band only
835 e) RTT is equal to 0
836
837 \param - pValue Pointer to input channel list
838 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
839
840 \return - 0 for success non-zero for failure
841
842 --------------------------------------------------------------------------*/
843static int
844hdd_parse_set_batchscan_command
845(
846 tANI_U8 *pValue,
847 tSirSetBatchScanReq *pHddSetBatchScanReq
848)
849{
850 tANI_U8 *inPtr = pValue;
851 tANI_U8 val = 0;
852 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800853 tANI_U32 nScanFreq;
854 tANI_U32 nMscan;
855 tANI_U32 nBestN;
856 tANI_U8 ucRfBand;
857 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800858 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530859
860 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800861 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
862 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
863 nRtt = 0;
864 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530865
866 /*go to space after WLS_BATCHING_SET command*/
867 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
868 /*no argument after the command*/
869 if (NULL == inPtr)
870 {
871 return -EINVAL;
872 }
873
874 /*no space after the command*/
875 else if (SPACE_ASCII_VALUE != *inPtr)
876 {
877 return -EINVAL;
878 }
879
880 /*removing empty spaces*/
881 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
882
883 /*no argument followed by spaces*/
884 if ('\0' == *inPtr)
885 {
886 return -EINVAL;
887 }
888
889 /*check and parse SCANFREQ*/
890 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
891 {
892 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800893 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800894
Rajeev Kumarc933d982013-11-18 20:04:20 -0800895 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800896 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800897 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800898 }
899
Rajeev79dbe4c2013-10-05 11:03:42 +0530900 if ( (NULL == inPtr) || (TRUE == lastArg))
901 {
902 return -EINVAL;
903 }
904 }
905
906 /*check and parse MSCAN*/
907 if ((strncmp(inPtr, "MSCAN", 5) == 0))
908 {
909 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800910 &nMscan, &lastArg);
911
912 if (0 == nMscan)
913 {
914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
915 "invalid MSCAN=%d", nMscan);
916 return -EINVAL;
917 }
918
Rajeev79dbe4c2013-10-05 11:03:42 +0530919 if (TRUE == lastArg)
920 {
921 goto done;
922 }
923 else if (NULL == inPtr)
924 {
925 return -EINVAL;
926 }
927 }
928 else
929 {
930 return -EINVAL;
931 }
932
933 /*check and parse BESTN*/
934 if ((strncmp(inPtr, "BESTN", 5) == 0))
935 {
936 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800937 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800938
Rajeev Kumarc933d982013-11-18 20:04:20 -0800939 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800940 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800941 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800942 }
943
Rajeev79dbe4c2013-10-05 11:03:42 +0530944 if (TRUE == lastArg)
945 {
946 goto done;
947 }
948 else if (NULL == inPtr)
949 {
950 return -EINVAL;
951 }
952 }
953
954 /*check and parse CHANNEL*/
955 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
956 {
957 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800958
Rajeev79dbe4c2013-10-05 11:03:42 +0530959 if (('A' == val) || ('a' == val))
960 {
c_hpothuebf89732014-02-25 13:00:24 +0530961 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530962 }
963 else if (('B' == val) || ('b' == val))
964 {
c_hpothuebf89732014-02-25 13:00:24 +0530965 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530966 }
967 else
968 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800969 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
970 }
971
972 if (TRUE == lastArg)
973 {
974 goto done;
975 }
976 else if (NULL == inPtr)
977 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530978 return -EINVAL;
979 }
980 }
981
982 /*check and parse RTT*/
983 if ((strncmp(inPtr, "RTT", 3) == 0))
984 {
985 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800986 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530987 if (TRUE == lastArg)
988 {
989 goto done;
990 }
991 if (NULL == inPtr)
992 {
993 return -EINVAL;
994 }
995 }
996
997
998done:
999
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001000 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1001 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1002 pHddSetBatchScanReq->bestNetwork = nBestN;
1003 pHddSetBatchScanReq->rfBand = ucRfBand;
1004 pHddSetBatchScanReq->rtt = nRtt;
1005
Rajeev79dbe4c2013-10-05 11:03:42 +05301006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1007 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1008 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1009 pHddSetBatchScanReq->scanFrequency,
1010 pHddSetBatchScanReq->numberOfScansToBatch,
1011 pHddSetBatchScanReq->bestNetwork,
1012 pHddSetBatchScanReq->rfBand,
1013 pHddSetBatchScanReq->rtt);
1014
1015 return 0;
1016}/*End of hdd_parse_set_batchscan_command*/
1017
1018/**---------------------------------------------------------------------------
1019
1020 \brief hdd_set_batch_scan_req_callback () - This function is called after
1021 receiving set batch scan response from FW and it saves set batch scan
1022 response data FW to HDD context and sets the completion event on
1023 which hdd_ioctl is waiting
1024
1025 \param - callbackContext Pointer to HDD adapter
1026 \param - pRsp Pointer to set batch scan response data received from FW
1027
1028 \return - nothing
1029
1030 --------------------------------------------------------------------------*/
1031static void hdd_set_batch_scan_req_callback
1032(
1033 void *callbackContext,
1034 tSirSetBatchScanRsp *pRsp
1035)
1036{
1037 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1038 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1039
1040 /*sanity check*/
1041 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1042 {
1043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1044 "%s: Invalid pAdapter magic", __func__);
1045 VOS_ASSERT(0);
1046 return;
1047 }
1048 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1049
1050 /*save set batch scan response*/
1051 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1052
1053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1054 "Received set batch scan rsp from FW with nScansToBatch=%d",
1055 pHddSetBatchScanRsp->nScansToBatch);
1056
1057 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1058 complete(&pAdapter->hdd_set_batch_scan_req_var);
1059
1060 return;
1061}/*End of hdd_set_batch_scan_req_callback*/
1062
1063
1064/**---------------------------------------------------------------------------
1065
1066 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1067 info in hdd batch scan response queue
1068
1069 \param - pAdapter Pointer to hdd adapter
1070 \param - pAPMetaInfo Pointer to access point meta info
1071 \param - scanId scan ID of batch scan response
1072 \param - isLastAp tells whether AP is last AP in batch scan response or not
1073
1074 \return - nothing
1075
1076 --------------------------------------------------------------------------*/
1077static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1078 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1079{
1080 tHddBatchScanRsp *pHead;
1081 tHddBatchScanRsp *pNode;
1082 tHddBatchScanRsp *pPrev;
1083 tHddBatchScanRsp *pTemp;
1084 tANI_U8 ssidLen;
1085
1086 /*head of hdd batch scan response queue*/
1087 pHead = pAdapter->pBatchScanRsp;
1088
1089 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1090 if (NULL == pNode)
1091 {
1092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1093 "%s: Could not allocate memory", __func__);
1094 VOS_ASSERT(0);
1095 return;
1096 }
1097
1098 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1099 sizeof(pNode->ApInfo.bssid));
1100 ssidLen = strlen(pApMetaInfo->ssid);
1101 if (SIR_MAX_SSID_SIZE < ssidLen)
1102 {
1103 /*invalid scan result*/
1104 vos_mem_free(pNode);
1105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1106 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1107 return;
1108 }
1109 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1110 /*null terminate ssid*/
1111 pNode->ApInfo.ssid[ssidLen] = '\0';
1112 pNode->ApInfo.ch = pApMetaInfo->ch;
1113 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1114 pNode->ApInfo.age = pApMetaInfo->timestamp;
1115 pNode->ApInfo.batchId = scanId;
1116 pNode->ApInfo.isLastAp = isLastAp;
1117
1118 pNode->pNext = NULL;
1119 if (NULL == pHead)
1120 {
1121 pAdapter->pBatchScanRsp = pNode;
1122 }
1123 else
1124 {
1125 pTemp = pHead;
1126 while (NULL != pTemp)
1127 {
1128 pPrev = pTemp;
1129 pTemp = pTemp->pNext;
1130 }
1131 pPrev->pNext = pNode;
1132 }
1133
1134 return;
1135}/*End of hdd_populate_batch_scan_rsp_queue*/
1136
1137/**---------------------------------------------------------------------------
1138
1139 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1140 receiving batch scan response indication from FW. It saves get batch scan
1141 response data in HDD batch scan response queue. This callback sets the
1142 completion event on which hdd_ioctl is waiting only after getting complete
1143 batch scan response data from FW
1144
1145 \param - callbackContext Pointer to HDD adapter
1146 \param - pRsp Pointer to get batch scan response data received from FW
1147
1148 \return - nothing
1149
1150 --------------------------------------------------------------------------*/
1151static void hdd_batch_scan_result_ind_callback
1152(
1153 void *callbackContext,
1154 void *pRsp
1155)
1156{
1157 v_BOOL_t isLastAp;
1158 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001159 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301160 tANI_U32 numberScanList;
1161 tANI_U32 nextScanListOffset;
1162 tANI_U32 nextApMetaInfoOffset;
1163 hdd_adapter_t* pAdapter;
1164 tpSirBatchScanList pScanList;
1165 tpSirBatchScanNetworkInfo pApMetaInfo;
1166 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1167 tSirSetBatchScanReq *pReq;
1168
1169 pAdapter = (hdd_adapter_t *)callbackContext;
1170 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001171 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301172 {
1173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1174 "%s: Invalid pAdapter magic", __func__);
1175 VOS_ASSERT(0);
1176 return;
1177 }
1178
1179 /*initialize locals*/
1180 pReq = &pAdapter->hddSetBatchScanReq;
1181 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1182 isLastAp = FALSE;
1183 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001184 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301185 numberScanList = 0;
1186 nextScanListOffset = 0;
1187 nextApMetaInfoOffset = 0;
1188 pScanList = NULL;
1189 pApMetaInfo = NULL;
1190
1191 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1192 {
1193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1194 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1195 isLastAp = TRUE;
1196 goto done;
1197 }
1198
1199 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "Batch scan rsp: numberScalList %d", numberScanList);
1202
1203 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1204 {
1205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1206 "%s: numberScanList %d", __func__, numberScanList);
1207 isLastAp = TRUE;
1208 goto done;
1209 }
1210
1211 while (numberScanList)
1212 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001213 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301214 nextScanListOffset);
1215 if (NULL == pScanList)
1216 {
1217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1218 "%s: pScanList is %p", __func__, pScanList);
1219 isLastAp = TRUE;
1220 goto done;
1221 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001222 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001224 "Batch scan rsp: numApMetaInfo %d scanId %d",
1225 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301226
1227 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1228 {
1229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1230 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1231 isLastAp = TRUE;
1232 goto done;
1233 }
1234
Rajeev Kumarce651e42013-10-21 18:57:15 -07001235 /*Initialize next AP meta info offset for next scan list*/
1236 nextApMetaInfoOffset = 0;
1237
Rajeev79dbe4c2013-10-05 11:03:42 +05301238 while (numApMetaInfo)
1239 {
1240 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1241 nextApMetaInfoOffset);
1242 if (NULL == pApMetaInfo)
1243 {
1244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1245 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1246 isLastAp = TRUE;
1247 goto done;
1248 }
1249 /*calculate AP age*/
1250 pApMetaInfo->timestamp =
1251 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1252
1253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001254 "%s: bssId "MAC_ADDRESS_STR
1255 " ch %d rssi %d timestamp %d", __func__,
1256 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1257 pApMetaInfo->ch, pApMetaInfo->rssi,
1258 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301259
1260 /*mark last AP in batch scan response*/
1261 if ((TRUE == pBatchScanRsp->isLastResult) &&
1262 (1 == numberScanList) && (1 == numApMetaInfo))
1263 {
1264 isLastAp = TRUE;
1265 }
1266
1267 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1268 /*store batch scan repsonse in hdd queue*/
1269 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1270 pScanList->scanId, isLastAp);
1271 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1272
1273 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1274 numApMetaInfo--;
1275 }
1276
Rajeev Kumarce651e42013-10-21 18:57:15 -07001277 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1278 + (sizeof(tSirBatchScanNetworkInfo)
1279 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301280 numberScanList--;
1281 }
1282
1283done:
1284
1285 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1286 requested from hdd_ioctl*/
1287 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1288 (TRUE == isLastAp))
1289 {
1290 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1291 complete(&pAdapter->hdd_get_batch_scan_req_var);
1292 }
1293
1294 return;
1295}/*End of hdd_batch_scan_result_ind_callback*/
1296
1297/**---------------------------------------------------------------------------
1298
1299 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1300 response as per batch scan FR request format by putting proper markers
1301
1302 \param - pDest pointer to destination buffer
1303 \param - cur_len current length
1304 \param - tot_len total remaining size which can be written to user space
1305 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1306 \param - pAdapter Pointer to HDD adapter
1307
1308 \return - ret no of characters written
1309
1310 --------------------------------------------------------------------------*/
1311static tANI_U32
1312hdd_format_batch_scan_rsp
1313(
1314 tANI_U8 *pDest,
1315 tANI_U32 cur_len,
1316 tANI_U32 tot_len,
1317 tHddBatchScanRsp *pApMetaInfo,
1318 hdd_adapter_t* pAdapter
1319)
1320{
1321 tANI_U32 ret = 0;
1322 tANI_U32 rem_len = 0;
1323 tANI_U8 temp_len = 0;
1324 tANI_U8 temp_total_len = 0;
1325 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1326 tANI_U8 *pTemp = temp;
1327
1328 /*Batch scan reponse needs to be returned to user space in
1329 following format:
1330 "scancount=X\n" where X is the number of scans in current batch
1331 batch
1332 "trunc\n" optional present if current scan truncated
1333 "bssid=XX:XX:XX:XX:XX:XX\n"
1334 "ssid=XXXX\n"
1335 "freq=X\n" frequency in Mhz
1336 "level=XX\n"
1337 "age=X\n" ms
1338 "dist=X\n" cm (-1 if not available)
1339 "errror=X\n" (-1if not available)
1340 "====\n" (end of ap marker)
1341 "####\n" (end of scan marker)
1342 "----\n" (end of results)*/
1343 /*send scan result in above format to user space based on
1344 available length*/
1345 /*The GET response may have more data than the driver can return in its
1346 buffer. In that case the buffer should be filled to the nearest complete
1347 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1348 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1349 The final buffer should end with "----\n"*/
1350
1351 /*sanity*/
1352 if (cur_len > tot_len)
1353 {
1354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1355 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1356 return 0;
1357 }
1358 else
1359 {
1360 rem_len = (tot_len - cur_len);
1361 }
1362
1363 /*end scan marker*/
1364 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1365 {
1366 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1367 pTemp += temp_len;
1368 temp_total_len += temp_len;
1369 }
1370
1371 /*bssid*/
1372 temp_len = snprintf(pTemp, sizeof(temp),
1373 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1374 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1375 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1376 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1377 pTemp += temp_len;
1378 temp_total_len += temp_len;
1379
1380 /*ssid*/
1381 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1382 pApMetaInfo->ApInfo.ssid);
1383 pTemp += temp_len;
1384 temp_total_len += temp_len;
1385
1386 /*freq*/
1387 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001388 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301389 pTemp += temp_len;
1390 temp_total_len += temp_len;
1391
1392 /*level*/
1393 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1394 pApMetaInfo->ApInfo.rssi);
1395 pTemp += temp_len;
1396 temp_total_len += temp_len;
1397
1398 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001399 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301400 pApMetaInfo->ApInfo.age);
1401 pTemp += temp_len;
1402 temp_total_len += temp_len;
1403
1404 /*dist*/
1405 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1406 pTemp += temp_len;
1407 temp_total_len += temp_len;
1408
1409 /*error*/
1410 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1411 pTemp += temp_len;
1412 temp_total_len += temp_len;
1413
1414 /*end AP marker*/
1415 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1416 pTemp += temp_len;
1417 temp_total_len += temp_len;
1418
1419 /*last AP in batch scan response*/
1420 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1421 {
1422 /*end scan marker*/
1423 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1424 pTemp += temp_len;
1425 temp_total_len += temp_len;
1426
1427 /*end batch scan result marker*/
1428 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1429 pTemp += temp_len;
1430 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001431
Rajeev79dbe4c2013-10-05 11:03:42 +05301432 }
1433
1434 if (temp_total_len < rem_len)
1435 {
1436 ret = temp_total_len + 1;
1437 strlcpy(pDest, temp, ret);
1438 pAdapter->isTruncated = FALSE;
1439 }
1440 else
1441 {
1442 pAdapter->isTruncated = TRUE;
1443 if (rem_len >= strlen("%%%%"))
1444 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001445 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301446 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001447 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301448 {
1449 ret = 0;
1450 }
1451 }
1452
1453 return ret;
1454
1455}/*End of hdd_format_batch_scan_rsp*/
1456
1457/**---------------------------------------------------------------------------
1458
1459 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1460 buffer starting with head of hdd batch scan response queue
1461
1462 \param - pAdapter Pointer to HDD adapter
1463 \param - pDest Pointer to user data buffer
1464 \param - cur_len current offset in user buffer
1465 \param - rem_len remaining no of bytes in user buffer
1466
1467 \return - number of bytes written in user buffer
1468
1469 --------------------------------------------------------------------------*/
1470
1471tANI_U32 hdd_populate_user_batch_scan_rsp
1472(
1473 hdd_adapter_t* pAdapter,
1474 tANI_U8 *pDest,
1475 tANI_U32 cur_len,
1476 tANI_U32 rem_len
1477)
1478{
1479 tHddBatchScanRsp *pHead;
1480 tHddBatchScanRsp *pPrev;
1481 tANI_U32 len;
1482
Rajeev79dbe4c2013-10-05 11:03:42 +05301483 pAdapter->isTruncated = FALSE;
1484
1485 /*head of hdd batch scan response queue*/
1486 pHead = pAdapter->pBatchScanRsp;
1487 while (pHead)
1488 {
1489 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1490 pAdapter);
1491 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001492 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301493 cur_len += len;
1494 if(TRUE == pAdapter->isTruncated)
1495 {
1496 /*result is truncated return rest of scan rsp in next req*/
1497 cur_len = rem_len;
1498 break;
1499 }
1500 pPrev = pHead;
1501 pHead = pHead->pNext;
1502 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001503 if (TRUE == pPrev->ApInfo.isLastAp)
1504 {
1505 pAdapter->prev_batch_id = 0;
1506 }
1507 else
1508 {
1509 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1510 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301511 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001512 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301513 }
1514
1515 return cur_len;
1516}/*End of hdd_populate_user_batch_scan_rsp*/
1517
1518/**---------------------------------------------------------------------------
1519
1520 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1521 scan response data from HDD queue to user space
1522 It does following in detail:
1523 a) if HDD has enough data in its queue then it 1st copies data to user
1524 space and then send get batch scan indication message to FW. In this
1525 case it does not wait on any event and batch scan response data will
1526 be populated in HDD response queue in MC thread context after receiving
1527 indication from FW
1528 b) else send get batch scan indication message to FW and wait on an event
1529 which will be set once HDD receives complete batch scan response from
1530 FW and then this function returns batch scan response to user space
1531
1532 \param - pAdapter Pointer to HDD adapter
1533 \param - pPrivData Pointer to priv_data
1534
1535 \return - 0 for success -EFAULT for failure
1536
1537 --------------------------------------------------------------------------*/
1538
1539int hdd_return_batch_scan_rsp_to_user
1540(
1541 hdd_adapter_t* pAdapter,
1542 hdd_priv_data_t *pPrivData,
1543 tANI_U8 *command
1544)
1545{
1546 tANI_U8 *pDest;
1547 tANI_U32 count = 0;
1548 tANI_U32 len = 0;
1549 tANI_U32 cur_len = 0;
1550 tANI_U32 rem_len = 0;
1551 eHalStatus halStatus;
1552 unsigned long rc;
1553 tSirTriggerBatchScanResultInd *pReq;
1554
1555 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1556 pReq->param = 0;/*batch scan client*/
1557 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1558 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1559
1560 cur_len = pPrivData->used_len;
1561 if (pPrivData->total_len > pPrivData->used_len)
1562 {
1563 rem_len = pPrivData->total_len - pPrivData->used_len;
1564 }
1565 else
1566 {
1567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1568 "%s: Invalid user data buffer total_len %d used_len %d",
1569 __func__, pPrivData->total_len, pPrivData->used_len);
1570 return -EFAULT;
1571 }
1572
1573 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1574 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1575 cur_len, rem_len);
1576 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1577
1578 /*enough scan result available in cache to return to user space or
1579 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001580 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301581 {
1582 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1583 halStatus = sme_TriggerBatchScanResultInd(
1584 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1585 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1586 pAdapter);
1587 if ( eHAL_STATUS_SUCCESS == halStatus )
1588 {
1589 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1590 {
1591 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1592 rc = wait_for_completion_timeout(
1593 &pAdapter->hdd_get_batch_scan_req_var,
1594 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1595 if (0 == rc)
1596 {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 "%s: Timeout waiting to fetch batch scan rsp from fw",
1599 __func__);
1600 return -EFAULT;
1601 }
1602 }
1603
1604 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001605 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301606 pDest += len;
1607 cur_len += len;
1608
1609 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1610 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1611 cur_len, rem_len);
1612 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1613
1614 count = 0;
1615 len = (len - pPrivData->used_len);
1616 pDest = (command + pPrivData->used_len);
1617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001618 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301619 while(count < len)
1620 {
1621 printk("%c", *(pDest + count));
1622 count++;
1623 }
1624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1625 "%s: copy %d data to user buffer", __func__, len);
1626 if (copy_to_user(pPrivData->buf, pDest, len))
1627 {
1628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1629 "%s: failed to copy data to user buffer", __func__);
1630 return -EFAULT;
1631 }
1632 }
1633 else
1634 {
1635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1636 "sme_GetBatchScanScan returned failure halStatus %d",
1637 halStatus);
1638 return -EINVAL;
1639 }
1640 }
1641 else
1642 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301643 count = 0;
1644 len = (len - pPrivData->used_len);
1645 pDest = (command + pPrivData->used_len);
1646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001647 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301648 while(count < len)
1649 {
1650 printk("%c", *(pDest + count));
1651 count++;
1652 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1654 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301655 if (copy_to_user(pPrivData->buf, pDest, len))
1656 {
1657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1658 "%s: failed to copy data to user buffer", __func__);
1659 return -EFAULT;
1660 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301661 }
1662
1663 return 0;
1664} /*End of hdd_return_batch_scan_rsp_to_user*/
1665
Rajeev Kumar8b373292014-01-08 20:36:55 -08001666
1667/**---------------------------------------------------------------------------
1668
1669 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1670 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1671 WLS_BATCHING VERSION
1672 WLS_BATCHING SET
1673 WLS_BATCHING GET
1674 WLS_BATCHING STOP
1675
1676 \param - pAdapter Pointer to HDD adapter
1677 \param - pPrivdata Pointer to priv_data
1678 \param - command Pointer to command
1679
1680 \return - 0 for success -EFAULT for failure
1681
1682 --------------------------------------------------------------------------*/
1683
1684int hdd_handle_batch_scan_ioctl
1685(
1686 hdd_adapter_t *pAdapter,
1687 hdd_priv_data_t *pPrivdata,
1688 tANI_U8 *command
1689)
1690{
1691 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001692 hdd_context_t *pHddCtx;
1693
1694 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1695 ret = wlan_hdd_validate_context(pHddCtx);
1696 if (ret)
1697 {
1698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1699 "%s: HDD context is not valid!", __func__);
1700 goto exit;
1701 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001702
1703 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1704 {
1705 char extra[32];
1706 tANI_U8 len = 0;
1707 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1708
1709 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1710 {
1711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1712 "%s: Batch scan feature is not supported by FW", __func__);
1713 ret = -EINVAL;
1714 goto exit;
1715 }
1716
1717 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1718 version);
1719 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1720 {
1721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1722 "%s: failed to copy data to user buffer", __func__);
1723 ret = -EFAULT;
1724 goto exit;
1725 }
1726 ret = HDD_BATCH_SCAN_VERSION;
1727 }
1728 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1729 {
1730 int status;
1731 tANI_U8 *value = (command + 16);
1732 eHalStatus halStatus;
1733 unsigned long rc;
1734 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1735 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1736
1737 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1738 {
1739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1740 "%s: Batch scan feature is not supported by FW", __func__);
1741 ret = -EINVAL;
1742 goto exit;
1743 }
1744
1745 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1746 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1747 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1748 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1749 {
1750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301751 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001752 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301753 hdd_device_modetoString(pAdapter->device_mode),
1754 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001755 ret = -EINVAL;
1756 goto exit;
1757 }
1758
1759 status = hdd_parse_set_batchscan_command(value, pReq);
1760 if (status)
1761 {
1762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1763 "Invalid WLS_BATCHING SET command");
1764 ret = -EINVAL;
1765 goto exit;
1766 }
1767
1768
1769 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1770 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1771 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1772 pAdapter);
1773
1774 if ( eHAL_STATUS_SUCCESS == halStatus )
1775 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301776 char extra[32];
1777 tANI_U8 len = 0;
1778 tANI_U8 mScan = 0;
1779
Rajeev Kumar8b373292014-01-08 20:36:55 -08001780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1781 "sme_SetBatchScanReq returned success halStatus %d",
1782 halStatus);
1783 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1784 {
1785 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1786 rc = wait_for_completion_timeout(
1787 &pAdapter->hdd_set_batch_scan_req_var,
1788 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1789 if (0 == rc)
1790 {
1791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1792 "%s: Timeout waiting for set batch scan to complete",
1793 __func__);
1794 ret = -EINVAL;
1795 goto exit;
1796 }
1797 }
1798 if ( !pRsp->nScansToBatch )
1799 {
1800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1801 "%s: Received set batch scan failure response from FW",
1802 __func__);
1803 ret = -EINVAL;
1804 goto exit;
1805 }
1806 /*As per the Batch Scan Framework API we should return the MIN of
1807 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301808 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001809
1810 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1811
1812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1813 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301814 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1815 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1816 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1817 {
1818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1819 "%s: failed to copy MSCAN value to user buffer", __func__);
1820 ret = -EFAULT;
1821 goto exit;
1822 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001823 }
1824 else
1825 {
1826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1827 "sme_SetBatchScanReq returned failure halStatus %d",
1828 halStatus);
1829 ret = -EINVAL;
1830 goto exit;
1831 }
1832 }
1833 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1834 {
1835 eHalStatus halStatus;
1836 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1837 pInd->param = 0;
1838
1839 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1840 {
1841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1842 "%s: Batch scan feature is not supported by FW", __func__);
1843 ret = -EINVAL;
1844 goto exit;
1845 }
1846
1847 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1848 {
1849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1850 "Batch scan is not yet enabled batch scan state %d",
1851 pAdapter->batchScanState);
1852 ret = -EINVAL;
1853 goto exit;
1854 }
1855
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001856 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1857 hdd_deinit_batch_scan(pAdapter);
1858 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1859
Rajeev Kumar8b373292014-01-08 20:36:55 -08001860 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1861
1862 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1863 pAdapter->sessionId);
1864 if ( eHAL_STATUS_SUCCESS == halStatus )
1865 {
1866 ret = 0;
1867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1868 "sme_StopBatchScanInd returned success halStatus %d",
1869 halStatus);
1870 }
1871 else
1872 {
1873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1874 "sme_StopBatchScanInd returned failure halStatus %d",
1875 halStatus);
1876 ret = -EINVAL;
1877 goto exit;
1878 }
1879 }
1880 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1881 {
1882 tANI_U32 remain_len;
1883
1884 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1885 {
1886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1887 "%s: Batch scan feature is not supported by FW", __func__);
1888 ret = -EINVAL;
1889 goto exit;
1890 }
1891
1892 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1893 {
1894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1895 "Batch scan is not yet enabled could not return results"
1896 "Batch Scan state %d",
1897 pAdapter->batchScanState);
1898 ret = -EINVAL;
1899 goto exit;
1900 }
1901
1902 pPrivdata->used_len = 16;
1903 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1904 if (remain_len < pPrivdata->total_len)
1905 {
1906 /*Clear previous batch scan response data if any*/
1907 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1908 }
1909 else
1910 {
1911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1912 "Invalid total length from user space can't fetch batch"
1913 " scan response total_len %d used_len %d remain len %d",
1914 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1915 ret = -EINVAL;
1916 goto exit;
1917 }
1918 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1919 }
1920
1921exit:
1922
1923 return ret;
1924}
1925
1926
Rajeev79dbe4c2013-10-05 11:03:42 +05301927#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1928
c_hpothu92367912014-05-01 15:18:17 +05301929static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1930{
c_hpothu39eb1e32014-06-26 16:31:50 +05301931 bcnMissRateContext_t *pCBCtx;
1932
1933 if (NULL == data)
1934 {
1935 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1936 return;
1937 }
c_hpothu92367912014-05-01 15:18:17 +05301938
1939 /* there is a race condition that exists between this callback
1940 function and the caller since the caller could time out either
1941 before or while this code is executing. we use a spinlock to
1942 serialize these actions */
1943 spin_lock(&hdd_context_lock);
1944
c_hpothu39eb1e32014-06-26 16:31:50 +05301945 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301946 gbcnMissRate = -1;
1947
c_hpothu39eb1e32014-06-26 16:31:50 +05301948 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301949 {
1950 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301951 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301952 spin_unlock(&hdd_context_lock);
1953 return ;
1954 }
1955
1956 if (VOS_STATUS_SUCCESS == status)
1957 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301958 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301959 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301960 else
1961 {
1962 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1963 }
1964
c_hpothu92367912014-05-01 15:18:17 +05301965 complete(&(pCBCtx->completion));
1966 spin_unlock(&hdd_context_lock);
1967
1968 return;
1969}
1970
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05301971static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
1972{
1973 int ret = 0;
1974
1975 if (!pCfg || !command || !extra || !len)
1976 {
1977 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1978 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
1979 ret = -EINVAL;
1980 return ret;
1981 }
1982
1983 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
1984 {
1985 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
1986 (int)pCfg->nActiveMaxChnTime);
1987 return ret;
1988 }
1989 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
1990 {
1991 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
1992 (int)pCfg->nActiveMinChnTime);
1993 return ret;
1994 }
1995 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
1996 {
1997 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
1998 (int)pCfg->nPassiveMaxChnTime);
1999 return ret;
2000 }
2001 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2002 {
2003 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2004 (int)pCfg->nPassiveMinChnTime);
2005 return ret;
2006 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302007 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2008 {
2009 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2010 (int)pCfg->nActiveMaxChnTime);
2011 return ret;
2012 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302013 else
2014 {
2015 ret = -EINVAL;
2016 }
2017
2018 return ret;
2019}
2020
2021static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2022{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302023 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302024 hdd_config_t *pCfg;
2025 tANI_U8 *value = command;
2026 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302027 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302028
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302029 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2030 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302031 {
2032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2033 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2034 ret = -EINVAL;
2035 return ret;
2036 }
2037
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302038 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2039 sme_GetConfigParam(hHal, &smeConfig);
2040
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302041 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2042 {
2043 value = value + 24;
2044 temp = kstrtou32(value, 10, &val);
2045 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2046 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2047 {
2048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2049 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2050 ret = -EFAULT;
2051 return ret;
2052 }
2053 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302054 smeConfig.csrConfig.nActiveMaxChnTime = val;
2055 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302056 }
2057 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2058 {
2059 value = value + 24;
2060 temp = kstrtou32(value, 10, &val);
2061 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2062 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2063 {
2064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2065 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2066 ret = -EFAULT;
2067 return ret;
2068 }
2069 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302070 smeConfig.csrConfig.nActiveMinChnTime = val;
2071 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302072 }
2073 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2074 {
2075 value = value + 25;
2076 temp = kstrtou32(value, 10, &val);
2077 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2078 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2079 {
2080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2081 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2082 ret = -EFAULT;
2083 return ret;
2084 }
2085 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302086 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2087 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302088 }
2089 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2090 {
2091 value = value + 25;
2092 temp = kstrtou32(value, 10, &val);
2093 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2094 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2095 {
2096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2097 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2098 ret = -EFAULT;
2099 return ret;
2100 }
2101 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302102 smeConfig.csrConfig.nPassiveMinChnTime = val;
2103 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302104 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302105 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2106 {
2107 value = value + 13;
2108 temp = kstrtou32(value, 10, &val);
2109 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2110 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2111 {
2112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2113 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2114 ret = -EFAULT;
2115 return ret;
2116 }
2117 pCfg->nActiveMaxChnTime = val;
2118 smeConfig.csrConfig.nActiveMaxChnTime = val;
2119 sme_UpdateConfig(hHal, &smeConfig);
2120 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302121 else
2122 {
2123 ret = -EINVAL;
2124 }
2125
2126 return ret;
2127}
2128
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002129static int hdd_driver_command(hdd_adapter_t *pAdapter,
2130 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002131{
Jeff Johnson295189b2012-06-20 16:38:30 -07002132 hdd_priv_data_t priv_data;
2133 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002134 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07002135
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002136 /*
2137 * Note that valid pointers are provided by caller
2138 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002139
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002140 /* copy to local struct to avoid numerous changes to legacy code */
2141 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002142
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002143 if (priv_data.total_len <= 0 ||
2144 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002145 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002146 hddLog(VOS_TRACE_LEVEL_WARN,
2147 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2148 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002149 ret = -EINVAL;
2150 goto exit;
2151 }
2152
2153 /* Allocate +1 for '\0' */
2154 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 if (!command)
2156 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002157 hddLog(VOS_TRACE_LEVEL_ERROR,
2158 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002159 ret = -ENOMEM;
2160 goto exit;
2161 }
2162
2163 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2164 {
2165 ret = -EFAULT;
2166 goto exit;
2167 }
2168
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002169 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002170 command[priv_data.total_len] = '\0';
2171
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002172 /* at one time the following block of code was conditional. braces
2173 * have been retained to avoid re-indenting the legacy code
2174 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002175 {
2176 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2177
2178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002179 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002180
2181 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2182 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302183 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2184 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2185 pAdapter->sessionId, (unsigned)
2186 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2187 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2188 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2189 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002190 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2191 sizeof(tSirMacAddr)))
2192 {
2193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002194 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002195 ret = -EFAULT;
2196 }
2197 }
Amar Singhal0974e402013-02-12 14:27:46 -08002198 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002199 {
Amar Singhal0974e402013-02-12 14:27:46 -08002200 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002201
Jeff Johnson295189b2012-06-20 16:38:30 -07002202 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002203
2204 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002205 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002207 "%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 -07002208 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002209 ret = hdd_setBand_helper(pAdapter->dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302210 if(ret != 0)
2211 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002212 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002213 }
Kiet Lamf040f472013-11-20 21:15:23 +05302214 else if(strncmp(command, "SETWMMPS", 8) == 0)
2215 {
2216 tANI_U8 *ptr = command;
2217 ret = hdd_wmmps_helper(pAdapter, ptr);
2218 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002219 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2220 {
2221 char *country_code;
2222
2223 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002224
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002225 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002226 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002227#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302228 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002229#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002230 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2231 (void *)(tSmeChangeCountryCallback)
2232 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302233 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002234 if (eHAL_STATUS_SUCCESS == ret)
2235 {
2236 ret = wait_for_completion_interruptible_timeout(
2237 &pAdapter->change_country_code,
2238 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2239 if (0 >= ret)
2240 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302242 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002243 }
2244 }
2245 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002246 {
2247 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002248 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002249 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002250 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002251
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002252 }
2253 /*
2254 command should be a string having format
2255 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2256 */
Amar Singhal0974e402013-02-12 14:27:46 -08002257 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002258 {
Amar Singhal0974e402013-02-12 14:27:46 -08002259 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002260
2261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002262 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002263
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002264 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002265 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002266 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2267 {
2268 int suspend = 0;
2269 tANI_U8 *ptr = (tANI_U8*)command + 15;
2270
2271 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302272 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2273 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2274 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002275 hdd_set_wlan_suspend_mode(suspend);
2276 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002277#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2278 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2279 {
2280 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002281 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002282 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2283 eHalStatus status = eHAL_STATUS_SUCCESS;
2284
2285 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2286 value = value + 15;
2287
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002288 /* Convert the value from ascii to integer */
2289 ret = kstrtos8(value, 10, &rssi);
2290 if (ret < 0)
2291 {
2292 /* If the input value is greater than max value of datatype, then also
2293 kstrtou8 fails */
2294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2295 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002296 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002297 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2298 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2299 ret = -EINVAL;
2300 goto exit;
2301 }
2302
Srinivas Girigowdade697412013-02-14 16:31:48 -08002303 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002304
Srinivas Girigowdade697412013-02-14 16:31:48 -08002305 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2306 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2307 {
2308 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2309 "Neighbor lookup threshold value %d is out of range"
2310 " (Min: %d Max: %d)", lookUpThreshold,
2311 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2312 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2313 ret = -EINVAL;
2314 goto exit;
2315 }
2316
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302317 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2318 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2319 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2321 "%s: Received Command to Set Roam trigger"
2322 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2323
2324 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2325 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2326 if (eHAL_STATUS_SUCCESS != status)
2327 {
2328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2329 "%s: Failed to set roam trigger, try again", __func__);
2330 ret = -EPERM;
2331 goto exit;
2332 }
2333
2334 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302335 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002336 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2337 }
2338 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2339 {
2340 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2341 int rssi = (-1) * lookUpThreshold;
2342 char extra[32];
2343 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302344 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2345 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2346 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002347 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002348 if (copy_to_user(priv_data.buf, &extra, len + 1))
2349 {
2350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2351 "%s: failed to copy data to user buffer", __func__);
2352 ret = -EFAULT;
2353 goto exit;
2354 }
2355 }
2356 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2357 {
2358 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002359 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002360 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002361
Srinivas Girigowdade697412013-02-14 16:31:48 -08002362 /* input refresh period is in terms of seconds */
2363 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2364 value = value + 18;
2365 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002366 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002367 if (ret < 0)
2368 {
2369 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002370 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002372 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002373 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002374 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2375 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002376 ret = -EINVAL;
2377 goto exit;
2378 }
2379
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002380 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2381 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002382 {
2383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002384 "Roam scan period value %d is out of range"
2385 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002386 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2387 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002388 ret = -EINVAL;
2389 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302390 }
2391 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2392 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2393 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002394 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002395
2396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2397 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002398 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002399
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002400 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2401 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002402 }
2403 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2404 {
2405 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2406 char extra[32];
2407 tANI_U8 len = 0;
2408
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302409 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2410 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2411 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002412 len = scnprintf(extra, sizeof(extra), "%s %d",
2413 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002414 /* Returned value is in units of seconds */
2415 if (copy_to_user(priv_data.buf, &extra, len + 1))
2416 {
2417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2418 "%s: failed to copy data to user buffer", __func__);
2419 ret = -EFAULT;
2420 goto exit;
2421 }
2422 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002423 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2424 {
2425 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002426 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002427 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002428
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002429 /* input refresh period is in terms of seconds */
2430 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2431 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002432
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002433 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002434 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002435 if (ret < 0)
2436 {
2437 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002438 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002440 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002441 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002442 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2443 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2444 ret = -EINVAL;
2445 goto exit;
2446 }
2447
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002448 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2449 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2450 {
2451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2452 "Neighbor scan results refresh period value %d is out of range"
2453 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2454 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2455 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2456 ret = -EINVAL;
2457 goto exit;
2458 }
2459 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2460
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2462 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002463 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002464
2465 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2466 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2467 }
2468 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2469 {
2470 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2471 char extra[32];
2472 tANI_U8 len = 0;
2473
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002474 len = scnprintf(extra, sizeof(extra), "%s %d",
2475 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002476 /* Returned value is in units of seconds */
2477 if (copy_to_user(priv_data.buf, &extra, len + 1))
2478 {
2479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2480 "%s: failed to copy data to user buffer", __func__);
2481 ret = -EFAULT;
2482 goto exit;
2483 }
2484 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002485#ifdef FEATURE_WLAN_LFR
2486 /* SETROAMMODE */
2487 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2488 {
2489 tANI_U8 *value = command;
2490 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2491
2492 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2493 value = value + SIZE_OF_SETROAMMODE + 1;
2494
2495 /* Convert the value from ascii to integer */
2496 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2497 if (ret < 0)
2498 {
2499 /* If the input value is greater than max value of datatype, then also
2500 kstrtou8 fails */
2501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2502 "%s: kstrtou8 failed range [%d - %d]", __func__,
2503 CFG_LFR_FEATURE_ENABLED_MIN,
2504 CFG_LFR_FEATURE_ENABLED_MAX);
2505 ret = -EINVAL;
2506 goto exit;
2507 }
2508 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2509 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2510 {
2511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2512 "Roam Mode value %d is out of range"
2513 " (Min: %d Max: %d)", roamMode,
2514 CFG_LFR_FEATURE_ENABLED_MIN,
2515 CFG_LFR_FEATURE_ENABLED_MAX);
2516 ret = -EINVAL;
2517 goto exit;
2518 }
2519
2520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2521 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2522 /*
2523 * Note that
2524 * SETROAMMODE 0 is to enable LFR while
2525 * SETROAMMODE 1 is to disable LFR, but
2526 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2527 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2528 */
2529 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2530 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2531 else
2532 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2533
2534 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2535 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2536 }
2537 /* GETROAMMODE */
2538 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2539 {
2540 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2541 char extra[32];
2542 tANI_U8 len = 0;
2543
2544 /*
2545 * roamMode value shall be inverted because the sementics is different.
2546 */
2547 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2548 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2549 else
2550 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2551
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002552 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002553 if (copy_to_user(priv_data.buf, &extra, len + 1))
2554 {
2555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2556 "%s: failed to copy data to user buffer", __func__);
2557 ret = -EFAULT;
2558 goto exit;
2559 }
2560 }
2561#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002562#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002563#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002564 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2565 {
2566 tANI_U8 *value = command;
2567 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2568
2569 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2570 value = value + 13;
2571 /* Convert the value from ascii to integer */
2572 ret = kstrtou8(value, 10, &roamRssiDiff);
2573 if (ret < 0)
2574 {
2575 /* If the input value is greater than max value of datatype, then also
2576 kstrtou8 fails */
2577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2578 "%s: kstrtou8 failed range [%d - %d]", __func__,
2579 CFG_ROAM_RSSI_DIFF_MIN,
2580 CFG_ROAM_RSSI_DIFF_MAX);
2581 ret = -EINVAL;
2582 goto exit;
2583 }
2584
2585 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2586 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2587 {
2588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2589 "Roam rssi diff value %d is out of range"
2590 " (Min: %d Max: %d)", roamRssiDiff,
2591 CFG_ROAM_RSSI_DIFF_MIN,
2592 CFG_ROAM_RSSI_DIFF_MAX);
2593 ret = -EINVAL;
2594 goto exit;
2595 }
2596
2597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2598 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2599
2600 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2601 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2602 }
2603 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2604 {
2605 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2606 char extra[32];
2607 tANI_U8 len = 0;
2608
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302609 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2610 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2611 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002612 len = scnprintf(extra, sizeof(extra), "%s %d",
2613 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002614 if (copy_to_user(priv_data.buf, &extra, len + 1))
2615 {
2616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2617 "%s: failed to copy data to user buffer", __func__);
2618 ret = -EFAULT;
2619 goto exit;
2620 }
2621 }
2622#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002623#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002624 else if (strncmp(command, "GETBAND", 7) == 0)
2625 {
2626 int band = -1;
2627 char extra[32];
2628 tANI_U8 len = 0;
2629 hdd_getBand_helper(pHddCtx, &band);
2630
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302631 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2632 TRACE_CODE_HDD_GETBAND_IOCTL,
2633 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002634 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002635 if (copy_to_user(priv_data.buf, &extra, len + 1))
2636 {
2637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2638 "%s: failed to copy data to user buffer", __func__);
2639 ret = -EFAULT;
2640 goto exit;
2641 }
2642 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002643 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2644 {
2645 tANI_U8 *value = command;
2646 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2647 tANI_U8 numChannels = 0;
2648 eHalStatus status = eHAL_STATUS_SUCCESS;
2649
2650 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2651 if (eHAL_STATUS_SUCCESS != status)
2652 {
2653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2654 "%s: Failed to parse channel list information", __func__);
2655 ret = -EINVAL;
2656 goto exit;
2657 }
2658
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302659 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2660 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2661 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002662 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2663 {
2664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2665 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2666 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2667 ret = -EINVAL;
2668 goto exit;
2669 }
2670 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2671 numChannels);
2672 if (eHAL_STATUS_SUCCESS != status)
2673 {
2674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2675 "%s: Failed to update channel list information", __func__);
2676 ret = -EINVAL;
2677 goto exit;
2678 }
2679 }
2680 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2681 {
2682 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2683 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002684 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002685 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002686 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002687
2688 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2689 ChannelList, &numChannels ))
2690 {
2691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2692 "%s: failed to get roam scan channel list", __func__);
2693 ret = -EFAULT;
2694 goto exit;
2695 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302696 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2697 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2698 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002699 /* output channel list is of the format
2700 [Number of roam scan channels][Channel1][Channel2]... */
2701 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002702 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002703 for (j = 0; (j < numChannels); j++)
2704 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002705 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2706 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002707 }
2708
2709 if (copy_to_user(priv_data.buf, &extra, len + 1))
2710 {
2711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2712 "%s: failed to copy data to user buffer", __func__);
2713 ret = -EFAULT;
2714 goto exit;
2715 }
2716 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002717 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2718 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002719 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002720 char extra[32];
2721 tANI_U8 len = 0;
2722
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002723 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002724 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002725 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002726 hdd_is_okc_mode_enabled(pHddCtx) &&
2727 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2728 {
2729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002730 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002731 " hence this operation is not permitted!", __func__);
2732 ret = -EPERM;
2733 goto exit;
2734 }
2735
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002736 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002737 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002738 if (copy_to_user(priv_data.buf, &extra, len + 1))
2739 {
2740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2741 "%s: failed to copy data to user buffer", __func__);
2742 ret = -EFAULT;
2743 goto exit;
2744 }
2745 }
2746 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2747 {
2748 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2749 char extra[32];
2750 tANI_U8 len = 0;
2751
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002752 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002753 then this operation is not permitted (return FAILURE) */
2754 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002755 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002756 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2757 {
2758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002759 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002760 " hence this operation is not permitted!", __func__);
2761 ret = -EPERM;
2762 goto exit;
2763 }
2764
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002765 len = scnprintf(extra, sizeof(extra), "%s %d",
2766 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002767 if (copy_to_user(priv_data.buf, &extra, len + 1))
2768 {
2769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2770 "%s: failed to copy data to user buffer", __func__);
2771 ret = -EFAULT;
2772 goto exit;
2773 }
2774 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002775 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002776 {
2777 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2778 char extra[32];
2779 tANI_U8 len = 0;
2780
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002781 len = scnprintf(extra, sizeof(extra), "%s %d",
2782 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002783 if (copy_to_user(priv_data.buf, &extra, len + 1))
2784 {
2785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2786 "%s: failed to copy data to user buffer", __func__);
2787 ret = -EFAULT;
2788 goto exit;
2789 }
2790 }
2791 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2792 {
2793 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2794 char extra[32];
2795 tANI_U8 len = 0;
2796
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002797 len = scnprintf(extra, sizeof(extra), "%s %d",
2798 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002799 if (copy_to_user(priv_data.buf, &extra, len + 1))
2800 {
2801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2802 "%s: failed to copy data to user buffer", __func__);
2803 ret = -EFAULT;
2804 goto exit;
2805 }
2806 }
2807 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2808 {
2809 tANI_U8 *value = command;
2810 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2811
2812 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2813 value = value + 26;
2814 /* Convert the value from ascii to integer */
2815 ret = kstrtou8(value, 10, &minTime);
2816 if (ret < 0)
2817 {
2818 /* If the input value is greater than max value of datatype, then also
2819 kstrtou8 fails */
2820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2821 "%s: kstrtou8 failed range [%d - %d]", __func__,
2822 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2823 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2824 ret = -EINVAL;
2825 goto exit;
2826 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002827 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2828 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2829 {
2830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2831 "scan min channel time value %d is out of range"
2832 " (Min: %d Max: %d)", minTime,
2833 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2834 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2835 ret = -EINVAL;
2836 goto exit;
2837 }
2838
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302839 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2840 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2841 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2843 "%s: Received Command to change channel min time = %d", __func__, minTime);
2844
2845 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2846 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2847 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002848 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2849 {
2850 tANI_U8 *value = command;
2851 tANI_U8 channel = 0;
2852 tANI_U8 dwellTime = 0;
2853 tANI_U8 bufLen = 0;
2854 tANI_U8 *buf = NULL;
2855 tSirMacAddr targetApBssid;
2856 eHalStatus status = eHAL_STATUS_SUCCESS;
2857 struct ieee80211_channel chan;
2858 tANI_U8 finalLen = 0;
2859 tANI_U8 *finalBuf = NULL;
2860 tANI_U8 temp = 0;
2861 u64 cookie;
2862 hdd_station_ctx_t *pHddStaCtx = NULL;
2863 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2864
2865 /* if not associated, no need to send action frame */
2866 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2867 {
2868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2869 ret = -EINVAL;
2870 goto exit;
2871 }
2872
2873 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2874 &dwellTime, &buf, &bufLen);
2875 if (eHAL_STATUS_SUCCESS != status)
2876 {
2877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2878 "%s: Failed to parse send action frame data", __func__);
2879 ret = -EINVAL;
2880 goto exit;
2881 }
2882
2883 /* if the target bssid is different from currently associated AP,
2884 then no need to send action frame */
2885 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2886 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2887 {
2888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2889 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002890 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002891 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002892 goto exit;
2893 }
2894
2895 /* if the channel number is different from operating channel then
2896 no need to send action frame */
2897 if (channel != pHddStaCtx->conn_info.operationChannel)
2898 {
2899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2900 "%s: channel(%d) is different from operating channel(%d)",
2901 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2902 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002903 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002904 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002905 goto exit;
2906 }
2907 chan.center_freq = sme_ChnToFreq(channel);
2908
2909 finalLen = bufLen + 24;
2910 finalBuf = vos_mem_malloc(finalLen);
2911 if (NULL == finalBuf)
2912 {
2913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2914 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002915 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002916 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002917 goto exit;
2918 }
2919 vos_mem_zero(finalBuf, finalLen);
2920
2921 /* Fill subtype */
2922 temp = SIR_MAC_MGMT_ACTION << 4;
2923 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2924
2925 /* Fill type */
2926 temp = SIR_MAC_MGMT_FRAME;
2927 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2928
2929 /* Fill destination address (bssid of the AP) */
2930 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2931
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002932 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002933 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2934
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002935 /* Fill BSSID (AP mac address) */
2936 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002937
2938 /* Fill received buffer from 24th address */
2939 vos_mem_copy(finalBuf + 24, buf, bufLen);
2940
Jeff Johnson11c33152013-04-16 17:52:40 -07002941 /* done with the parsed buffer */
2942 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002943 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002944
DARAM SUDHA39eede62014-02-12 11:16:40 +05302945 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002946#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2947 &(pAdapter->wdev),
2948#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002949 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002950#endif
2951 &chan, 0,
2952#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2953 NL80211_CHAN_HT20, 1,
2954#endif
2955 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002956 1, &cookie );
2957 vos_mem_free(finalBuf);
2958 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002959 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2960 {
2961 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2962 char extra[32];
2963 tANI_U8 len = 0;
2964
2965 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002966 len = scnprintf(extra, sizeof(extra), "%s %d",
2967 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302968 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2969 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2970 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002971 if (copy_to_user(priv_data.buf, &extra, len + 1))
2972 {
2973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2974 "%s: failed to copy data to user buffer", __func__);
2975 ret = -EFAULT;
2976 goto exit;
2977 }
2978 }
2979 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2980 {
2981 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002982 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002983
2984 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2985 value = value + 19;
2986 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002987 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002988 if (ret < 0)
2989 {
2990 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002991 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002993 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002994 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2995 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2996 ret = -EINVAL;
2997 goto exit;
2998 }
2999
3000 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3001 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3002 {
3003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3004 "lfr mode value %d is out of range"
3005 " (Min: %d Max: %d)", maxTime,
3006 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3007 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3008 ret = -EINVAL;
3009 goto exit;
3010 }
3011
3012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3013 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3014
3015 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3016 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3017 }
3018 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3019 {
3020 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3021 char extra[32];
3022 tANI_U8 len = 0;
3023
3024 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003025 len = scnprintf(extra, sizeof(extra), "%s %d",
3026 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003027 if (copy_to_user(priv_data.buf, &extra, len + 1))
3028 {
3029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3030 "%s: failed to copy data to user buffer", __func__);
3031 ret = -EFAULT;
3032 goto exit;
3033 }
3034 }
3035 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3036 {
3037 tANI_U8 *value = command;
3038 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3039
3040 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3041 value = value + 16;
3042 /* Convert the value from ascii to integer */
3043 ret = kstrtou16(value, 10, &val);
3044 if (ret < 0)
3045 {
3046 /* If the input value is greater than max value of datatype, then also
3047 kstrtou16 fails */
3048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3049 "%s: kstrtou16 failed range [%d - %d]", __func__,
3050 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3051 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3052 ret = -EINVAL;
3053 goto exit;
3054 }
3055
3056 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3057 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3058 {
3059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3060 "scan home time value %d is out of range"
3061 " (Min: %d Max: %d)", val,
3062 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3063 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3064 ret = -EINVAL;
3065 goto exit;
3066 }
3067
3068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3069 "%s: Received Command to change scan home time = %d", __func__, val);
3070
3071 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3072 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3073 }
3074 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3075 {
3076 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3077 char extra[32];
3078 tANI_U8 len = 0;
3079
3080 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003081 len = scnprintf(extra, sizeof(extra), "%s %d",
3082 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003083 if (copy_to_user(priv_data.buf, &extra, len + 1))
3084 {
3085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3086 "%s: failed to copy data to user buffer", __func__);
3087 ret = -EFAULT;
3088 goto exit;
3089 }
3090 }
3091 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3092 {
3093 tANI_U8 *value = command;
3094 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3095
3096 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3097 value = value + 17;
3098 /* Convert the value from ascii to integer */
3099 ret = kstrtou8(value, 10, &val);
3100 if (ret < 0)
3101 {
3102 /* If the input value is greater than max value of datatype, then also
3103 kstrtou8 fails */
3104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3105 "%s: kstrtou8 failed range [%d - %d]", __func__,
3106 CFG_ROAM_INTRA_BAND_MIN,
3107 CFG_ROAM_INTRA_BAND_MAX);
3108 ret = -EINVAL;
3109 goto exit;
3110 }
3111
3112 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3113 (val > CFG_ROAM_INTRA_BAND_MAX))
3114 {
3115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3116 "intra band mode value %d is out of range"
3117 " (Min: %d Max: %d)", val,
3118 CFG_ROAM_INTRA_BAND_MIN,
3119 CFG_ROAM_INTRA_BAND_MAX);
3120 ret = -EINVAL;
3121 goto exit;
3122 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3124 "%s: Received Command to change intra band = %d", __func__, val);
3125
3126 pHddCtx->cfg_ini->nRoamIntraBand = val;
3127 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3128 }
3129 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3130 {
3131 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3132 char extra[32];
3133 tANI_U8 len = 0;
3134
3135 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003136 len = scnprintf(extra, sizeof(extra), "%s %d",
3137 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003138 if (copy_to_user(priv_data.buf, &extra, len + 1))
3139 {
3140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3141 "%s: failed to copy data to user buffer", __func__);
3142 ret = -EFAULT;
3143 goto exit;
3144 }
3145 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003146 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3147 {
3148 tANI_U8 *value = command;
3149 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3150
3151 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3152 value = value + 15;
3153 /* Convert the value from ascii to integer */
3154 ret = kstrtou8(value, 10, &nProbes);
3155 if (ret < 0)
3156 {
3157 /* If the input value is greater than max value of datatype, then also
3158 kstrtou8 fails */
3159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3160 "%s: kstrtou8 failed range [%d - %d]", __func__,
3161 CFG_ROAM_SCAN_N_PROBES_MIN,
3162 CFG_ROAM_SCAN_N_PROBES_MAX);
3163 ret = -EINVAL;
3164 goto exit;
3165 }
3166
3167 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3168 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3169 {
3170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3171 "NProbes value %d is out of range"
3172 " (Min: %d Max: %d)", nProbes,
3173 CFG_ROAM_SCAN_N_PROBES_MIN,
3174 CFG_ROAM_SCAN_N_PROBES_MAX);
3175 ret = -EINVAL;
3176 goto exit;
3177 }
3178
3179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3180 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3181
3182 pHddCtx->cfg_ini->nProbes = nProbes;
3183 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3184 }
3185 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3186 {
3187 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3188 char extra[32];
3189 tANI_U8 len = 0;
3190
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003191 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003192 if (copy_to_user(priv_data.buf, &extra, len + 1))
3193 {
3194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3195 "%s: failed to copy data to user buffer", __func__);
3196 ret = -EFAULT;
3197 goto exit;
3198 }
3199 }
3200 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3201 {
3202 tANI_U8 *value = command;
3203 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3204
3205 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3206 /* input value is in units of msec */
3207 value = value + 20;
3208 /* Convert the value from ascii to integer */
3209 ret = kstrtou16(value, 10, &homeAwayTime);
3210 if (ret < 0)
3211 {
3212 /* If the input value is greater than max value of datatype, then also
3213 kstrtou8 fails */
3214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3215 "%s: kstrtou8 failed range [%d - %d]", __func__,
3216 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3217 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3218 ret = -EINVAL;
3219 goto exit;
3220 }
3221
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003222 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3223 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3224 {
3225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3226 "homeAwayTime value %d is out of range"
3227 " (Min: %d Max: %d)", homeAwayTime,
3228 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3229 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3230 ret = -EINVAL;
3231 goto exit;
3232 }
3233
3234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3235 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003236 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3237 {
3238 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3239 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3240 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003241 }
3242 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3243 {
3244 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3245 char extra[32];
3246 tANI_U8 len = 0;
3247
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003248 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003249 if (copy_to_user(priv_data.buf, &extra, len + 1))
3250 {
3251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3252 "%s: failed to copy data to user buffer", __func__);
3253 ret = -EFAULT;
3254 goto exit;
3255 }
3256 }
3257 else if (strncmp(command, "REASSOC", 7) == 0)
3258 {
3259 tANI_U8 *value = command;
3260 tANI_U8 channel = 0;
3261 tSirMacAddr targetApBssid;
3262 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003263#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3264 tCsrHandoffRequest handoffInfo;
3265#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003266 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003267 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3268
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003269 /* if not associated, no need to proceed with reassoc */
3270 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3271 {
3272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3273 ret = -EINVAL;
3274 goto exit;
3275 }
3276
3277 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3278 if (eHAL_STATUS_SUCCESS != status)
3279 {
3280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3281 "%s: Failed to parse reassoc command data", __func__);
3282 ret = -EINVAL;
3283 goto exit;
3284 }
3285
3286 /* if the target bssid is same as currently associated AP,
3287 then no need to proceed with reassoc */
3288 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3289 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3290 {
3291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3292 ret = -EINVAL;
3293 goto exit;
3294 }
3295
3296 /* Check channel number is a valid channel number */
3297 if(VOS_STATUS_SUCCESS !=
3298 wlan_hdd_validate_operation_channel(pAdapter, channel))
3299 {
3300 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003301 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003302 return -EINVAL;
3303 }
3304
3305 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003306#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3307 handoffInfo.channel = channel;
3308 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3309 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3310#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003311 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003312 else if (strncmp(command, "SETWESMODE", 10) == 0)
3313 {
3314 tANI_U8 *value = command;
3315 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3316
3317 /* Move pointer to ahead of SETWESMODE<delimiter> */
3318 value = value + 11;
3319 /* Convert the value from ascii to integer */
3320 ret = kstrtou8(value, 10, &wesMode);
3321 if (ret < 0)
3322 {
3323 /* If the input value is greater than max value of datatype, then also
3324 kstrtou8 fails */
3325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3326 "%s: kstrtou8 failed range [%d - %d]", __func__,
3327 CFG_ENABLE_WES_MODE_NAME_MIN,
3328 CFG_ENABLE_WES_MODE_NAME_MAX);
3329 ret = -EINVAL;
3330 goto exit;
3331 }
3332
3333 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3334 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3335 {
3336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3337 "WES Mode value %d is out of range"
3338 " (Min: %d Max: %d)", wesMode,
3339 CFG_ENABLE_WES_MODE_NAME_MIN,
3340 CFG_ENABLE_WES_MODE_NAME_MAX);
3341 ret = -EINVAL;
3342 goto exit;
3343 }
3344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3345 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3346
3347 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3348 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3349 }
3350 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3351 {
3352 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3353 char extra[32];
3354 tANI_U8 len = 0;
3355
Arif Hussain826d9412013-11-12 16:44:54 -08003356 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003357 if (copy_to_user(priv_data.buf, &extra, len + 1))
3358 {
3359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3360 "%s: failed to copy data to user buffer", __func__);
3361 ret = -EFAULT;
3362 goto exit;
3363 }
3364 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003365#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003366#ifdef FEATURE_WLAN_LFR
3367 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3368 {
3369 tANI_U8 *value = command;
3370 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3371
3372 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3373 value = value + 12;
3374 /* Convert the value from ascii to integer */
3375 ret = kstrtou8(value, 10, &lfrMode);
3376 if (ret < 0)
3377 {
3378 /* If the input value is greater than max value of datatype, then also
3379 kstrtou8 fails */
3380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3381 "%s: kstrtou8 failed range [%d - %d]", __func__,
3382 CFG_LFR_FEATURE_ENABLED_MIN,
3383 CFG_LFR_FEATURE_ENABLED_MAX);
3384 ret = -EINVAL;
3385 goto exit;
3386 }
3387
3388 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3389 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3390 {
3391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3392 "lfr mode value %d is out of range"
3393 " (Min: %d Max: %d)", lfrMode,
3394 CFG_LFR_FEATURE_ENABLED_MIN,
3395 CFG_LFR_FEATURE_ENABLED_MAX);
3396 ret = -EINVAL;
3397 goto exit;
3398 }
3399
3400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3401 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3402
3403 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3404 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3405 }
3406#endif
3407#ifdef WLAN_FEATURE_VOWIFI_11R
3408 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3409 {
3410 tANI_U8 *value = command;
3411 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3412
3413 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3414 value = value + 18;
3415 /* Convert the value from ascii to integer */
3416 ret = kstrtou8(value, 10, &ft);
3417 if (ret < 0)
3418 {
3419 /* If the input value is greater than max value of datatype, then also
3420 kstrtou8 fails */
3421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3422 "%s: kstrtou8 failed range [%d - %d]", __func__,
3423 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3424 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3425 ret = -EINVAL;
3426 goto exit;
3427 }
3428
3429 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3430 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3431 {
3432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3433 "ft mode value %d is out of range"
3434 " (Min: %d Max: %d)", ft,
3435 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3436 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3437 ret = -EINVAL;
3438 goto exit;
3439 }
3440
3441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3442 "%s: Received Command to change ft mode = %d", __func__, ft);
3443
3444 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3445 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3446 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303447
3448 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3449 {
3450 tANI_U8 *value = command;
3451 tSirMacAddr targetApBssid;
3452 tANI_U8 trigger = 0;
3453 eHalStatus status = eHAL_STATUS_SUCCESS;
3454 hdd_station_ctx_t *pHddStaCtx = NULL;
3455 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3456
3457 /* if not associated, no need to proceed with reassoc */
3458 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3459 {
3460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3461 ret = -EINVAL;
3462 goto exit;
3463 }
3464
3465 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3466 if (eHAL_STATUS_SUCCESS != status)
3467 {
3468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3469 "%s: Failed to parse reassoc command data", __func__);
3470 ret = -EINVAL;
3471 goto exit;
3472 }
3473
3474 /* if the target bssid is same as currently associated AP,
3475 then no need to proceed with reassoc */
3476 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3477 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3478 {
3479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3480 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3481 __func__);
3482 ret = -EINVAL;
3483 goto exit;
3484 }
3485
3486 /* Proceed with scan/roam */
3487 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3488 &targetApBssid[0],
3489 (tSmeFastRoamTrigger)(trigger));
3490 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003491#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003492#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003493 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3494 {
3495 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003496 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003497
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003498 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003499 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003500 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003501 hdd_is_okc_mode_enabled(pHddCtx) &&
3502 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3503 {
3504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003505 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003506 " hence this operation is not permitted!", __func__);
3507 ret = -EPERM;
3508 goto exit;
3509 }
3510
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003511 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3512 value = value + 11;
3513 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003514 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003515 if (ret < 0)
3516 {
3517 /* If the input value is greater than max value of datatype, then also
3518 kstrtou8 fails */
3519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3520 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003521 CFG_ESE_FEATURE_ENABLED_MIN,
3522 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003523 ret = -EINVAL;
3524 goto exit;
3525 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003526 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3527 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003528 {
3529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003530 "Ese mode value %d is out of range"
3531 " (Min: %d Max: %d)", eseMode,
3532 CFG_ESE_FEATURE_ENABLED_MIN,
3533 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003534 ret = -EINVAL;
3535 goto exit;
3536 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003538 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003539
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003540 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3541 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003542 }
3543#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003544 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3545 {
3546 tANI_U8 *value = command;
3547 tANI_BOOLEAN roamScanControl = 0;
3548
3549 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3550 value = value + 19;
3551 /* Convert the value from ascii to integer */
3552 ret = kstrtou8(value, 10, &roamScanControl);
3553 if (ret < 0)
3554 {
3555 /* If the input value is greater than max value of datatype, then also
3556 kstrtou8 fails */
3557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3558 "%s: kstrtou8 failed ", __func__);
3559 ret = -EINVAL;
3560 goto exit;
3561 }
3562
3563 if (0 != roamScanControl)
3564 {
3565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3566 "roam scan control invalid value = %d",
3567 roamScanControl);
3568 ret = -EINVAL;
3569 goto exit;
3570 }
3571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3572 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3573
3574 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3575 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003576#ifdef FEATURE_WLAN_OKC
3577 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3578 {
3579 tANI_U8 *value = command;
3580 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3581
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003582 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003583 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003584 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003585 hdd_is_okc_mode_enabled(pHddCtx) &&
3586 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3587 {
3588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003589 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003590 " hence this operation is not permitted!", __func__);
3591 ret = -EPERM;
3592 goto exit;
3593 }
3594
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003595 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3596 value = value + 11;
3597 /* Convert the value from ascii to integer */
3598 ret = kstrtou8(value, 10, &okcMode);
3599 if (ret < 0)
3600 {
3601 /* If the input value is greater than max value of datatype, then also
3602 kstrtou8 fails */
3603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3604 "%s: kstrtou8 failed range [%d - %d]", __func__,
3605 CFG_OKC_FEATURE_ENABLED_MIN,
3606 CFG_OKC_FEATURE_ENABLED_MAX);
3607 ret = -EINVAL;
3608 goto exit;
3609 }
3610
3611 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3612 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3613 {
3614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3615 "Okc mode value %d is out of range"
3616 " (Min: %d Max: %d)", okcMode,
3617 CFG_OKC_FEATURE_ENABLED_MIN,
3618 CFG_OKC_FEATURE_ENABLED_MAX);
3619 ret = -EINVAL;
3620 goto exit;
3621 }
3622
3623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3624 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3625
3626 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3627 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003628#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003629 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3630 {
3631 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3632 char extra[32];
3633 tANI_U8 len = 0;
3634
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003635 len = scnprintf(extra, sizeof(extra), "%s %d",
3636 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003637 if (copy_to_user(priv_data.buf, &extra, len + 1))
3638 {
3639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3640 "%s: failed to copy data to user buffer", __func__);
3641 ret = -EFAULT;
3642 goto exit;
3643 }
3644 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303645#ifdef WLAN_FEATURE_PACKET_FILTERING
3646 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3647 {
3648 tANI_U8 filterType = 0;
3649 tANI_U8 *value = command;
3650
3651 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3652 value = value + 22;
3653
3654 /* Convert the value from ascii to integer */
3655 ret = kstrtou8(value, 10, &filterType);
3656 if (ret < 0)
3657 {
3658 /* If the input value is greater than max value of datatype,
3659 * then also kstrtou8 fails
3660 */
3661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3662 "%s: kstrtou8 failed range ", __func__);
3663 ret = -EINVAL;
3664 goto exit;
3665 }
3666
3667 if (filterType != 0 && filterType != 1)
3668 {
3669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3670 "%s: Accepted Values are 0 and 1 ", __func__);
3671 ret = -EINVAL;
3672 goto exit;
3673 }
3674 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3675 pAdapter->sessionId);
3676 }
3677#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303678 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3679 {
Kiet Lamad161252014-07-22 11:23:32 -07003680 char *dhcpPhase;
3681 dhcpPhase = command + 11;
3682 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303683 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lamad161252014-07-22 11:23:32 -07003685 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303686
3687 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003688
3689 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3690 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303691 }
Kiet Lamad161252014-07-22 11:23:32 -07003692 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303693 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lamad161252014-07-22 11:23:32 -07003695 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303696
3697 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003698
3699 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3700 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303701 }
3702 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003703 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3704 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3706 FL("making default scan to ACTIVE"));
3707 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003708 }
3709 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3710 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3712 FL("making default scan to PASSIVE"));
3713 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003714 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303715 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3716 {
3717 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3718 char extra[32];
3719 tANI_U8 len = 0;
3720
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303721 memset(extra, 0, sizeof(extra));
3722 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3723 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303724 {
3725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3726 "%s: failed to copy data to user buffer", __func__);
3727 ret = -EFAULT;
3728 goto exit;
3729 }
3730 ret = len;
3731 }
3732 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3733 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303734 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303735 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003736 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3737 {
3738 tANI_U8 filterType = 0;
3739 tANI_U8 *value;
3740 value = command + 9;
3741
3742 /* Convert the value from ascii to integer */
3743 ret = kstrtou8(value, 10, &filterType);
3744 if (ret < 0)
3745 {
3746 /* If the input value is greater than max value of datatype,
3747 * then also kstrtou8 fails
3748 */
3749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3750 "%s: kstrtou8 failed range ", __func__);
3751 ret = -EINVAL;
3752 goto exit;
3753 }
3754 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3755 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3756 {
3757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3758 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3759 " 2-Sink ", __func__);
3760 ret = -EINVAL;
3761 goto exit;
3762 }
3763 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3764 pHddCtx->drvr_miracast = filterType;
3765 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3766 }
Leo Chang614d2072013-08-22 14:59:44 -07003767 else if (strncmp(command, "SETMCRATE", 9) == 0)
3768 {
Leo Chang614d2072013-08-22 14:59:44 -07003769 tANI_U8 *value = command;
3770 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003771 tSirRateUpdateInd *rateUpdate;
3772 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003773
3774 /* Only valid for SAP mode */
3775 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3776 {
3777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3778 "%s: SAP mode is not running", __func__);
3779 ret = -EFAULT;
3780 goto exit;
3781 }
3782
3783 /* Move pointer to ahead of SETMCRATE<delimiter> */
3784 /* input value is in units of hundred kbps */
3785 value = value + 10;
3786 /* Convert the value from ascii to integer, decimal base */
3787 ret = kstrtouint(value, 10, &targetRate);
3788
Leo Chang1f98cbd2013-10-17 15:03:52 -07003789 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3790 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003791 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003792 hddLog(VOS_TRACE_LEVEL_ERROR,
3793 "%s: SETMCRATE indication alloc fail", __func__);
3794 ret = -EFAULT;
3795 goto exit;
3796 }
3797 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3798
3799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3800 "MC Target rate %d", targetRate);
3801 /* Ignore unicast */
3802 rateUpdate->ucastDataRate = -1;
3803 rateUpdate->mcastDataRate24GHz = targetRate;
3804 rateUpdate->mcastDataRate5GHz = targetRate;
3805 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3806 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3807 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3808 if (eHAL_STATUS_SUCCESS != status)
3809 {
3810 hddLog(VOS_TRACE_LEVEL_ERROR,
3811 "%s: SET_MC_RATE failed", __func__);
3812 vos_mem_free(rateUpdate);
3813 ret = -EFAULT;
3814 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003815 }
3816 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303817#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003818 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303819 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003820 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303821 }
3822#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003823#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003824 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3825 {
3826 tANI_U8 *value = command;
3827 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3828 tANI_U8 numChannels = 0;
3829 eHalStatus status = eHAL_STATUS_SUCCESS;
3830
3831 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3832 if (eHAL_STATUS_SUCCESS != status)
3833 {
3834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3835 "%s: Failed to parse channel list information", __func__);
3836 ret = -EINVAL;
3837 goto exit;
3838 }
3839
3840 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3841 {
3842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3843 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3844 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3845 ret = -EINVAL;
3846 goto exit;
3847 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003848 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003849 ChannelList,
3850 numChannels);
3851 if (eHAL_STATUS_SUCCESS != status)
3852 {
3853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3854 "%s: Failed to update channel list information", __func__);
3855 ret = -EINVAL;
3856 goto exit;
3857 }
3858 }
3859 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3860 {
3861 tANI_U8 *value = command;
3862 char extra[128] = {0};
3863 int len = 0;
3864 tANI_U8 tid = 0;
3865 hdd_station_ctx_t *pHddStaCtx = NULL;
3866 tAniTrafStrmMetrics tsmMetrics;
3867 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3868
3869 /* if not associated, return error */
3870 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3871 {
3872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3873 ret = -EINVAL;
3874 goto exit;
3875 }
3876
3877 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3878 value = value + 12;
3879 /* Convert the value from ascii to integer */
3880 ret = kstrtou8(value, 10, &tid);
3881 if (ret < 0)
3882 {
3883 /* If the input value is greater than max value of datatype, then also
3884 kstrtou8 fails */
3885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3886 "%s: kstrtou8 failed range [%d - %d]", __func__,
3887 TID_MIN_VALUE,
3888 TID_MAX_VALUE);
3889 ret = -EINVAL;
3890 goto exit;
3891 }
3892
3893 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3894 {
3895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3896 "tid value %d is out of range"
3897 " (Min: %d Max: %d)", tid,
3898 TID_MIN_VALUE,
3899 TID_MAX_VALUE);
3900 ret = -EINVAL;
3901 goto exit;
3902 }
3903
3904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3905 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3906
3907 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3908 {
3909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3910 "%s: failed to get tsm stats", __func__);
3911 ret = -EFAULT;
3912 goto exit;
3913 }
3914
3915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3916 "UplinkPktQueueDly(%d)\n"
3917 "UplinkPktQueueDlyHist[0](%d)\n"
3918 "UplinkPktQueueDlyHist[1](%d)\n"
3919 "UplinkPktQueueDlyHist[2](%d)\n"
3920 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303921 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003922 "UplinkPktLoss(%d)\n"
3923 "UplinkPktCount(%d)\n"
3924 "RoamingCount(%d)\n"
3925 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3926 tsmMetrics.UplinkPktQueueDlyHist[0],
3927 tsmMetrics.UplinkPktQueueDlyHist[1],
3928 tsmMetrics.UplinkPktQueueDlyHist[2],
3929 tsmMetrics.UplinkPktQueueDlyHist[3],
3930 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3931 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3932
3933 /* Output TSM stats is of the format
3934 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3935 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003936 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003937 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3938 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3939 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3940 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3941 tsmMetrics.RoamingDly);
3942
3943 if (copy_to_user(priv_data.buf, &extra, len + 1))
3944 {
3945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3946 "%s: failed to copy data to user buffer", __func__);
3947 ret = -EFAULT;
3948 goto exit;
3949 }
3950 }
3951 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3952 {
3953 tANI_U8 *value = command;
3954 tANI_U8 *cckmIe = NULL;
3955 tANI_U8 cckmIeLen = 0;
3956 eHalStatus status = eHAL_STATUS_SUCCESS;
3957
3958 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3959 if (eHAL_STATUS_SUCCESS != status)
3960 {
3961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3962 "%s: Failed to parse cckm ie data", __func__);
3963 ret = -EINVAL;
3964 goto exit;
3965 }
3966
3967 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3968 {
3969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3970 "%s: CCKM Ie input length is more than max[%d]", __func__,
3971 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003972 vos_mem_free(cckmIe);
3973 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003974 ret = -EINVAL;
3975 goto exit;
3976 }
3977 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003978 vos_mem_free(cckmIe);
3979 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003980 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003981 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3982 {
3983 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003984 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003985 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003986
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003987 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003988 if (eHAL_STATUS_SUCCESS != status)
3989 {
3990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003991 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003992 ret = -EINVAL;
3993 goto exit;
3994 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07003995 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
3996 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
3997 hdd_indicateEseBcnReportNoResults (pAdapter,
3998 eseBcnReq.bcnReq[0].measurementToken,
3999 0x02, //BIT(1) set for measurement done
4000 0); // no BSS
4001 goto exit;
4002 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004003
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004004 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4005 if (eHAL_STATUS_SUCCESS != status)
4006 {
4007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4008 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4009 ret = -EINVAL;
4010 goto exit;
4011 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004012 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004013#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304014 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4015 {
4016 eHalStatus status;
4017 char buf[32], len;
4018 long waitRet;
4019 bcnMissRateContext_t getBcnMissRateCtx;
4020
4021 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4022
4023 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4024 {
4025 hddLog(VOS_TRACE_LEVEL_WARN,
4026 FL("GETBCNMISSRATE: STA is not in connected state"));
4027 ret = -1;
4028 goto exit;
4029 }
4030
4031 init_completion(&(getBcnMissRateCtx.completion));
4032 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4033
4034 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4035 pAdapter->sessionId,
4036 (void *)getBcnMissRateCB,
4037 (void *)(&getBcnMissRateCtx));
4038 if( eHAL_STATUS_SUCCESS != status)
4039 {
4040 hddLog(VOS_TRACE_LEVEL_INFO,
4041 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4042 ret = -EINVAL;
4043 goto exit;
4044 }
4045
4046 waitRet = wait_for_completion_interruptible_timeout
4047 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4048 if(waitRet <= 0)
4049 {
4050 hddLog(VOS_TRACE_LEVEL_ERROR,
4051 FL("failed to wait on bcnMissRateComp %d"), ret);
4052
4053 //Make magic number to zero so that callback is not called.
4054 spin_lock(&hdd_context_lock);
4055 getBcnMissRateCtx.magic = 0x0;
4056 spin_unlock(&hdd_context_lock);
4057 ret = -EINVAL;
4058 goto exit;
4059 }
4060
4061 hddLog(VOS_TRACE_LEVEL_INFO,
4062 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4063
4064 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4065 if (copy_to_user(priv_data.buf, &buf, len + 1))
4066 {
4067 hddLog(VOS_TRACE_LEVEL_ERROR,
4068 "%s: failed to copy data to user buffer", __func__);
4069 ret = -EFAULT;
4070 goto exit;
4071 }
4072 ret = len;
4073 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004074 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304075 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4076 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4077 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004078 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
4079 __func__, command);
4080 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004081 }
4082exit:
4083 if (command)
4084 {
4085 kfree(command);
4086 }
4087 return ret;
4088}
4089
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004090#ifdef CONFIG_COMPAT
4091static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4092{
4093 struct {
4094 compat_uptr_t buf;
4095 int used_len;
4096 int total_len;
4097 } compat_priv_data;
4098 hdd_priv_data_t priv_data;
4099 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004100
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004101 /*
4102 * Note that pAdapter and ifr have already been verified by caller,
4103 * and HDD context has also been validated
4104 */
4105 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4106 sizeof(compat_priv_data))) {
4107 ret = -EFAULT;
4108 goto exit;
4109 }
4110 priv_data.buf = compat_ptr(compat_priv_data.buf);
4111 priv_data.used_len = compat_priv_data.used_len;
4112 priv_data.total_len = compat_priv_data.total_len;
4113 ret = hdd_driver_command(pAdapter, &priv_data);
4114 exit:
4115 return ret;
4116}
4117#else /* CONFIG_COMPAT */
4118static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4119{
4120 /* will never be invoked */
4121 return 0;
4122}
4123#endif /* CONFIG_COMPAT */
4124
4125static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4126{
4127 hdd_priv_data_t priv_data;
4128 int ret = 0;
4129
4130 /*
4131 * Note that pAdapter and ifr have already been verified by caller,
4132 * and HDD context has also been validated
4133 */
4134 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4135 ret = -EFAULT;
4136 } else {
4137 ret = hdd_driver_command(pAdapter, &priv_data);
4138 }
4139 return ret;
4140}
4141
4142int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4143{
4144 hdd_adapter_t *pAdapter;
4145 hdd_context_t *pHddCtx;
4146 int ret;
4147
4148 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4149 if (NULL == pAdapter) {
4150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4151 "%s: HDD adapter context is Null", __func__);
4152 ret = -ENODEV;
4153 goto exit;
4154 }
4155 if (dev != pAdapter->dev) {
4156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4157 "%s: HDD adapter/dev inconsistency", __func__);
4158 ret = -ENODEV;
4159 goto exit;
4160 }
4161
4162 if ((!ifr) || (!ifr->ifr_data)) {
4163 ret = -EINVAL;
4164 goto exit;
4165 }
4166
4167 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4168 ret = wlan_hdd_validate_context(pHddCtx);
4169 if (ret) {
4170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4171 "%s: invalid context", __func__);
4172 ret = -EBUSY;
4173 goto exit;
4174 }
4175
4176 switch (cmd) {
4177 case (SIOCDEVPRIVATE + 1):
4178 if (is_compat_task())
4179 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4180 else
4181 ret = hdd_driver_ioctl(pAdapter, ifr);
4182 break;
4183 default:
4184 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4185 __func__, cmd);
4186 ret = -EINVAL;
4187 break;
4188 }
4189 exit:
4190 return ret;
4191}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004192
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004193#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004194/**---------------------------------------------------------------------------
4195
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004196 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004197
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004198 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004199 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4200 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4201 <space>Scan Mode N<space>Meas Duration N
4202 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4203 then take N.
4204 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4205 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4206 This function does not take care of removing duplicate channels from the list
4207
4208 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004209 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004210
4211 \return - 0 for success non-zero for failure
4212
4213 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004214static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4215 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004216{
4217 tANI_U8 *inPtr = pValue;
4218 int tempInt = 0;
4219 int j = 0, i = 0, v = 0;
4220 char buf[32];
4221
4222 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4223 /*no argument after the command*/
4224 if (NULL == inPtr)
4225 {
4226 return -EINVAL;
4227 }
4228 /*no space after the command*/
4229 else if (SPACE_ASCII_VALUE != *inPtr)
4230 {
4231 return -EINVAL;
4232 }
4233
4234 /*removing empty spaces*/
4235 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4236
4237 /*no argument followed by spaces*/
4238 if ('\0' == *inPtr) return -EINVAL;
4239
4240 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004241 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004242 if (1 != v) return -EINVAL;
4243
4244 v = kstrtos32(buf, 10, &tempInt);
4245 if ( v < 0) return -EINVAL;
4246
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004247 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004248
4249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004250 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004251
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004252 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004253 {
4254 for (i = 0; i < 4; i++)
4255 {
4256 /*inPtr pointing to the beginning of first space after number of ie fields*/
4257 inPtr = strpbrk( inPtr, " " );
4258 /*no ie data after the number of ie fields argument*/
4259 if (NULL == inPtr) return -EINVAL;
4260
4261 /*removing empty space*/
4262 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4263
4264 /*no ie data after the number of ie fields argument and spaces*/
4265 if ( '\0' == *inPtr ) return -EINVAL;
4266
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004267 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004268 if (1 != v) return -EINVAL;
4269
4270 v = kstrtos32(buf, 10, &tempInt);
4271 if (v < 0) return -EINVAL;
4272
4273 switch (i)
4274 {
4275 case 0: /* Measurement token */
4276 if (tempInt <= 0)
4277 {
4278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4279 "Invalid Measurement Token(%d)", tempInt);
4280 return -EINVAL;
4281 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004282 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004283 break;
4284
4285 case 1: /* Channel number */
4286 if ((tempInt <= 0) ||
4287 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4288 {
4289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4290 "Invalid Channel Number(%d)", tempInt);
4291 return -EINVAL;
4292 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004293 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004294 break;
4295
4296 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004297 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004298 {
4299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4300 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4301 return -EINVAL;
4302 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004303 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004304 break;
4305
4306 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004307 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4308 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004309 {
4310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4311 "Invalid Measurement Duration(%d)", tempInt);
4312 return -EINVAL;
4313 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004314 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004315 break;
4316 }
4317 }
4318 }
4319
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004320 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004321 {
4322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304323 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004324 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004325 pEseBcnReq->bcnReq[j].measurementToken,
4326 pEseBcnReq->bcnReq[j].channel,
4327 pEseBcnReq->bcnReq[j].scanMode,
4328 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004329 }
4330
4331 return VOS_STATUS_SUCCESS;
4332}
4333
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004334static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4335{
4336 struct statsContext *pStatsContext = NULL;
4337 hdd_adapter_t *pAdapter = NULL;
4338
4339 if (NULL == pContext)
4340 {
4341 hddLog(VOS_TRACE_LEVEL_ERROR,
4342 "%s: Bad param, pContext [%p]",
4343 __func__, pContext);
4344 return;
4345 }
4346
Jeff Johnson72a40512013-12-19 10:14:15 -08004347 /* there is a race condition that exists between this callback
4348 function and the caller since the caller could time out either
4349 before or while this code is executing. we use a spinlock to
4350 serialize these actions */
4351 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004352
4353 pStatsContext = pContext;
4354 pAdapter = pStatsContext->pAdapter;
4355 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4356 {
4357 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004358 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004359 hddLog(VOS_TRACE_LEVEL_WARN,
4360 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4361 __func__, pAdapter, pStatsContext->magic);
4362 return;
4363 }
4364
Jeff Johnson72a40512013-12-19 10:14:15 -08004365 /* context is valid so caller is still waiting */
4366
4367 /* paranoia: invalidate the magic */
4368 pStatsContext->magic = 0;
4369
4370 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004371 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4372 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4373 tsmMetrics.UplinkPktQueueDlyHist,
4374 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4375 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4376 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4377 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4378 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4379 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4380 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4381
Jeff Johnson72a40512013-12-19 10:14:15 -08004382 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004383 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004384
4385 /* serialization is complete */
4386 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004387}
4388
4389
4390
4391static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4392 tAniTrafStrmMetrics* pTsmMetrics)
4393{
4394 hdd_station_ctx_t *pHddStaCtx = NULL;
4395 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004396 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004397 long lrc;
4398 struct statsContext context;
4399 hdd_context_t *pHddCtx = NULL;
4400
4401 if (NULL == pAdapter)
4402 {
4403 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4404 return VOS_STATUS_E_FAULT;
4405 }
4406
4407 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4408 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4409
4410 /* we are connected prepare our callback context */
4411 init_completion(&context.completion);
4412 context.pAdapter = pAdapter;
4413 context.magic = STATS_CONTEXT_MAGIC;
4414
4415 /* query tsm stats */
4416 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4417 pHddStaCtx->conn_info.staId[ 0 ],
4418 pHddStaCtx->conn_info.bssId,
4419 &context, pHddCtx->pvosContext, tid);
4420
4421 if (eHAL_STATUS_SUCCESS != hstatus)
4422 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4424 __func__);
4425 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004426 }
4427 else
4428 {
4429 /* request was sent -- wait for the response */
4430 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4431 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004432 if (lrc <= 0)
4433 {
4434 hddLog(VOS_TRACE_LEVEL_ERROR,
4435 "%s: SME %s while retrieving statistics",
4436 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004437 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004438 }
4439 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004440
Jeff Johnson72a40512013-12-19 10:14:15 -08004441 /* either we never sent a request, we sent a request and received a
4442 response or we sent a request and timed out. if we never sent a
4443 request or if we sent a request and got a response, we want to
4444 clear the magic out of paranoia. if we timed out there is a
4445 race condition such that the callback function could be
4446 executing at the same time we are. of primary concern is if the
4447 callback function had already verified the "magic" but had not
4448 yet set the completion variable when a timeout occurred. we
4449 serialize these activities by invalidating the magic while
4450 holding a shared spinlock which will cause us to block if the
4451 callback is currently executing */
4452 spin_lock(&hdd_context_lock);
4453 context.magic = 0;
4454 spin_unlock(&hdd_context_lock);
4455
4456 if (VOS_STATUS_SUCCESS == vstatus)
4457 {
4458 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4459 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4460 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4461 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4462 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4463 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4464 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4465 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4466 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4467 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4468 }
4469 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004470}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004471#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004472
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004473#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004474void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4475{
4476 eCsrBand band = -1;
4477 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4478 switch (band)
4479 {
4480 case eCSR_BAND_ALL:
4481 *pBand = WLAN_HDD_UI_BAND_AUTO;
4482 break;
4483
4484 case eCSR_BAND_24:
4485 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4486 break;
4487
4488 case eCSR_BAND_5G:
4489 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4490 break;
4491
4492 default:
4493 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4494 *pBand = -1;
4495 break;
4496 }
4497}
4498
4499/**---------------------------------------------------------------------------
4500
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004501 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4502
4503 This function parses the send action frame data passed in the format
4504 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4505
Srinivas Girigowda56076852013-08-20 14:00:50 -07004506 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004507 \param - pTargetApBssid Pointer to target Ap bssid
4508 \param - pChannel Pointer to the Target AP channel
4509 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4510 \param - pBuf Pointer to data
4511 \param - pBufLen Pointer to data length
4512
4513 \return - 0 for success non-zero for failure
4514
4515 --------------------------------------------------------------------------*/
4516VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4517 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4518{
4519 tANI_U8 *inPtr = pValue;
4520 tANI_U8 *dataEnd;
4521 int tempInt;
4522 int j = 0;
4523 int i = 0;
4524 int v = 0;
4525 tANI_U8 tempBuf[32];
4526 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004527 /* 12 hexa decimal digits, 5 ':' and '\0' */
4528 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004529
4530 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4531 /*no argument after the command*/
4532 if (NULL == inPtr)
4533 {
4534 return -EINVAL;
4535 }
4536
4537 /*no space after the command*/
4538 else if (SPACE_ASCII_VALUE != *inPtr)
4539 {
4540 return -EINVAL;
4541 }
4542
4543 /*removing empty spaces*/
4544 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4545
4546 /*no argument followed by spaces*/
4547 if ('\0' == *inPtr)
4548 {
4549 return -EINVAL;
4550 }
4551
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004552 v = sscanf(inPtr, "%17s", macAddress);
4553 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004554 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4556 "Invalid MAC address or All hex inputs are not read (%d)", v);
4557 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004558 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004559
4560 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4561 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4562 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4563 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4564 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4565 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004566
4567 /* point to the next argument */
4568 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4569 /*no argument after the command*/
4570 if (NULL == inPtr) return -EINVAL;
4571
4572 /*removing empty spaces*/
4573 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4574
4575 /*no argument followed by spaces*/
4576 if ('\0' == *inPtr)
4577 {
4578 return -EINVAL;
4579 }
4580
4581 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004582 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004583 if (1 != v) return -EINVAL;
4584
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004585 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304586 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304587 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004588
4589 *pChannel = tempInt;
4590
4591 /* point to the next argument */
4592 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4593 /*no argument after the command*/
4594 if (NULL == inPtr) return -EINVAL;
4595 /*removing empty spaces*/
4596 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4597
4598 /*no argument followed by spaces*/
4599 if ('\0' == *inPtr)
4600 {
4601 return -EINVAL;
4602 }
4603
4604 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004605 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004606 if (1 != v) return -EINVAL;
4607
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004608 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004609 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004610
4611 *pDwellTime = tempInt;
4612
4613 /* point to the next argument */
4614 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4615 /*no argument after the command*/
4616 if (NULL == inPtr) return -EINVAL;
4617 /*removing empty spaces*/
4618 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4619
4620 /*no argument followed by spaces*/
4621 if ('\0' == *inPtr)
4622 {
4623 return -EINVAL;
4624 }
4625
4626 /* find the length of data */
4627 dataEnd = inPtr;
4628 while(('\0' != *dataEnd) )
4629 {
4630 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004631 }
Kiet Lambe150c22013-11-21 16:30:32 +05304632 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004633 if ( *pBufLen <= 0) return -EINVAL;
4634
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004635 /* Allocate the number of bytes based on the number of input characters
4636 whether it is even or odd.
4637 if the number of input characters are even, then we need N/2 byte.
4638 if the number of input characters are odd, then we need do (N+1)/2 to
4639 compensate rounding off.
4640 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4641 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4642 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004643 if (NULL == *pBuf)
4644 {
4645 hddLog(VOS_TRACE_LEVEL_FATAL,
4646 "%s: vos_mem_alloc failed ", __func__);
4647 return -EINVAL;
4648 }
4649
4650 /* the buffer received from the upper layer is character buffer,
4651 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4652 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4653 and f0 in 3rd location */
4654 for (i = 0, j = 0; j < *pBufLen; j += 2)
4655 {
Kiet Lambe150c22013-11-21 16:30:32 +05304656 if( j+1 == *pBufLen)
4657 {
4658 tempByte = hdd_parse_hex(inPtr[j]);
4659 }
4660 else
4661 {
4662 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4663 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004664 (*pBuf)[i++] = tempByte;
4665 }
4666 *pBufLen = i;
4667 return VOS_STATUS_SUCCESS;
4668}
4669
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004670/**---------------------------------------------------------------------------
4671
Srinivas Girigowdade697412013-02-14 16:31:48 -08004672 \brief hdd_parse_channellist() - HDD Parse channel list
4673
4674 This function parses the channel list passed in the format
4675 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004676 if the Number of channels (N) does not match with the actual number of channels passed
4677 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4678 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4679 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4680 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004681
4682 \param - pValue Pointer to input channel list
4683 \param - ChannelList Pointer to local output array to record channel list
4684 \param - pNumChannels Pointer to number of roam scan channels
4685
4686 \return - 0 for success non-zero for failure
4687
4688 --------------------------------------------------------------------------*/
4689VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4690{
4691 tANI_U8 *inPtr = pValue;
4692 int tempInt;
4693 int j = 0;
4694 int v = 0;
4695 char buf[32];
4696
4697 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4698 /*no argument after the command*/
4699 if (NULL == inPtr)
4700 {
4701 return -EINVAL;
4702 }
4703
4704 /*no space after the command*/
4705 else if (SPACE_ASCII_VALUE != *inPtr)
4706 {
4707 return -EINVAL;
4708 }
4709
4710 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004711 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004712
4713 /*no argument followed by spaces*/
4714 if ('\0' == *inPtr)
4715 {
4716 return -EINVAL;
4717 }
4718
4719 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004720 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004721 if (1 != v) return -EINVAL;
4722
Srinivas Girigowdade697412013-02-14 16:31:48 -08004723 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004724 if ((v < 0) ||
4725 (tempInt <= 0) ||
4726 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4727 {
4728 return -EINVAL;
4729 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004730
4731 *pNumChannels = tempInt;
4732
4733 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4734 "Number of channels are: %d", *pNumChannels);
4735
4736 for (j = 0; j < (*pNumChannels); j++)
4737 {
4738 /*inPtr pointing to the beginning of first space after number of channels*/
4739 inPtr = strpbrk( inPtr, " " );
4740 /*no channel list after the number of channels argument*/
4741 if (NULL == inPtr)
4742 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004743 if (0 != j)
4744 {
4745 *pNumChannels = j;
4746 return VOS_STATUS_SUCCESS;
4747 }
4748 else
4749 {
4750 return -EINVAL;
4751 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004752 }
4753
4754 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004755 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004756
4757 /*no channel list after the number of channels argument and spaces*/
4758 if ( '\0' == *inPtr )
4759 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004760 if (0 != j)
4761 {
4762 *pNumChannels = j;
4763 return VOS_STATUS_SUCCESS;
4764 }
4765 else
4766 {
4767 return -EINVAL;
4768 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004769 }
4770
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004771 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004772 if (1 != v) return -EINVAL;
4773
Srinivas Girigowdade697412013-02-14 16:31:48 -08004774 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004775 if ((v < 0) ||
4776 (tempInt <= 0) ||
4777 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4778 {
4779 return -EINVAL;
4780 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004781 pChannelList[j] = tempInt;
4782
4783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4784 "Channel %d added to preferred channel list",
4785 pChannelList[j] );
4786 }
4787
Srinivas Girigowdade697412013-02-14 16:31:48 -08004788 return VOS_STATUS_SUCCESS;
4789}
4790
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004791
4792/**---------------------------------------------------------------------------
4793
4794 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4795
4796 This function parses the reasoc command data passed in the format
4797 REASSOC<space><bssid><space><channel>
4798
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004799 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004800 \param - pTargetApBssid Pointer to target Ap bssid
4801 \param - pChannel Pointer to the Target AP channel
4802
4803 \return - 0 for success non-zero for failure
4804
4805 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004806VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4807 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004808{
4809 tANI_U8 *inPtr = pValue;
4810 int tempInt;
4811 int v = 0;
4812 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004813 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004814 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004815
4816 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4817 /*no argument after the command*/
4818 if (NULL == inPtr)
4819 {
4820 return -EINVAL;
4821 }
4822
4823 /*no space after the command*/
4824 else if (SPACE_ASCII_VALUE != *inPtr)
4825 {
4826 return -EINVAL;
4827 }
4828
4829 /*removing empty spaces*/
4830 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4831
4832 /*no argument followed by spaces*/
4833 if ('\0' == *inPtr)
4834 {
4835 return -EINVAL;
4836 }
4837
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004838 v = sscanf(inPtr, "%17s", macAddress);
4839 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004840 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4842 "Invalid MAC address or All hex inputs are not read (%d)", v);
4843 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004844 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004845
4846 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4847 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4848 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4849 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4850 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4851 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004852
4853 /* point to the next argument */
4854 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4855 /*no argument after the command*/
4856 if (NULL == inPtr) return -EINVAL;
4857
4858 /*removing empty spaces*/
4859 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4860
4861 /*no argument followed by spaces*/
4862 if ('\0' == *inPtr)
4863 {
4864 return -EINVAL;
4865 }
4866
4867 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004868 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004869 if (1 != v) return -EINVAL;
4870
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004871 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004872 if ((v < 0) ||
4873 (tempInt <= 0) ||
4874 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4875 {
4876 return -EINVAL;
4877 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004878
4879 *pChannel = tempInt;
4880 return VOS_STATUS_SUCCESS;
4881}
4882
4883#endif
4884
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004885#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004886/**---------------------------------------------------------------------------
4887
4888 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4889
4890 This function parses the SETCCKM IE command
4891 SETCCKMIE<space><ie data>
4892
4893 \param - pValue Pointer to input data
4894 \param - pCckmIe Pointer to output cckm Ie
4895 \param - pCckmIeLen Pointer to output cckm ie length
4896
4897 \return - 0 for success non-zero for failure
4898
4899 --------------------------------------------------------------------------*/
4900VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4901 tANI_U8 *pCckmIeLen)
4902{
4903 tANI_U8 *inPtr = pValue;
4904 tANI_U8 *dataEnd;
4905 int j = 0;
4906 int i = 0;
4907 tANI_U8 tempByte = 0;
4908
4909 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4910 /*no argument after the command*/
4911 if (NULL == inPtr)
4912 {
4913 return -EINVAL;
4914 }
4915
4916 /*no space after the command*/
4917 else if (SPACE_ASCII_VALUE != *inPtr)
4918 {
4919 return -EINVAL;
4920 }
4921
4922 /*removing empty spaces*/
4923 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4924
4925 /*no argument followed by spaces*/
4926 if ('\0' == *inPtr)
4927 {
4928 return -EINVAL;
4929 }
4930
4931 /* find the length of data */
4932 dataEnd = inPtr;
4933 while(('\0' != *dataEnd) )
4934 {
4935 dataEnd++;
4936 ++(*pCckmIeLen);
4937 }
4938 if ( *pCckmIeLen <= 0) return -EINVAL;
4939
4940 /* Allocate the number of bytes based on the number of input characters
4941 whether it is even or odd.
4942 if the number of input characters are even, then we need N/2 byte.
4943 if the number of input characters are odd, then we need do (N+1)/2 to
4944 compensate rounding off.
4945 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4946 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4947 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4948 if (NULL == *pCckmIe)
4949 {
4950 hddLog(VOS_TRACE_LEVEL_FATAL,
4951 "%s: vos_mem_alloc failed ", __func__);
4952 return -EINVAL;
4953 }
4954 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4955 /* the buffer received from the upper layer is character buffer,
4956 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4957 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4958 and f0 in 3rd location */
4959 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4960 {
4961 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4962 (*pCckmIe)[i++] = tempByte;
4963 }
4964 *pCckmIeLen = i;
4965
4966 return VOS_STATUS_SUCCESS;
4967}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004968#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004969
Jeff Johnson295189b2012-06-20 16:38:30 -07004970/**---------------------------------------------------------------------------
4971
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004972 \brief hdd_is_valid_mac_address() - Validate MAC address
4973
4974 This function validates whether the given MAC address is valid or not
4975 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4976 where X is the hexa decimal digit character and separated by ':'
4977 This algorithm works even if MAC address is not separated by ':'
4978
4979 This code checks given input string mac contains exactly 12 hexadecimal digits.
4980 and a separator colon : appears in the input string only after
4981 an even number of hex digits.
4982
4983 \param - pMacAddr pointer to the input MAC address
4984 \return - 1 for valid and 0 for invalid
4985
4986 --------------------------------------------------------------------------*/
4987
4988v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4989{
4990 int xdigit = 0;
4991 int separator = 0;
4992 while (*pMacAddr)
4993 {
4994 if (isxdigit(*pMacAddr))
4995 {
4996 xdigit++;
4997 }
4998 else if (':' == *pMacAddr)
4999 {
5000 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5001 break;
5002
5003 ++separator;
5004 }
5005 else
5006 {
5007 separator = -1;
5008 /* Invalid MAC found */
5009 return 0;
5010 }
5011 ++pMacAddr;
5012 }
5013 return (xdigit == 12 && (separator == 5 || separator == 0));
5014}
5015
5016/**---------------------------------------------------------------------------
5017
Jeff Johnson295189b2012-06-20 16:38:30 -07005018 \brief hdd_open() - HDD Open function
5019
5020 This is called in response to ifconfig up
5021
5022 \param - dev Pointer to net_device structure
5023
5024 \return - 0 for success non-zero for failure
5025
5026 --------------------------------------------------------------------------*/
5027int hdd_open (struct net_device *dev)
5028{
5029 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5030 hdd_context_t *pHddCtx;
5031 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5032 VOS_STATUS status;
5033 v_BOOL_t in_standby = TRUE;
5034
5035 if (NULL == pAdapter)
5036 {
5037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305038 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 return -ENODEV;
5040 }
5041
5042 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305043 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5044 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005045 if (NULL == pHddCtx)
5046 {
5047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005048 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005049 return -ENODEV;
5050 }
5051
5052 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5053 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5054 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005055 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5056 {
5057 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305058 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005059 in_standby = FALSE;
5060 break;
5061 }
5062 else
5063 {
5064 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5065 pAdapterNode = pNext;
5066 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005067 }
5068
5069 if (TRUE == in_standby)
5070 {
5071 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5072 {
5073 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5074 "wlan out of power save", __func__);
5075 return -EINVAL;
5076 }
5077 }
5078
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005079 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005080 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5081 {
5082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005083 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 /* Enable TX queues only when we are connected */
5085 netif_tx_start_all_queues(dev);
5086 }
5087
5088 return 0;
5089}
5090
5091int hdd_mon_open (struct net_device *dev)
5092{
5093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5094
5095 if(pAdapter == NULL) {
5096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005097 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005098 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005099 }
5100
5101 netif_start_queue(dev);
5102
5103 return 0;
5104}
5105/**---------------------------------------------------------------------------
5106
5107 \brief hdd_stop() - HDD stop function
5108
5109 This is called in response to ifconfig down
5110
5111 \param - dev Pointer to net_device structure
5112
5113 \return - 0 for success non-zero for failure
5114
5115 --------------------------------------------------------------------------*/
5116
5117int hdd_stop (struct net_device *dev)
5118{
5119 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5120 hdd_context_t *pHddCtx;
5121 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5122 VOS_STATUS status;
5123 v_BOOL_t enter_standby = TRUE;
5124
5125 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005126 if (NULL == pAdapter)
5127 {
5128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305129 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005130 return -ENODEV;
5131 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305132 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5133 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
5135 if (NULL == pHddCtx)
5136 {
5137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005138 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005139 return -ENODEV;
5140 }
5141
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305142 /* Nothing to be done if the interface is not opened */
5143 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5144 {
5145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5146 "%s: NETDEV Interface is not OPENED", __func__);
5147 return -ENODEV;
5148 }
5149
5150 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005151 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005152 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305153
5154 /* Disable TX on the interface, after this hard_start_xmit() will not
5155 * be called on that interface
5156 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005157 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305158
5159 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005160 netif_carrier_off(pAdapter->dev);
5161
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305162 /* The interface is marked as down for outside world (aka kernel)
5163 * But the driver is pretty much alive inside. The driver needs to
5164 * tear down the existing connection on the netdev (session)
5165 * cleanup the data pipes and wait until the control plane is stabilized
5166 * for this interface. The call also needs to wait until the above
5167 * mentioned actions are completed before returning to the caller.
5168 * Notice that the hdd_stop_adapter is requested not to close the session
5169 * That is intentional to be able to scan if it is a STA/P2P interface
5170 */
5171 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07005172
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305173 /* DeInit the adapter. This ensures datapath cleanup as well */
5174 hdd_deinit_adapter(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005175 /* SoftAP ifaces should never go in power save mode
5176 making sure same here. */
5177 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5178 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005179 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005180 )
5181 {
5182 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5184 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005185 EXIT();
5186 return 0;
5187 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305188 /* Find if any iface is up. If any iface is up then can't put device to
5189 * sleep/power save mode
5190 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005191 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5192 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5193 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005194 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5195 {
5196 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305197 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005198 enter_standby = FALSE;
5199 break;
5200 }
5201 else
5202 {
5203 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5204 pAdapterNode = pNext;
5205 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005206 }
5207
5208 if (TRUE == enter_standby)
5209 {
5210 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5211 "entering standby", __func__);
5212 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5213 {
5214 /*log and return success*/
5215 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5216 "wlan in power save", __func__);
5217 }
5218 }
5219
5220 EXIT();
5221 return 0;
5222}
5223
5224/**---------------------------------------------------------------------------
5225
5226 \brief hdd_uninit() - HDD uninit function
5227
5228 This is called during the netdev unregister to uninitialize all data
5229associated with the device
5230
5231 \param - dev Pointer to net_device structure
5232
5233 \return - void
5234
5235 --------------------------------------------------------------------------*/
5236static void hdd_uninit (struct net_device *dev)
5237{
5238 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5239
5240 ENTER();
5241
5242 do
5243 {
5244 if (NULL == pAdapter)
5245 {
5246 hddLog(VOS_TRACE_LEVEL_FATAL,
5247 "%s: NULL pAdapter", __func__);
5248 break;
5249 }
5250
5251 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5252 {
5253 hddLog(VOS_TRACE_LEVEL_FATAL,
5254 "%s: Invalid magic", __func__);
5255 break;
5256 }
5257
5258 if (NULL == pAdapter->pHddCtx)
5259 {
5260 hddLog(VOS_TRACE_LEVEL_FATAL,
5261 "%s: NULL pHddCtx", __func__);
5262 break;
5263 }
5264
5265 if (dev != pAdapter->dev)
5266 {
5267 hddLog(VOS_TRACE_LEVEL_FATAL,
5268 "%s: Invalid device reference", __func__);
5269 /* we haven't validated all cases so let this go for now */
5270 }
5271
5272 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5273
5274 /* after uninit our adapter structure will no longer be valid */
5275 pAdapter->dev = NULL;
5276 pAdapter->magic = 0;
5277 } while (0);
5278
5279 EXIT();
5280}
5281
5282/**---------------------------------------------------------------------------
5283
5284 \brief hdd_release_firmware() -
5285
5286 This function calls the release firmware API to free the firmware buffer.
5287
5288 \param - pFileName Pointer to the File Name.
5289 pCtx - Pointer to the adapter .
5290
5291
5292 \return - 0 for success, non zero for failure
5293
5294 --------------------------------------------------------------------------*/
5295
5296VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5297{
5298 VOS_STATUS status = VOS_STATUS_SUCCESS;
5299 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5300 ENTER();
5301
5302
5303 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5304
5305 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5306
5307 if(pHddCtx->fw) {
5308 release_firmware(pHddCtx->fw);
5309 pHddCtx->fw = NULL;
5310 }
5311 else
5312 status = VOS_STATUS_E_FAILURE;
5313 }
5314 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5315 if(pHddCtx->nv) {
5316 release_firmware(pHddCtx->nv);
5317 pHddCtx->nv = NULL;
5318 }
5319 else
5320 status = VOS_STATUS_E_FAILURE;
5321
5322 }
5323
5324 EXIT();
5325 return status;
5326}
5327
5328/**---------------------------------------------------------------------------
5329
5330 \brief hdd_request_firmware() -
5331
5332 This function reads the firmware file using the request firmware
5333 API and returns the the firmware data and the firmware file size.
5334
5335 \param - pfileName - Pointer to the file name.
5336 - pCtx - Pointer to the adapter .
5337 - ppfw_data - Pointer to the pointer of the firmware data.
5338 - pSize - Pointer to the file size.
5339
5340 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5341
5342 --------------------------------------------------------------------------*/
5343
5344
5345VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5346{
5347 int status;
5348 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5349 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5350 ENTER();
5351
5352 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5353
5354 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5355
5356 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5357 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5358 __func__, pfileName);
5359 retval = VOS_STATUS_E_FAILURE;
5360 }
5361
5362 else {
5363 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5364 *pSize = pHddCtx->fw->size;
5365 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5366 __func__, *pSize);
5367 }
5368 }
5369 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5370
5371 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5372
5373 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5374 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5375 __func__, pfileName);
5376 retval = VOS_STATUS_E_FAILURE;
5377 }
5378
5379 else {
5380 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5381 *pSize = pHddCtx->nv->size;
5382 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5383 __func__, *pSize);
5384 }
5385 }
5386
5387 EXIT();
5388 return retval;
5389}
5390/**---------------------------------------------------------------------------
5391 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5392
5393 This is the function invoked by SME to inform the result of a full power
5394 request issued by HDD
5395
5396 \param - callbackcontext - Pointer to cookie
5397 status - result of request
5398
5399 \return - None
5400
5401--------------------------------------------------------------------------*/
5402void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5403{
5404 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5405
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005406 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005407 if(&pHddCtx->full_pwr_comp_var)
5408 {
5409 complete(&pHddCtx->full_pwr_comp_var);
5410 }
5411}
5412
5413/**---------------------------------------------------------------------------
5414
5415 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5416
5417 This is the function invoked by SME to inform the result of BMPS
5418 request issued by HDD
5419
5420 \param - callbackcontext - Pointer to cookie
5421 status - result of request
5422
5423 \return - None
5424
5425--------------------------------------------------------------------------*/
5426void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5427{
5428
5429 struct completion *completion_var = (struct completion*) callbackContext;
5430
Arif Hussain6d2a3322013-11-17 19:50:10 -08005431 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 if(completion_var != NULL)
5433 {
5434 complete(completion_var);
5435 }
5436}
5437
5438/**---------------------------------------------------------------------------
5439
5440 \brief hdd_get_cfg_file_size() -
5441
5442 This function reads the configuration file using the request firmware
5443 API and returns the configuration file size.
5444
5445 \param - pCtx - Pointer to the adapter .
5446 - pFileName - Pointer to the file name.
5447 - pBufSize - Pointer to the buffer size.
5448
5449 \return - 0 for success, non zero for failure
5450
5451 --------------------------------------------------------------------------*/
5452
5453VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5454{
5455 int status;
5456 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5457
5458 ENTER();
5459
5460 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5461
5462 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5463 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5464 status = VOS_STATUS_E_FAILURE;
5465 }
5466 else {
5467 *pBufSize = pHddCtx->fw->size;
5468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5469 release_firmware(pHddCtx->fw);
5470 pHddCtx->fw = NULL;
5471 }
5472
5473 EXIT();
5474 return VOS_STATUS_SUCCESS;
5475}
5476
5477/**---------------------------------------------------------------------------
5478
5479 \brief hdd_read_cfg_file() -
5480
5481 This function reads the configuration file using the request firmware
5482 API and returns the cfg data and the buffer size of the configuration file.
5483
5484 \param - pCtx - Pointer to the adapter .
5485 - pFileName - Pointer to the file name.
5486 - pBuffer - Pointer to the data buffer.
5487 - pBufSize - Pointer to the buffer size.
5488
5489 \return - 0 for success, non zero for failure
5490
5491 --------------------------------------------------------------------------*/
5492
5493VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5494 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5495{
5496 int status;
5497 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5498
5499 ENTER();
5500
5501 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5502
5503 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5504 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5505 return VOS_STATUS_E_FAILURE;
5506 }
5507 else {
5508 if(*pBufSize != pHddCtx->fw->size) {
5509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5510 "file size", __func__);
5511 release_firmware(pHddCtx->fw);
5512 pHddCtx->fw = NULL;
5513 return VOS_STATUS_E_FAILURE;
5514 }
5515 else {
5516 if(pBuffer) {
5517 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5518 }
5519 release_firmware(pHddCtx->fw);
5520 pHddCtx->fw = NULL;
5521 }
5522 }
5523
5524 EXIT();
5525
5526 return VOS_STATUS_SUCCESS;
5527}
5528
5529/**---------------------------------------------------------------------------
5530
Jeff Johnson295189b2012-06-20 16:38:30 -07005531 \brief hdd_set_mac_address() -
5532
5533 This function sets the user specified mac address using
5534 the command ifconfig wlanX hw ether <mac adress>.
5535
5536 \param - dev - Pointer to the net device.
5537 - addr - Pointer to the sockaddr.
5538 \return - 0 for success, non zero for failure
5539
5540 --------------------------------------------------------------------------*/
5541
5542static int hdd_set_mac_address(struct net_device *dev, void *addr)
5543{
5544 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5545 struct sockaddr *psta_mac_addr = addr;
5546 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5547
5548 ENTER();
5549
5550 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5552
5553 EXIT();
5554 return halStatus;
5555}
5556
5557tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5558{
5559 int i;
5560 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5561 {
Abhishek Singheb183782014-02-06 13:37:21 +05305562 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 break;
5564 }
5565
5566 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5567 return NULL;
5568
5569 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5570 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5571}
5572
5573void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5574{
5575 int i;
5576 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5577 {
5578 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5579 {
5580 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5581 break;
5582 }
5583 }
5584 return;
5585}
5586
5587#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5588 static struct net_device_ops wlan_drv_ops = {
5589 .ndo_open = hdd_open,
5590 .ndo_stop = hdd_stop,
5591 .ndo_uninit = hdd_uninit,
5592 .ndo_start_xmit = hdd_hard_start_xmit,
5593 .ndo_tx_timeout = hdd_tx_timeout,
5594 .ndo_get_stats = hdd_stats,
5595 .ndo_do_ioctl = hdd_ioctl,
5596 .ndo_set_mac_address = hdd_set_mac_address,
5597 .ndo_select_queue = hdd_select_queue,
5598#ifdef WLAN_FEATURE_PACKET_FILTERING
5599#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5600 .ndo_set_rx_mode = hdd_set_multicast_list,
5601#else
5602 .ndo_set_multicast_list = hdd_set_multicast_list,
5603#endif //LINUX_VERSION_CODE
5604#endif
5605 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005606 static struct net_device_ops wlan_mon_drv_ops = {
5607 .ndo_open = hdd_mon_open,
5608 .ndo_stop = hdd_stop,
5609 .ndo_uninit = hdd_uninit,
5610 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5611 .ndo_tx_timeout = hdd_tx_timeout,
5612 .ndo_get_stats = hdd_stats,
5613 .ndo_do_ioctl = hdd_ioctl,
5614 .ndo_set_mac_address = hdd_set_mac_address,
5615 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005616
5617#endif
5618
5619void hdd_set_station_ops( struct net_device *pWlanDev )
5620{
5621#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005622 pWlanDev->netdev_ops = &wlan_drv_ops;
5623#else
5624 pWlanDev->open = hdd_open;
5625 pWlanDev->stop = hdd_stop;
5626 pWlanDev->uninit = hdd_uninit;
5627 pWlanDev->hard_start_xmit = NULL;
5628 pWlanDev->tx_timeout = hdd_tx_timeout;
5629 pWlanDev->get_stats = hdd_stats;
5630 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005631 pWlanDev->set_mac_address = hdd_set_mac_address;
5632#endif
5633}
5634
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005635static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005636{
5637 struct net_device *pWlanDev = NULL;
5638 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 /*
5640 * cfg80211 initialization and registration....
5641 */
5642 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5643
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 if(pWlanDev != NULL)
5645 {
5646
5647 //Save the pointer to the net_device in the HDD adapter
5648 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5649
Jeff Johnson295189b2012-06-20 16:38:30 -07005650 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5651
5652 pAdapter->dev = pWlanDev;
5653 pAdapter->pHddCtx = pHddCtx;
5654 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5655
5656 init_completion(&pAdapter->session_open_comp_var);
5657 init_completion(&pAdapter->session_close_comp_var);
5658 init_completion(&pAdapter->disconnect_comp_var);
5659 init_completion(&pAdapter->linkup_event_var);
5660 init_completion(&pAdapter->cancel_rem_on_chan_var);
5661 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305662 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005663#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5664 init_completion(&pAdapter->offchannel_tx_event);
5665#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005666 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005667#ifdef FEATURE_WLAN_TDLS
5668 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005669 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005670 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305671 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005672#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005673 init_completion(&pHddCtx->mc_sus_event_var);
5674 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305675 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005676 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005677 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005678
Rajeev79dbe4c2013-10-05 11:03:42 +05305679#ifdef FEATURE_WLAN_BATCH_SCAN
5680 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5681 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5682 pAdapter->pBatchScanRsp = NULL;
5683 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005684 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005685 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305686 mutex_init(&pAdapter->hdd_batch_scan_lock);
5687#endif
5688
Jeff Johnson295189b2012-06-20 16:38:30 -07005689 pAdapter->isLinkUpSvcNeeded = FALSE;
5690 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5691 //Init the net_device structure
5692 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5693
5694 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5695 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5696 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5697 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5698
5699 hdd_set_station_ops( pAdapter->dev );
5700
5701 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5703 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5704 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005705 /* set pWlanDev's parent to underlying device */
5706 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07005707
5708 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005709 }
5710
5711 return pAdapter;
5712}
5713
5714VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5715{
5716 struct net_device *pWlanDev = pAdapter->dev;
5717 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5718 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5719 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5720
5721 if( rtnl_lock_held )
5722 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005723 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5725 {
5726 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5727 return VOS_STATUS_E_FAILURE;
5728 }
5729 }
5730 if (register_netdevice(pWlanDev))
5731 {
5732 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5733 return VOS_STATUS_E_FAILURE;
5734 }
5735 }
5736 else
5737 {
5738 if(register_netdev(pWlanDev))
5739 {
5740 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5741 return VOS_STATUS_E_FAILURE;
5742 }
5743 }
5744 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5745
5746 return VOS_STATUS_SUCCESS;
5747}
5748
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005749static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005750{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005751 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005752
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005753 if (NULL == pAdapter)
5754 {
5755 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5756 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005757 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005758
5759 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5760 {
5761 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5762 return eHAL_STATUS_NOT_INITIALIZED;
5763 }
5764
5765 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5766
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005767#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005768 /* need to make sure all of our scheduled work has completed.
5769 * This callback is called from MC thread context, so it is safe to
5770 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005771 *
5772 * Even though this is called from MC thread context, if there is a faulty
5773 * work item in the system, that can hang this call forever. So flushing
5774 * this global work queue is not safe; and now we make sure that
5775 * individual work queues are stopped correctly. But the cancel work queue
5776 * is a GPL only API, so the proprietary version of the driver would still
5777 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005778 */
5779 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005780#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005781
5782 /* We can be blocked while waiting for scheduled work to be
5783 * flushed, and the adapter structure can potentially be freed, in
5784 * which case the magic will have been reset. So make sure the
5785 * magic is still good, and hence the adapter structure is still
5786 * valid, before signaling completion */
5787 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5788 {
5789 complete(&pAdapter->session_close_comp_var);
5790 }
5791
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 return eHAL_STATUS_SUCCESS;
5793}
5794
5795VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5796{
5797 struct net_device *pWlanDev = pAdapter->dev;
5798 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5799 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5800 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5801 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305802 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005803
5804 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005805 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 //Open a SME session for future operation
5807 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005808 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005809 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5810 {
5811 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005812 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 halStatus, halStatus );
5814 status = VOS_STATUS_E_FAILURE;
5815 goto error_sme_open;
5816 }
5817
5818 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305819 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 &pAdapter->session_open_comp_var,
5821 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305822 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 {
5824 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305825 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 status = VOS_STATUS_E_FAILURE;
5827 goto error_sme_open;
5828 }
5829
5830 // Register wireless extensions
5831 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5832 {
5833 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005834 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 halStatus, halStatus );
5836 status = VOS_STATUS_E_FAILURE;
5837 goto error_register_wext;
5838 }
5839 //Safe to register the hard_start_xmit function again
5840#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5841 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5842#else
5843 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5844#endif
5845
5846 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05305847 hddLog(VOS_TRACE_LEVEL_INFO,
5848 "%s: Set HDD connState to eConnectionState_NotConnected",
5849 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005850 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5851
5852 //Set the default operation channel
5853 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5854
5855 /* Make the default Auth Type as OPEN*/
5856 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5857
5858 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5859 {
5860 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005861 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 status, status );
5863 goto error_init_txrx;
5864 }
5865
5866 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5867
5868 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5869 {
5870 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005871 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005872 status, status );
5873 goto error_wmm_init;
5874 }
5875
5876 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5877
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005878#ifdef FEATURE_WLAN_TDLS
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305879 if(0 != wlan_hdd_sta_tdls_init(pAdapter))
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005880 {
5881 status = VOS_STATUS_E_FAILURE;
Agarwal Ashish4b87f922014-06-18 03:03:21 +05305882 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005883 goto error_tdls_init;
5884 }
5885 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5886#endif
5887
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 return VOS_STATUS_SUCCESS;
5889
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005890#ifdef FEATURE_WLAN_TDLS
5891error_tdls_init:
5892 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5893 hdd_wmm_adapter_close(pAdapter);
5894#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005895error_wmm_init:
5896 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5897 hdd_deinit_tx_rx(pAdapter);
5898error_init_txrx:
5899 hdd_UnregisterWext(pWlanDev);
5900error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005901 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 {
5903 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005904 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005906 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305908 unsigned long rc;
5909
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305911 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005913 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305914 if (rc <= 0)
5915 hddLog(VOS_TRACE_LEVEL_ERROR,
5916 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005917 }
5918}
5919error_sme_open:
5920 return status;
5921}
5922
Jeff Johnson295189b2012-06-20 16:38:30 -07005923void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5924{
5925 hdd_cfg80211_state_t *cfgState;
5926
5927 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5928
5929 if( NULL != cfgState->buf )
5930 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305931 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005932 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5933 rc = wait_for_completion_interruptible_timeout(
5934 &pAdapter->tx_action_cnf_event,
5935 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305936 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305939 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5940 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005941 }
5942 }
5943 return;
5944}
Jeff Johnson295189b2012-06-20 16:38:30 -07005945
5946void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5947{
5948 ENTER();
5949 switch ( pAdapter->device_mode )
5950 {
5951 case WLAN_HDD_INFRA_STATION:
5952 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005953 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 {
5955 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5956 {
5957 hdd_deinit_tx_rx( pAdapter );
5958 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5959 }
5960
5961 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5962 {
5963 hdd_wmm_adapter_close( pAdapter );
5964 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5965 }
5966
Jeff Johnson295189b2012-06-20 16:38:30 -07005967 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005968#ifdef FEATURE_WLAN_TDLS
5969 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5970 {
5971 wlan_hdd_tdls_exit(pAdapter);
5972 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5973 }
5974#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005975
5976 break;
5977 }
5978
5979 case WLAN_HDD_SOFTAP:
5980 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005981 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305982
5983 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5984 {
5985 hdd_wmm_adapter_close( pAdapter );
5986 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5987 }
5988
Jeff Johnson295189b2012-06-20 16:38:30 -07005989 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005990
5991 hdd_unregister_hostapd(pAdapter);
5992 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005993 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 break;
5995 }
5996
5997 case WLAN_HDD_MONITOR:
5998 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005999 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006000 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6001 {
6002 hdd_deinit_tx_rx( pAdapter );
6003 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6004 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006005 if(NULL != pAdapterforTx)
6006 {
6007 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6008 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006009 break;
6010 }
6011
6012
6013 default:
6014 break;
6015 }
6016
6017 EXIT();
6018}
6019
6020void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6021{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006022 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306023
6024 ENTER();
6025 if (NULL == pAdapter)
6026 {
6027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6028 "%s: HDD adapter is Null", __func__);
6029 return;
6030 }
6031
6032 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006033
Rajeev79dbe4c2013-10-05 11:03:42 +05306034#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306035 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6036 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006037 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306038 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6039 )
6040 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006041 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306042 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006043 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6044 {
6045 hdd_deinit_batch_scan(pAdapter);
6046 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306047 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006048 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306049#endif
6050
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6052 if( rtnl_held )
6053 {
6054 unregister_netdevice(pWlanDev);
6055 }
6056 else
6057 {
6058 unregister_netdev(pWlanDev);
6059 }
6060 // note that the pAdapter is no longer valid at this point
6061 // since the memory has been reclaimed
6062 }
6063
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306064 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006065}
6066
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006067void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6068{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306069 VOS_STATUS status;
6070 hdd_adapter_t *pAdapter = NULL;
6071 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006072
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306073 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006074
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306075 /*loop through all adapters.*/
6076 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006077 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306078 pAdapter = pAdapterNode->pAdapter;
6079 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6080 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006081
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306082 { // we skip this registration for modes other than STA and P2P client modes.
6083 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6084 pAdapterNode = pNext;
6085 continue;
6086 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006087
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306088 //Apply Dynamic DTIM For P2P
6089 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6090 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6091 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6092 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6093 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6094 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6095 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6096 (eConnectionState_Associated ==
6097 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6098 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6099 {
6100 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006101
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306102 powerRequest.uIgnoreDTIM = 1;
6103 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6104
6105 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6106 {
6107 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6108 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6109 }
6110 else
6111 {
6112 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6113 }
6114
6115 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6116 * specified during Enter/Exit BMPS when LCD off*/
6117 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6118 NULL, eANI_BOOLEAN_FALSE);
6119 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6120 NULL, eANI_BOOLEAN_FALSE);
6121
6122 /* switch to the DTIM specified in cfg.ini */
6123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6124 "Switch to DTIM %d", powerRequest.uListenInterval);
6125 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6126 break;
6127
6128 }
6129
6130 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6131 pAdapterNode = pNext;
6132 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006133}
6134
6135void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6136{
6137 /*Switch back to DTIM 1*/
6138 tSirSetPowerParamsReq powerRequest = { 0 };
6139
6140 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6141 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006142 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006143
6144 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6145 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6146 NULL, eANI_BOOLEAN_FALSE);
6147 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6148 NULL, eANI_BOOLEAN_FALSE);
6149
6150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6151 "Switch to DTIM%d",powerRequest.uListenInterval);
6152 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6153
6154}
6155
Jeff Johnson295189b2012-06-20 16:38:30 -07006156VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6157{
6158 VOS_STATUS status = VOS_STATUS_SUCCESS;
6159
6160 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6161 {
6162 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6163 }
6164
6165 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6166 {
6167 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6168 }
6169
6170 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6171 {
6172 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6173 }
6174
6175 return status;
6176}
6177
6178VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6179{
6180 hdd_adapter_t *pAdapter = NULL;
6181 eHalStatus halStatus;
6182 VOS_STATUS status = VOS_STATUS_E_INVAL;
6183 v_BOOL_t disableBmps = FALSE;
6184 v_BOOL_t disableImps = FALSE;
6185
6186 switch(session_type)
6187 {
6188 case WLAN_HDD_INFRA_STATION:
6189 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006190 case WLAN_HDD_P2P_CLIENT:
6191 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006192 //Exit BMPS -> Is Sta/P2P Client is already connected
6193 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6194 if((NULL != pAdapter)&&
6195 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6196 {
6197 disableBmps = TRUE;
6198 }
6199
6200 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6201 if((NULL != pAdapter)&&
6202 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6203 {
6204 disableBmps = TRUE;
6205 }
6206
6207 //Exit both Bmps and Imps incase of Go/SAP Mode
6208 if((WLAN_HDD_SOFTAP == session_type) ||
6209 (WLAN_HDD_P2P_GO == session_type))
6210 {
6211 disableBmps = TRUE;
6212 disableImps = TRUE;
6213 }
6214
6215 if(TRUE == disableImps)
6216 {
6217 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6218 {
6219 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6220 }
6221 }
6222
6223 if(TRUE == disableBmps)
6224 {
6225 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6226 {
6227 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6228
6229 if(eHAL_STATUS_SUCCESS != halStatus)
6230 {
6231 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006232 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006233 VOS_ASSERT(0);
6234 return status;
6235 }
6236 }
6237
6238 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6239 {
6240 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6241
6242 if(eHAL_STATUS_SUCCESS != halStatus)
6243 {
6244 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006245 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006246 VOS_ASSERT(0);
6247 return status;
6248 }
6249 }
6250 }
6251
6252 if((TRUE == disableBmps) ||
6253 (TRUE == disableImps))
6254 {
6255 /* Now, get the chip into Full Power now */
6256 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6257 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6258 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6259
6260 if(halStatus != eHAL_STATUS_SUCCESS)
6261 {
6262 if(halStatus == eHAL_STATUS_PMC_PENDING)
6263 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306264 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006265 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306266 ret = wait_for_completion_interruptible_timeout(
6267 &pHddCtx->full_pwr_comp_var,
6268 msecs_to_jiffies(1000));
6269 if (ret <= 0)
6270 {
6271 hddLog(VOS_TRACE_LEVEL_ERROR,
6272 "%s: wait on full_pwr_comp_var failed %ld",
6273 __func__, ret);
6274 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 }
6276 else
6277 {
6278 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006279 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 VOS_ASSERT(0);
6281 return status;
6282 }
6283 }
6284
6285 status = VOS_STATUS_SUCCESS;
6286 }
6287
6288 break;
6289 }
6290 return status;
6291}
6292
6293hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006294 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 tANI_U8 rtnl_held )
6296{
6297 hdd_adapter_t *pAdapter = NULL;
6298 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6299 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6300 VOS_STATUS exitbmpsStatus;
6301
Arif Hussain6d2a3322013-11-17 19:50:10 -08006302 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006303
Nirav Shah436658f2014-02-28 17:05:45 +05306304 if(macAddr == NULL)
6305 {
6306 /* Not received valid macAddr */
6307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6308 "%s:Unable to add virtual intf: Not able to get"
6309 "valid mac address",__func__);
6310 return NULL;
6311 }
6312
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 //Disable BMPS incase of Concurrency
6314 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6315
6316 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6317 {
6318 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306319 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 VOS_ASSERT(0);
6321 return NULL;
6322 }
6323
6324 switch(session_type)
6325 {
6326 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006328 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 {
6330 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6331
6332 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306333 {
6334 hddLog(VOS_TRACE_LEVEL_FATAL,
6335 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306337 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006338
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306339#ifdef FEATURE_WLAN_TDLS
6340 /* A Mutex Lock is introduced while changing/initializing the mode to
6341 * protect the concurrent access for the Adapters by TDLS module.
6342 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306343 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306344#endif
6345
Jeff Johnsone7245742012-09-05 17:12:55 -07006346 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6347 NL80211_IFTYPE_P2P_CLIENT:
6348 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006349
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306351#ifdef FEATURE_WLAN_TDLS
6352 mutex_unlock(&pHddCtx->tdls_lock);
6353#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306354
6355 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 if( VOS_STATUS_SUCCESS != status )
6357 goto err_free_netdev;
6358
6359 status = hdd_register_interface( pAdapter, rtnl_held );
6360 if( VOS_STATUS_SUCCESS != status )
6361 {
6362 hdd_deinit_adapter(pHddCtx, pAdapter);
6363 goto err_free_netdev;
6364 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306365
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306366 // Workqueue which gets scheduled in IPv4 notification callback.
6367 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6368
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306369#ifdef WLAN_NS_OFFLOAD
6370 // Workqueue which gets scheduled in IPv6 notification callback.
6371 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6372#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 //Stop the Interface TX queue.
6374 netif_tx_disable(pAdapter->dev);
6375 //netif_tx_disable(pWlanDev);
6376 netif_carrier_off(pAdapter->dev);
6377
6378 break;
6379 }
6380
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 case WLAN_HDD_SOFTAP:
6383 {
6384 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6385 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306386 {
6387 hddLog(VOS_TRACE_LEVEL_FATAL,
6388 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306390 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006391
Jeff Johnson295189b2012-06-20 16:38:30 -07006392 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6393 NL80211_IFTYPE_AP:
6394 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 pAdapter->device_mode = session_type;
6396
6397 status = hdd_init_ap_mode(pAdapter);
6398 if( VOS_STATUS_SUCCESS != status )
6399 goto err_free_netdev;
6400
6401 status = hdd_register_hostapd( pAdapter, rtnl_held );
6402 if( VOS_STATUS_SUCCESS != status )
6403 {
6404 hdd_deinit_adapter(pHddCtx, pAdapter);
6405 goto err_free_netdev;
6406 }
6407
6408 netif_tx_disable(pAdapter->dev);
6409 netif_carrier_off(pAdapter->dev);
6410
6411 hdd_set_conparam( 1 );
6412 break;
6413 }
6414 case WLAN_HDD_MONITOR:
6415 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006416 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6417 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306418 {
6419 hddLog(VOS_TRACE_LEVEL_FATAL,
6420 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306422 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006423
6424 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6425 pAdapter->device_mode = session_type;
6426 status = hdd_register_interface( pAdapter, rtnl_held );
6427#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6428 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6429#else
6430 pAdapter->dev->open = hdd_mon_open;
6431 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6432#endif
6433 hdd_init_tx_rx( pAdapter );
6434 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6435 //Set adapter to be used for data tx. It will use either GO or softap.
6436 pAdapter->sessionCtx.monitor.pAdapterForTx =
6437 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6439 {
6440 pAdapter->sessionCtx.monitor.pAdapterForTx =
6441 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6442 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 /* This workqueue will be used to transmit management packet over
6444 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006445 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6446 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6447 return NULL;
6448 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006449
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6451 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006452 }
6453 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006454 case WLAN_HDD_FTM:
6455 {
6456 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6457
6458 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306459 {
6460 hddLog(VOS_TRACE_LEVEL_FATAL,
6461 FL("failed to allocate adapter for session %d"), session_type);
6462 return NULL;
6463 }
6464
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6466 * message while loading driver in FTM mode. */
6467 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6468 pAdapter->device_mode = session_type;
6469 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306470
6471 hdd_init_tx_rx( pAdapter );
6472
6473 //Stop the Interface TX queue.
6474 netif_tx_disable(pAdapter->dev);
6475 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006476 }
6477 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006478 default:
6479 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306480 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6481 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 VOS_ASSERT(0);
6483 return NULL;
6484 }
6485 }
6486
Jeff Johnson295189b2012-06-20 16:38:30 -07006487 if( VOS_STATUS_SUCCESS == status )
6488 {
6489 //Add it to the hdd's session list.
6490 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6491 if( NULL == pHddAdapterNode )
6492 {
6493 status = VOS_STATUS_E_NOMEM;
6494 }
6495 else
6496 {
6497 pHddAdapterNode->pAdapter = pAdapter;
6498 status = hdd_add_adapter_back ( pHddCtx,
6499 pHddAdapterNode );
6500 }
6501 }
6502
6503 if( VOS_STATUS_SUCCESS != status )
6504 {
6505 if( NULL != pAdapter )
6506 {
6507 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6508 pAdapter = NULL;
6509 }
6510 if( NULL != pHddAdapterNode )
6511 {
6512 vos_mem_free( pHddAdapterNode );
6513 }
6514
6515 goto resume_bmps;
6516 }
6517
6518 if(VOS_STATUS_SUCCESS == status)
6519 {
6520 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6521
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006522 //Initialize the WoWL service
6523 if(!hdd_init_wowl(pAdapter))
6524 {
6525 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6526 goto err_free_netdev;
6527 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006529 return pAdapter;
6530
6531err_free_netdev:
6532 free_netdev(pAdapter->dev);
6533 wlan_hdd_release_intf_addr( pHddCtx,
6534 pAdapter->macAddressCurrent.bytes );
6535
6536resume_bmps:
6537 //If bmps disabled enable it
6538 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6539 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306540 if (pHddCtx->hdd_wlan_suspended)
6541 {
6542 hdd_set_pwrparams(pHddCtx);
6543 }
6544 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006545 }
6546 return NULL;
6547}
6548
6549VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6550 tANI_U8 rtnl_held )
6551{
6552 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6553 VOS_STATUS status;
6554
6555 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6556 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306557 {
6558 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6559 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306561 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006562
6563 while ( pCurrent->pAdapter != pAdapter )
6564 {
6565 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6566 if( VOS_STATUS_SUCCESS != status )
6567 break;
6568
6569 pCurrent = pNext;
6570 }
6571 pAdapterNode = pCurrent;
6572 if( VOS_STATUS_SUCCESS == status )
6573 {
6574 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6575 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306576
6577#ifdef FEATURE_WLAN_TDLS
6578
6579 /* A Mutex Lock is introduced while changing/initializing the mode to
6580 * protect the concurrent access for the Adapters by TDLS module.
6581 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306582 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306583#endif
6584
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 hdd_remove_adapter( pHddCtx, pAdapterNode );
6586 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006587 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006588
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306589#ifdef FEATURE_WLAN_TDLS
6590 mutex_unlock(&pHddCtx->tdls_lock);
6591#endif
6592
Jeff Johnson295189b2012-06-20 16:38:30 -07006593
6594 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306595 if ((!vos_concurrent_open_sessions_running()) &&
6596 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6597 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306599 if (pHddCtx->hdd_wlan_suspended)
6600 {
6601 hdd_set_pwrparams(pHddCtx);
6602 }
6603 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006604 }
6605
6606 return VOS_STATUS_SUCCESS;
6607 }
6608
6609 return VOS_STATUS_E_FAILURE;
6610}
6611
6612VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6613{
6614 hdd_adapter_list_node_t *pHddAdapterNode;
6615 VOS_STATUS status;
6616
6617 ENTER();
6618
6619 do
6620 {
6621 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6622 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6623 {
6624 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6625 vos_mem_free( pHddAdapterNode );
6626 }
6627 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6628
6629 EXIT();
6630
6631 return VOS_STATUS_SUCCESS;
6632}
6633
6634void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6635{
6636 v_U8_t addIE[1] = {0};
6637
6638 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6639 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6640 eANI_BOOLEAN_FALSE) )
6641 {
6642 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006643 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006644 }
6645
6646 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6647 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6648 eANI_BOOLEAN_FALSE) )
6649 {
6650 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006651 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006652 }
6653
6654 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6655 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6656 eANI_BOOLEAN_FALSE) )
6657 {
6658 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006659 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006660 }
6661}
6662
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306663VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6664 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07006665{
6666 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6667 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6668 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306669 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306670 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006671
6672 ENTER();
6673
6674 switch(pAdapter->device_mode)
6675 {
6676 case WLAN_HDD_INFRA_STATION:
6677 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006678 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306679 {
6680 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6681 if( hdd_connIsConnected(pstation) ||
6682 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 {
6684 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6685 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6686 pAdapter->sessionId,
6687 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6688 else
6689 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6690 pAdapter->sessionId,
6691 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6692 //success implies disconnect command got queued up successfully
6693 if(halStatus == eHAL_STATUS_SUCCESS)
6694 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306695 ret = wait_for_completion_interruptible_timeout(
6696 &pAdapter->disconnect_comp_var,
6697 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6698 if (ret <= 0)
6699 {
6700 hddLog(VOS_TRACE_LEVEL_ERROR,
6701 "%s: wait on disconnect_comp_var failed %ld",
6702 __func__, ret);
6703 }
6704 }
6705 else
6706 {
6707 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6708 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006709 }
6710 memset(&wrqu, '\0', sizeof(wrqu));
6711 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6712 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6713 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6714 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306715 else if(pstation->conn_info.connState ==
6716 eConnectionState_Disconnecting)
6717 {
6718 ret = wait_for_completion_interruptible_timeout(
6719 &pAdapter->disconnect_comp_var,
6720 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6721 if (ret <= 0)
6722 {
6723 hddLog(VOS_TRACE_LEVEL_ERROR,
6724 FL("wait on disconnect_comp_var failed %ld"), ret);
6725 }
6726 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006727 else
6728 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306729 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6730 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006731 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306732 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6733 {
6734 while (pAdapter->is_roc_inprogress)
6735 {
6736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6737 "%s: ROC in progress for session %d!!!",
6738 __func__, pAdapter->sessionId);
6739 // waiting for ROC to expire
6740 msleep(500);
6741 /* In GO present case , if retry exceeds 3,
6742 it means something went wrong. */
6743 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6744 {
6745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6746 "%s: ROC completion is not received.!!!", __func__);
6747 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6748 pAdapter->sessionId);
6749 wait_for_completion_interruptible_timeout(
6750 &pAdapter->cancel_rem_on_chan_var,
6751 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6752 break;
6753 }
6754 }
6755 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306756#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306757#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306758 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6759#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306760 if (pAdapter->ipv6_notifier_registered)
6761 {
6762 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6763 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6764 pAdapter->ipv6_notifier_registered = false;
6765 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306766#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306767 if (pAdapter->ipv4_notifier_registered)
6768 {
6769 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6770 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6771 pAdapter->ipv4_notifier_registered = false;
6772 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306773#ifdef WLAN_OPEN_SOURCE
6774 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6775#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306776 /* It is possible that the caller of this function does not
6777 * wish to close the session
6778 */
6779 if (VOS_TRUE == bCloseSession &&
6780 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006781 {
6782 INIT_COMPLETION(pAdapter->session_close_comp_var);
6783 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306784 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6785 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306787 unsigned long ret;
6788
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306790 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306791 &pAdapter->session_close_comp_var,
6792 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306793 if ( 0 >= ret)
6794 {
6795 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306796 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306797 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 }
6799 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306800 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006801 break;
6802
6803 case WLAN_HDD_SOFTAP:
6804 case WLAN_HDD_P2P_GO:
6805 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306806 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6807 while (pAdapter->is_roc_inprogress) {
6808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6809 "%s: ROC in progress for session %d!!!",
6810 __func__, pAdapter->sessionId);
6811 msleep(500);
6812 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6814 "%s: ROC completion is not received.!!!", __func__);
6815 WLANSAP_CancelRemainOnChannel(
6816 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6817 wait_for_completion_interruptible_timeout(
6818 &pAdapter->cancel_rem_on_chan_var,
6819 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6820 break;
6821 }
6822 }
6823 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006824 mutex_lock(&pHddCtx->sap_lock);
6825 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6826 {
6827 VOS_STATUS status;
6828 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6829
6830 //Stop Bss.
6831 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6832 if (VOS_IS_STATUS_SUCCESS(status))
6833 {
6834 hdd_hostapd_state_t *pHostapdState =
6835 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6836
6837 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6838
6839 if (!VOS_IS_STATUS_SUCCESS(status))
6840 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306841 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6842 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006843 }
6844 }
6845 else
6846 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006847 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 }
6849 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306850 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006851
6852 if (eHAL_STATUS_FAILURE ==
6853 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6854 0, NULL, eANI_BOOLEAN_FALSE))
6855 {
6856 hddLog(LOGE,
6857 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006858 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 }
6860
6861 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6862 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6863 eANI_BOOLEAN_FALSE) )
6864 {
6865 hddLog(LOGE,
6866 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6867 }
6868
6869 // Reset WNI_CFG_PROBE_RSP Flags
6870 wlan_hdd_reset_prob_rspies(pAdapter);
6871 kfree(pAdapter->sessionCtx.ap.beacon);
6872 pAdapter->sessionCtx.ap.beacon = NULL;
6873 }
6874 mutex_unlock(&pHddCtx->sap_lock);
6875 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006876
Jeff Johnson295189b2012-06-20 16:38:30 -07006877 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006878#ifdef WLAN_OPEN_SOURCE
6879 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6880#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006882
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 default:
6884 break;
6885 }
6886
6887 EXIT();
6888 return VOS_STATUS_SUCCESS;
6889}
6890
6891VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6892{
6893 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6894 VOS_STATUS status;
6895 hdd_adapter_t *pAdapter;
6896
6897 ENTER();
6898
6899 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6900
6901 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6902 {
6903 pAdapter = pAdapterNode->pAdapter;
6904 netif_tx_disable(pAdapter->dev);
6905 netif_carrier_off(pAdapter->dev);
6906
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306907 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006908
6909 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6910 pAdapterNode = pNext;
6911 }
6912
6913 EXIT();
6914
6915 return VOS_STATUS_SUCCESS;
6916}
6917
Rajeev Kumarf999e582014-01-09 17:33:29 -08006918
6919#ifdef FEATURE_WLAN_BATCH_SCAN
6920/**---------------------------------------------------------------------------
6921
6922 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6923 structures
6924
6925 \param - pAdapter Pointer to HDD adapter
6926
6927 \return - None
6928
6929 --------------------------------------------------------------------------*/
6930void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6931{
6932 tHddBatchScanRsp *pNode;
6933 tHddBatchScanRsp *pPrev;
6934
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306935 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006936 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306937 hddLog(VOS_TRACE_LEVEL_ERROR,
6938 "%s: Adapter context is Null", __func__);
6939 return;
6940 }
6941
6942 pNode = pAdapter->pBatchScanRsp;
6943 while (pNode)
6944 {
6945 pPrev = pNode;
6946 pNode = pNode->pNext;
6947 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006948 }
6949
6950 pAdapter->pBatchScanRsp = NULL;
6951 pAdapter->numScanList = 0;
6952 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6953 pAdapter->prev_batch_id = 0;
6954
6955 return;
6956}
6957#endif
6958
6959
Jeff Johnson295189b2012-06-20 16:38:30 -07006960VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6961{
6962 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6963 VOS_STATUS status;
6964 hdd_adapter_t *pAdapter;
6965
6966 ENTER();
6967
6968 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6969
6970 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6971 {
6972 pAdapter = pAdapterNode->pAdapter;
6973 netif_tx_disable(pAdapter->dev);
6974 netif_carrier_off(pAdapter->dev);
6975
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006976 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6977
Jeff Johnson295189b2012-06-20 16:38:30 -07006978 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306979 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6980 {
6981 hdd_wmm_adapter_close( pAdapter );
6982 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006984
Rajeev Kumarf999e582014-01-09 17:33:29 -08006985#ifdef FEATURE_WLAN_BATCH_SCAN
6986 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6987 {
6988 hdd_deinit_batch_scan(pAdapter);
6989 }
6990#endif
6991
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6993 pAdapterNode = pNext;
6994 }
6995
6996 EXIT();
6997
6998 return VOS_STATUS_SUCCESS;
6999}
7000
7001VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7002{
7003 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7004 VOS_STATUS status;
7005 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307006 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007007
7008 ENTER();
7009
7010 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7011
7012 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7013 {
7014 pAdapter = pAdapterNode->pAdapter;
7015
Kumar Anand82c009f2014-05-29 00:29:42 -07007016 hdd_wmm_init( pAdapter );
7017
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 switch(pAdapter->device_mode)
7019 {
7020 case WLAN_HDD_INFRA_STATION:
7021 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007022 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307023
7024 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7025
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 hdd_init_station_mode(pAdapter);
7027 /* Open the gates for HDD to receive Wext commands */
7028 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007029 pHddCtx->scan_info.mScanPending = FALSE;
7030 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007031
7032 //Trigger the initial scan
7033 hdd_wlan_initial_scan(pAdapter);
7034
7035 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307036 if (eConnectionState_Associated == connState ||
7037 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 {
7039 union iwreq_data wrqu;
7040 memset(&wrqu, '\0', sizeof(wrqu));
7041 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7042 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7043 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007044 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007045
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 /* indicate disconnected event to nl80211 */
7047 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7048 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007049 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307050 else if (eConnectionState_Connecting == connState)
7051 {
7052 /*
7053 * Indicate connect failure to supplicant if we were in the
7054 * process of connecting
7055 */
7056 cfg80211_connect_result(pAdapter->dev, NULL,
7057 NULL, 0, NULL, 0,
7058 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7059 GFP_KERNEL);
7060 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007061 break;
7062
7063 case WLAN_HDD_SOFTAP:
7064 /* softAP can handle SSR */
7065 break;
7066
7067 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007068 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007070 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007071 break;
7072
7073 case WLAN_HDD_MONITOR:
7074 /* monitor interface start */
7075 break;
7076 default:
7077 break;
7078 }
7079
7080 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7081 pAdapterNode = pNext;
7082 }
7083
7084 EXIT();
7085
7086 return VOS_STATUS_SUCCESS;
7087}
7088
7089VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7090{
7091 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7092 hdd_adapter_t *pAdapter;
7093 VOS_STATUS status;
7094 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307095 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007096
7097 ENTER();
7098
7099 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7100
7101 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7102 {
7103 pAdapter = pAdapterNode->pAdapter;
7104
7105 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7106 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7107 {
7108 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7109 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7110
Abhishek Singhf4669da2014-05-26 15:07:49 +05307111 hddLog(VOS_TRACE_LEVEL_INFO,
7112 "%s: Set HDD connState to eConnectionState_NotConnected",
7113 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7115 init_completion(&pAdapter->disconnect_comp_var);
7116 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7117 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7118
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307119 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007120 &pAdapter->disconnect_comp_var,
7121 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307122 if (0 >= ret)
7123 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7124 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007125
7126 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7127 pHddCtx->isAmpAllowed = VOS_FALSE;
7128 sme_RoamConnect(pHddCtx->hHal,
7129 pAdapter->sessionId, &(pWextState->roamProfile),
7130 &roamId);
7131 }
7132
7133 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7134 pAdapterNode = pNext;
7135 }
7136
7137 EXIT();
7138
7139 return VOS_STATUS_SUCCESS;
7140}
7141
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007142void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7143{
7144 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7145 VOS_STATUS status;
7146 hdd_adapter_t *pAdapter;
7147 hdd_station_ctx_t *pHddStaCtx;
7148 hdd_ap_ctx_t *pHddApCtx;
7149 hdd_hostapd_state_t * pHostapdState;
7150 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7151 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7152 const char *p2pMode = "DEV";
7153 const char *ccMode = "Standalone";
7154 int n;
7155
7156 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7157 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7158 {
7159 pAdapter = pAdapterNode->pAdapter;
7160 switch (pAdapter->device_mode) {
7161 case WLAN_HDD_INFRA_STATION:
7162 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7163 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7164 staChannel = pHddStaCtx->conn_info.operationChannel;
7165 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7166 }
7167 break;
7168 case WLAN_HDD_P2P_CLIENT:
7169 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7170 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7171 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7172 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7173 p2pMode = "CLI";
7174 }
7175 break;
7176 case WLAN_HDD_P2P_GO:
7177 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7178 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7179 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7180 p2pChannel = pHddApCtx->operatingChannel;
7181 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7182 }
7183 p2pMode = "GO";
7184 break;
7185 case WLAN_HDD_SOFTAP:
7186 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7187 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7188 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7189 apChannel = pHddApCtx->operatingChannel;
7190 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7191 }
7192 break;
7193 default:
7194 break;
7195 }
7196 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7197 pAdapterNode = pNext;
7198 }
7199 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7200 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7201 }
7202 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7203 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7204 if (p2pChannel > 0) {
7205 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7206 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7207 }
7208 if (apChannel > 0) {
7209 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7210 apChannel, MAC_ADDR_ARRAY(apBssid));
7211 }
7212
7213 if (p2pChannel > 0 && apChannel > 0) {
7214 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7215 }
7216}
7217
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007218bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007219{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007220 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007221}
7222
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007223/* Once SSR is disabled then it cannot be set. */
7224void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007225{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007226 if (HDD_SSR_DISABLED == isSsrRequired)
7227 return;
7228
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 isSsrRequired = value;
7230}
7231
7232VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7233 hdd_adapter_list_node_t** ppAdapterNode)
7234{
7235 VOS_STATUS status;
7236 spin_lock(&pHddCtx->hddAdapters.lock);
7237 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7238 (hdd_list_node_t**) ppAdapterNode );
7239 spin_unlock(&pHddCtx->hddAdapters.lock);
7240 return status;
7241}
7242
7243VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7244 hdd_adapter_list_node_t* pAdapterNode,
7245 hdd_adapter_list_node_t** pNextAdapterNode)
7246{
7247 VOS_STATUS status;
7248 spin_lock(&pHddCtx->hddAdapters.lock);
7249 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7250 (hdd_list_node_t*) pAdapterNode,
7251 (hdd_list_node_t**)pNextAdapterNode );
7252
7253 spin_unlock(&pHddCtx->hddAdapters.lock);
7254 return status;
7255}
7256
7257VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7258 hdd_adapter_list_node_t* pAdapterNode)
7259{
7260 VOS_STATUS status;
7261 spin_lock(&pHddCtx->hddAdapters.lock);
7262 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7263 &pAdapterNode->node );
7264 spin_unlock(&pHddCtx->hddAdapters.lock);
7265 return status;
7266}
7267
7268VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7269 hdd_adapter_list_node_t** ppAdapterNode)
7270{
7271 VOS_STATUS status;
7272 spin_lock(&pHddCtx->hddAdapters.lock);
7273 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7274 (hdd_list_node_t**) ppAdapterNode );
7275 spin_unlock(&pHddCtx->hddAdapters.lock);
7276 return status;
7277}
7278
7279VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7280 hdd_adapter_list_node_t* pAdapterNode)
7281{
7282 VOS_STATUS status;
7283 spin_lock(&pHddCtx->hddAdapters.lock);
7284 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7285 (hdd_list_node_t*) pAdapterNode );
7286 spin_unlock(&pHddCtx->hddAdapters.lock);
7287 return status;
7288}
7289
7290VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7291 hdd_adapter_list_node_t* pAdapterNode)
7292{
7293 VOS_STATUS status;
7294 spin_lock(&pHddCtx->hddAdapters.lock);
7295 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7296 (hdd_list_node_t*) pAdapterNode );
7297 spin_unlock(&pHddCtx->hddAdapters.lock);
7298 return status;
7299}
7300
7301hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7302 tSirMacAddr macAddr )
7303{
7304 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7305 hdd_adapter_t *pAdapter;
7306 VOS_STATUS status;
7307
7308 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7309
7310 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7311 {
7312 pAdapter = pAdapterNode->pAdapter;
7313
7314 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7315 macAddr, sizeof(tSirMacAddr) ) )
7316 {
7317 return pAdapter;
7318 }
7319 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7320 pAdapterNode = pNext;
7321 }
7322
7323 return NULL;
7324
7325}
7326
7327hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7328{
7329 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7330 hdd_adapter_t *pAdapter;
7331 VOS_STATUS status;
7332
7333 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7334
7335 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7336 {
7337 pAdapter = pAdapterNode->pAdapter;
7338
7339 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7340 IFNAMSIZ ) )
7341 {
7342 return pAdapter;
7343 }
7344 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7345 pAdapterNode = pNext;
7346 }
7347
7348 return NULL;
7349
7350}
7351
7352hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7353{
7354 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7355 hdd_adapter_t *pAdapter;
7356 VOS_STATUS status;
7357
7358 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7359
7360 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7361 {
7362 pAdapter = pAdapterNode->pAdapter;
7363
7364 if( pAdapter && (mode == pAdapter->device_mode) )
7365 {
7366 return pAdapter;
7367 }
7368 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7369 pAdapterNode = pNext;
7370 }
7371
7372 return NULL;
7373
7374}
7375
7376//Remove this function later
7377hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7378{
7379 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7380 hdd_adapter_t *pAdapter;
7381 VOS_STATUS status;
7382
7383 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7384
7385 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7386 {
7387 pAdapter = pAdapterNode->pAdapter;
7388
7389 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7390 {
7391 return pAdapter;
7392 }
7393
7394 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7395 pAdapterNode = pNext;
7396 }
7397
7398 return NULL;
7399
7400}
7401
Jeff Johnson295189b2012-06-20 16:38:30 -07007402/**---------------------------------------------------------------------------
7403
7404 \brief hdd_set_monitor_tx_adapter() -
7405
7406 This API initializes the adapter to be used while transmitting on monitor
7407 adapter.
7408
7409 \param - pHddCtx - Pointer to the HDD context.
7410 pAdapter - Adapter that will used for TX. This can be NULL.
7411 \return - None.
7412 --------------------------------------------------------------------------*/
7413void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7414{
7415 hdd_adapter_t *pMonAdapter;
7416
7417 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7418
7419 if( NULL != pMonAdapter )
7420 {
7421 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7422 }
7423}
Jeff Johnson295189b2012-06-20 16:38:30 -07007424/**---------------------------------------------------------------------------
7425
7426 \brief hdd_select_queue() -
7427
7428 This API returns the operating channel of the requested device mode
7429
7430 \param - pHddCtx - Pointer to the HDD context.
7431 - mode - Device mode for which operating channel is required
7432 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7433 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7434 \return - channel number. "0" id the requested device is not found OR it is not connected.
7435 --------------------------------------------------------------------------*/
7436v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7437{
7438 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7439 VOS_STATUS status;
7440 hdd_adapter_t *pAdapter;
7441 v_U8_t operatingChannel = 0;
7442
7443 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7444
7445 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7446 {
7447 pAdapter = pAdapterNode->pAdapter;
7448
7449 if( mode == pAdapter->device_mode )
7450 {
7451 switch(pAdapter->device_mode)
7452 {
7453 case WLAN_HDD_INFRA_STATION:
7454 case WLAN_HDD_P2P_CLIENT:
7455 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7456 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7457 break;
7458 case WLAN_HDD_SOFTAP:
7459 case WLAN_HDD_P2P_GO:
7460 /*softap connection info */
7461 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7462 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7463 break;
7464 default:
7465 break;
7466 }
7467
7468 break; //Found the device of interest. break the loop
7469 }
7470
7471 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7472 pAdapterNode = pNext;
7473 }
7474 return operatingChannel;
7475}
7476
7477#ifdef WLAN_FEATURE_PACKET_FILTERING
7478/**---------------------------------------------------------------------------
7479
7480 \brief hdd_set_multicast_list() -
7481
7482 This used to set the multicast address list.
7483
7484 \param - dev - Pointer to the WLAN device.
7485 - skb - Pointer to OS packet (sk_buff).
7486 \return - success/fail
7487
7488 --------------------------------------------------------------------------*/
7489static void hdd_set_multicast_list(struct net_device *dev)
7490{
7491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007492 int mc_count;
7493 int i = 0;
7494 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307495
7496 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007497 {
7498 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307499 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 return;
7501 }
7502
7503 if (dev->flags & IFF_ALLMULTI)
7504 {
7505 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007506 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307507 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 }
7509 else
7510 {
7511 mc_count = netdev_mc_count(dev);
7512 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007513 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007514 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7515 {
7516 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007517 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307518 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007519 return;
7520 }
7521
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307522 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007523
7524 netdev_for_each_mc_addr(ha, dev) {
7525 if (i == mc_count)
7526 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307527 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7528 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007529 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007530 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307531 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007532 i++;
7533 }
7534 }
7535 return;
7536}
7537#endif
7538
7539/**---------------------------------------------------------------------------
7540
7541 \brief hdd_select_queue() -
7542
7543 This function is registered with the Linux OS for network
7544 core to decide which queue to use first.
7545
7546 \param - dev - Pointer to the WLAN device.
7547 - skb - Pointer to OS packet (sk_buff).
7548 \return - ac, Queue Index/access category corresponding to UP in IP header
7549
7550 --------------------------------------------------------------------------*/
7551v_U16_t hdd_select_queue(struct net_device *dev,
7552 struct sk_buff *skb)
7553{
7554 return hdd_wmm_select_queue(dev, skb);
7555}
7556
7557
7558/**---------------------------------------------------------------------------
7559
7560 \brief hdd_wlan_initial_scan() -
7561
7562 This function triggers the initial scan
7563
7564 \param - pAdapter - Pointer to the HDD adapter.
7565
7566 --------------------------------------------------------------------------*/
7567void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7568{
7569 tCsrScanRequest scanReq;
7570 tCsrChannelInfo channelInfo;
7571 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007572 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007573 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7574
7575 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7576 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7577 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7578
7579 if(sme_Is11dSupported(pHddCtx->hHal))
7580 {
7581 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7582 if ( HAL_STATUS_SUCCESS( halStatus ) )
7583 {
7584 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7585 if( !scanReq.ChannelInfo.ChannelList )
7586 {
7587 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7588 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007589 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007590 return;
7591 }
7592 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7593 channelInfo.numOfChannels);
7594 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7595 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007596 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 }
7598
7599 scanReq.scanType = eSIR_PASSIVE_SCAN;
7600 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7601 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7602 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7603 }
7604 else
7605 {
7606 scanReq.scanType = eSIR_ACTIVE_SCAN;
7607 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7608 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7609 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7610 }
7611
7612 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7613 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7614 {
7615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7616 __func__, halStatus );
7617 }
7618
7619 if(sme_Is11dSupported(pHddCtx->hHal))
7620 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7621}
7622
Jeff Johnson295189b2012-06-20 16:38:30 -07007623/**---------------------------------------------------------------------------
7624
7625 \brief hdd_full_power_callback() - HDD full power callback function
7626
7627 This is the function invoked by SME to inform the result of a full power
7628 request issued by HDD
7629
7630 \param - callbackcontext - Pointer to cookie
7631 \param - status - result of request
7632
7633 \return - None
7634
7635 --------------------------------------------------------------------------*/
7636static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7637{
Jeff Johnson72a40512013-12-19 10:14:15 -08007638 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007639
7640 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307641 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007642
7643 if (NULL == callbackContext)
7644 {
7645 hddLog(VOS_TRACE_LEVEL_ERROR,
7646 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007647 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 return;
7649 }
7650
Jeff Johnson72a40512013-12-19 10:14:15 -08007651 /* there is a race condition that exists between this callback
7652 function and the caller since the caller could time out either
7653 before or while this code is executing. we use a spinlock to
7654 serialize these actions */
7655 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007656
7657 if (POWER_CONTEXT_MAGIC != pContext->magic)
7658 {
7659 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007660 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007661 hddLog(VOS_TRACE_LEVEL_WARN,
7662 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007663 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 return;
7665 }
7666
Jeff Johnson72a40512013-12-19 10:14:15 -08007667 /* context is valid so caller is still waiting */
7668
7669 /* paranoia: invalidate the magic */
7670 pContext->magic = 0;
7671
7672 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007674
7675 /* serialization is complete */
7676 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007677}
7678
7679/**---------------------------------------------------------------------------
7680
7681 \brief hdd_wlan_exit() - HDD WLAN exit function
7682
7683 This is the driver exit point (invoked during rmmod)
7684
7685 \param - pHddCtx - Pointer to the HDD Context
7686
7687 \return - None
7688
7689 --------------------------------------------------------------------------*/
7690void hdd_wlan_exit(hdd_context_t *pHddCtx)
7691{
7692 eHalStatus halStatus;
7693 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7694 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307695 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007696 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007697 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007698 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05307699 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007700
7701 ENTER();
7702
Jeff Johnson88ba7742013-02-27 14:36:02 -08007703 if (VOS_FTM_MODE != hdd_get_conparam())
7704 {
7705 // Unloading, restart logic is no more required.
7706 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07007707
c_hpothu5ab05e92014-06-13 17:34:05 +05307708 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7709 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07007710 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307711 pAdapter = pAdapterNode->pAdapter;
7712 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007713 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307714 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
7715 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
7716 {
7717 wlan_hdd_cfg80211_deregister_frames(pAdapter);
7718 hdd_UnregisterWext(pAdapter->dev);
7719 }
7720 // Cancel any outstanding scan requests. We are about to close all
7721 // of our adapters, but an adapter structure is what SME passes back
7722 // to our callback function. Hence if there are any outstanding scan
7723 // requests then there is a race condition between when the adapter
7724 // is closed and when the callback is invoked.We try to resolve that
7725 // race condition here by canceling any outstanding scans before we
7726 // close the adapters.
7727 // Note that the scans may be cancelled in an asynchronous manner,
7728 // so ideally there needs to be some kind of synchronization. Rather
7729 // than introduce a new synchronization here, we will utilize the
7730 // fact that we are about to Request Full Power, and since that is
7731 // synchronized, the expectation is that by the time Request Full
7732 // Power has completed all scans will be cancelled.
7733 if (pHddCtx->scan_info.mScanPending)
7734 {
7735 hddLog(VOS_TRACE_LEVEL_INFO,
7736 FL("abort scan mode: %d sessionId: %d"),
7737 pAdapter->device_mode,
7738 pAdapter->sessionId);
7739 hdd_abort_mac_scan(pHddCtx,
7740 pAdapter->sessionId,
7741 eCSR_SCAN_ABORT_DEFAULT);
7742 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007743 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307744 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7745 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007746 }
7747 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307748 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08007749 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307750 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007751 wlan_hdd_ftm_close(pHddCtx);
7752 goto free_hdd_ctx;
7753 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307754
Jeff Johnson295189b2012-06-20 16:38:30 -07007755 /* DeRegister with platform driver as client for Suspend/Resume */
7756 vosStatus = hddDeregisterPmOps(pHddCtx);
7757 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7758 {
7759 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7760 VOS_ASSERT(0);
7761 }
7762
7763 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7764 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7765 {
7766 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7767 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007768
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007769 //Stop the traffic monitor timer
7770 if ( VOS_TIMER_STATE_RUNNING ==
7771 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7772 {
7773 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7774 }
7775
7776 // Destroy the traffic monitor timer
7777 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7778 &pHddCtx->tx_rx_trafficTmr)))
7779 {
7780 hddLog(VOS_TRACE_LEVEL_ERROR,
7781 "%s: Cannot deallocate Traffic monitor timer", __func__);
7782 }
7783
Jeff Johnson295189b2012-06-20 16:38:30 -07007784 //Disable IMPS/BMPS as we do not want the device to enter any power
7785 //save mode during shutdown
7786 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7787 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7788 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7789
7790 //Ensure that device is in full power as we will touch H/W during vos_Stop
7791 init_completion(&powerContext.completion);
7792 powerContext.magic = POWER_CONTEXT_MAGIC;
7793
7794 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7795 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7796
7797 if (eHAL_STATUS_SUCCESS != halStatus)
7798 {
7799 if (eHAL_STATUS_PMC_PENDING == halStatus)
7800 {
7801 /* request was sent -- wait for the response */
7802 lrc = wait_for_completion_interruptible_timeout(
7803 &powerContext.completion,
7804 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007805 if (lrc <= 0)
7806 {
7807 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007808 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007809 }
7810 }
7811 else
7812 {
7813 hddLog(VOS_TRACE_LEVEL_ERROR,
7814 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007815 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007816 /* continue -- need to clean up as much as possible */
7817 }
7818 }
7819
Jeff Johnson72a40512013-12-19 10:14:15 -08007820 /* either we never sent a request, we sent a request and received a
7821 response or we sent a request and timed out. if we never sent a
7822 request or if we sent a request and got a response, we want to
7823 clear the magic out of paranoia. if we timed out there is a
7824 race condition such that the callback function could be
7825 executing at the same time we are. of primary concern is if the
7826 callback function had already verified the "magic" but had not
7827 yet set the completion variable when a timeout occurred. we
7828 serialize these activities by invalidating the magic while
7829 holding a shared spinlock which will cause us to block if the
7830 callback is currently executing */
7831 spin_lock(&hdd_context_lock);
7832 powerContext.magic = 0;
7833 spin_unlock(&hdd_context_lock);
7834
Yue Ma0d4891e2013-08-06 17:01:45 -07007835 hdd_debugfs_exit(pHddCtx);
7836
Jeff Johnson295189b2012-06-20 16:38:30 -07007837 // Unregister the Net Device Notifier
7838 unregister_netdevice_notifier(&hdd_netdev_notifier);
7839
Jeff Johnson295189b2012-06-20 16:38:30 -07007840 hdd_stop_all_adapters( pHddCtx );
7841
Jeff Johnson295189b2012-06-20 16:38:30 -07007842#ifdef WLAN_BTAMP_FEATURE
7843 vosStatus = WLANBAP_Stop(pVosContext);
7844 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7845 {
7846 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7847 "%s: Failed to stop BAP",__func__);
7848 }
7849#endif //WLAN_BTAMP_FEATURE
7850
7851 //Stop all the modules
7852 vosStatus = vos_stop( pVosContext );
7853 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7854 {
7855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7856 "%s: Failed to stop VOSS",__func__);
7857 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7858 }
7859
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 //Assert Deep sleep signal now to put Libra HW in lowest power state
7861 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7862 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7863
7864 //Vote off any PMIC voltage supplies
7865 vos_chipPowerDown(NULL, NULL, NULL);
7866
7867 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7868
Leo Chang59cdc7e2013-07-10 10:08:21 -07007869
Jeff Johnson295189b2012-06-20 16:38:30 -07007870 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007872
7873 //Close the scheduler before calling vos_close to make sure no thread is
7874 // scheduled after the each module close is called i.e after all the data
7875 // structures are freed.
7876 vosStatus = vos_sched_close( pVosContext );
7877 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7878 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7879 "%s: Failed to close VOSS Scheduler",__func__);
7880 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7881 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007882#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007883#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7884 /* Destroy the wake lock */
7885 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7886#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007887 /* Destroy the wake lock */
7888 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007890
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307891#ifdef CONFIG_ENABLE_LINUX_REG
7892 vosStatus = vos_nv_close();
7893 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7894 {
7895 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7896 "%s: Failed to close NV", __func__);
7897 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7898 }
7899#endif
7900
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 //Close VOSS
7902 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7903 vos_close(pVosContext);
7904
Jeff Johnson295189b2012-06-20 16:38:30 -07007905 //Close Watchdog
7906 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7907 vos_watchdog_close(pVosContext);
7908
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307909 //Clean up HDD Nlink Service
7910 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007911#ifdef WLAN_KD_READY_NOTIFIER
7912 nl_srv_exit(pHddCtx->ptt_pid);
7913#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307914 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007915#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307916
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307917#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307918 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307919 {
7920 wlan_logging_sock_deactivate_svc();
7921 }
7922#endif
7923
Jeff Johnson295189b2012-06-20 16:38:30 -07007924 /* Cancel the vote for XO Core ON.
7925 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7926 * exited at this point
7927 */
7928 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007929 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007930 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7931 {
7932 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7933 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007934 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 }
7936
7937 hdd_close_all_adapters( pHddCtx );
7938
Jeff Johnson295189b2012-06-20 16:38:30 -07007939 /* free the power on lock from platform driver */
7940 if (free_riva_power_on_lock("wlan"))
7941 {
7942 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7943 __func__);
7944 }
7945
Jeff Johnson88ba7742013-02-27 14:36:02 -08007946free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05307947
7948 //Free up dynamically allocated members inside HDD Adapter
7949 if (pHddCtx->cfg_ini)
7950 {
7951 kfree(pHddCtx->cfg_ini);
7952 pHddCtx->cfg_ini= NULL;
7953 }
7954
Leo Changf04ddad2013-09-18 13:46:38 -07007955 /* FTM mode, WIPHY did not registered
7956 If un-register here, system crash will happen */
7957 if (VOS_FTM_MODE != hdd_get_conparam())
7958 {
7959 wiphy_unregister(wiphy) ;
7960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 if (hdd_is_ssr_required())
7963 {
7964 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007965 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007966 msleep(5000);
7967 }
7968 hdd_set_ssr_required (VOS_FALSE);
7969}
7970
7971
7972/**---------------------------------------------------------------------------
7973
7974 \brief hdd_update_config_from_nv() - Function to update the contents of
7975 the running configuration with parameters taken from NV storage
7976
7977 \param - pHddCtx - Pointer to the HDD global context
7978
7979 \return - VOS_STATUS_SUCCESS if successful
7980
7981 --------------------------------------------------------------------------*/
7982static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7983{
Jeff Johnson295189b2012-06-20 16:38:30 -07007984 v_BOOL_t itemIsValid = VOS_FALSE;
7985 VOS_STATUS status;
7986 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7987 v_U8_t macLoop;
7988
7989 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7990 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7991 if(status != VOS_STATUS_SUCCESS)
7992 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007993 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 return VOS_STATUS_E_FAILURE;
7995 }
7996
7997 if (itemIsValid == VOS_TRUE)
7998 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007999 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008000 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8001 VOS_MAX_CONCURRENCY_PERSONA);
8002 if(status != VOS_STATUS_SUCCESS)
8003 {
8004 /* Get MAC from NV fail, not update CFG info
8005 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008006 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008007 return VOS_STATUS_E_FAILURE;
8008 }
8009
8010 /* If first MAC is not valid, treat all others are not valid
8011 * Then all MACs will be got from ini file */
8012 if(vos_is_macaddr_zero(&macFromNV[0]))
8013 {
8014 /* MAC address in NV file is not configured yet */
8015 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8016 return VOS_STATUS_E_INVAL;
8017 }
8018
8019 /* Get MAC address from NV, update CFG info */
8020 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8021 {
8022 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8023 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308024 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008025 /* This MAC is not valid, skip it
8026 * This MAC will be got from ini file */
8027 }
8028 else
8029 {
8030 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8031 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8032 VOS_MAC_ADDR_SIZE);
8033 }
8034 }
8035 }
8036 else
8037 {
8038 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8039 return VOS_STATUS_E_FAILURE;
8040 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008041
Jeff Johnson295189b2012-06-20 16:38:30 -07008042
8043 return VOS_STATUS_SUCCESS;
8044}
8045
8046/**---------------------------------------------------------------------------
8047
8048 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8049
8050 \param - pAdapter - Pointer to the HDD
8051
8052 \return - None
8053
8054 --------------------------------------------------------------------------*/
8055VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8056{
8057 eHalStatus halStatus;
8058 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308059 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008060
Jeff Johnson295189b2012-06-20 16:38:30 -07008061
8062 // Send ready indication to the HDD. This will kick off the MAC
8063 // into a 'running' state and should kick off an initial scan.
8064 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8065 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8066 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308067 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008068 "code %08d [x%08x]",__func__, halStatus, halStatus );
8069 return VOS_STATUS_E_FAILURE;
8070 }
8071
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308072 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8074 // And RIVA will crash
8075 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8076 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308077 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8078 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8079
8080
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 return VOS_STATUS_SUCCESS;
8082}
8083
Jeff Johnson295189b2012-06-20 16:38:30 -07008084/* wake lock APIs for HDD */
8085void hdd_prevent_suspend(void)
8086{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008087#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008088 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008089#else
8090 wcnss_prevent_suspend();
8091#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008092}
8093
8094void hdd_allow_suspend(void)
8095{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008096#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008097 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008098#else
8099 wcnss_allow_suspend();
8100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008101}
8102
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308103void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008104{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008105#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008106 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008107#else
8108 /* Do nothing as there is no API in wcnss for timeout*/
8109#endif
8110}
8111
Jeff Johnson295189b2012-06-20 16:38:30 -07008112/**---------------------------------------------------------------------------
8113
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008114 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8115 information between Host and Riva
8116
8117 This function gets reported version of FW
8118 It also finds the version of Riva headers used to compile the host
8119 It compares the above two and prints a warning if they are different
8120 It gets the SW and HW version string
8121 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8122 indicating the features they support through a bitmap
8123
8124 \param - pHddCtx - Pointer to HDD context
8125
8126 \return - void
8127
8128 --------------------------------------------------------------------------*/
8129
8130void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8131{
8132
8133 tSirVersionType versionCompiled;
8134 tSirVersionType versionReported;
8135 tSirVersionString versionString;
8136 tANI_U8 fwFeatCapsMsgSupported = 0;
8137 VOS_STATUS vstatus;
8138
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008139 memset(&versionCompiled, 0, sizeof(versionCompiled));
8140 memset(&versionReported, 0, sizeof(versionReported));
8141
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008142 /* retrieve and display WCNSS version information */
8143 do {
8144
8145 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8146 &versionCompiled);
8147 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8148 {
8149 hddLog(VOS_TRACE_LEVEL_FATAL,
8150 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008151 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008152 break;
8153 }
8154
8155 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8156 &versionReported);
8157 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8158 {
8159 hddLog(VOS_TRACE_LEVEL_FATAL,
8160 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008161 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008162 break;
8163 }
8164
8165 if ((versionCompiled.major != versionReported.major) ||
8166 (versionCompiled.minor != versionReported.minor) ||
8167 (versionCompiled.version != versionReported.version) ||
8168 (versionCompiled.revision != versionReported.revision))
8169 {
8170 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8171 "Host expected %u.%u.%u.%u\n",
8172 WLAN_MODULE_NAME,
8173 (int)versionReported.major,
8174 (int)versionReported.minor,
8175 (int)versionReported.version,
8176 (int)versionReported.revision,
8177 (int)versionCompiled.major,
8178 (int)versionCompiled.minor,
8179 (int)versionCompiled.version,
8180 (int)versionCompiled.revision);
8181 }
8182 else
8183 {
8184 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8185 WLAN_MODULE_NAME,
8186 (int)versionReported.major,
8187 (int)versionReported.minor,
8188 (int)versionReported.version,
8189 (int)versionReported.revision);
8190 }
8191
8192 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8193 versionString,
8194 sizeof(versionString));
8195 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8196 {
8197 hddLog(VOS_TRACE_LEVEL_FATAL,
8198 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008199 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008200 break;
8201 }
8202
8203 pr_info("%s: WCNSS software version %s\n",
8204 WLAN_MODULE_NAME, versionString);
8205
8206 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8207 versionString,
8208 sizeof(versionString));
8209 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8210 {
8211 hddLog(VOS_TRACE_LEVEL_FATAL,
8212 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008213 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008214 break;
8215 }
8216
8217 pr_info("%s: WCNSS hardware version %s\n",
8218 WLAN_MODULE_NAME, versionString);
8219
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008220 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8221 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008222 send the message only if it the riva is 1.1
8223 minor numbers for different riva branches:
8224 0 -> (1.0)Mainline Build
8225 1 -> (1.1)Mainline Build
8226 2->(1.04) Stability Build
8227 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008228 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008229 ((versionReported.minor>=1) && (versionReported.version>=1)))
8230 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8231 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008232
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008233 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008234 {
8235#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8236 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8237 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8238#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008239 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8240 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8241 {
8242 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8243 }
8244
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008245 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008246 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008247
8248 } while (0);
8249
8250}
8251
8252/**---------------------------------------------------------------------------
8253
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308254 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8255
8256 \param - pHddCtx - Pointer to the hdd context
8257
8258 \return - true if hardware supports 5GHz
8259
8260 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308261boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308262{
8263 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8264 * then hardware support 5Ghz.
8265 */
8266 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8267 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308268 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308269 return true;
8270 }
8271 else
8272 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308273 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308274 __func__);
8275 return false;
8276 }
8277}
8278
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308279/**---------------------------------------------------------------------------
8280
8281 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8282 generate function
8283
8284 This is generate the random mac address for WLAN interface
8285
8286 \param - pHddCtx - Pointer to HDD context
8287 idx - Start interface index to get auto
8288 generated mac addr.
8289 mac_addr - Mac address
8290
8291 \return - 0 for success, < 0 for failure
8292
8293 --------------------------------------------------------------------------*/
8294
8295static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8296 int idx, v_MACADDR_t mac_addr)
8297{
8298 int i;
8299 unsigned int serialno;
8300 serialno = wcnss_get_serial_number();
8301
8302 if (0 != serialno)
8303 {
8304 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8305 bytes of the serial number that can be used to generate
8306 the other 3 bytes of the MAC address. Mask off all but
8307 the lower 3 bytes (this will also make sure we don't
8308 overflow in the next step) */
8309 serialno &= 0x00FFFFFF;
8310
8311 /* we need a unique address for each session */
8312 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8313
8314 /* autogen other Mac addresses */
8315 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8316 {
8317 /* start with the entire default address */
8318 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8319 /* then replace the lower 3 bytes */
8320 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8321 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8322 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8323
8324 serialno++;
8325 hddLog(VOS_TRACE_LEVEL_ERROR,
8326 "%s: Derived Mac Addr: "
8327 MAC_ADDRESS_STR, __func__,
8328 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8329 }
8330
8331 }
8332 else
8333 {
8334 hddLog(LOGE, FL("Failed to Get Serial NO"));
8335 return -1;
8336 }
8337 return 0;
8338}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308339
8340/**---------------------------------------------------------------------------
8341
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308342 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8343 completed to flush out the scan results
8344
8345 11d scan is done during driver load and is a passive scan on all
8346 channels supported by the device, 11d scans may find some APs on
8347 frequencies which are forbidden to be used in the regulatory domain
8348 the device is operating in. If these APs are notified to the supplicant
8349 it may try to connect to these APs, thus flush out all the scan results
8350 which are present in SME after 11d scan is done.
8351
8352 \return - eHalStatus
8353
8354 --------------------------------------------------------------------------*/
8355static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8356 tANI_U32 scanId, eCsrScanStatus status)
8357{
8358 ENTER();
8359
8360 sme_ScanFlushResult(halHandle, 0);
8361
8362 EXIT();
8363
8364 return eHAL_STATUS_SUCCESS;
8365}
8366
8367/**---------------------------------------------------------------------------
8368
Jeff Johnson295189b2012-06-20 16:38:30 -07008369 \brief hdd_wlan_startup() - HDD init function
8370
8371 This is the driver startup code executed once a WLAN device has been detected
8372
8373 \param - dev - Pointer to the underlying device
8374
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008375 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008376
8377 --------------------------------------------------------------------------*/
8378
8379int hdd_wlan_startup(struct device *dev )
8380{
8381 VOS_STATUS status;
8382 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008383 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008384 hdd_context_t *pHddCtx = NULL;
8385 v_CONTEXT_t pVosContext= NULL;
8386#ifdef WLAN_BTAMP_FEATURE
8387 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8388 WLANBAP_ConfigType btAmpConfig;
8389 hdd_config_t *pConfig;
8390#endif
8391 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308393 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008394
8395 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008396 /*
8397 * cfg80211: wiphy allocation
8398 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308399 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008400
8401 if(wiphy == NULL)
8402 {
8403 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008404 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 }
8406
8407 pHddCtx = wiphy_priv(wiphy);
8408
Jeff Johnson295189b2012-06-20 16:38:30 -07008409 //Initialize the adapter context to zeros.
8410 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8411
Jeff Johnson295189b2012-06-20 16:38:30 -07008412 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008413 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308414 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008415
8416 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8417
8418 /*Get vos context here bcoz vos_open requires it*/
8419 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8420
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008421 if(pVosContext == NULL)
8422 {
8423 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8424 goto err_free_hdd_context;
8425 }
8426
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 //Save the Global VOSS context in adapter context for future.
8428 pHddCtx->pvosContext = pVosContext;
8429
8430 //Save the adapter context in global context for future.
8431 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8432
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 pHddCtx->parent_dev = dev;
8434
8435 init_completion(&pHddCtx->full_pwr_comp_var);
8436 init_completion(&pHddCtx->standby_comp_var);
8437 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008438 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008439 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308440 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308441 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008442
8443#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008444 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008445#else
8446 init_completion(&pHddCtx->driver_crda_req);
8447#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008448
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308449 spin_lock_init(&pHddCtx->schedScan_lock);
8450
Jeff Johnson295189b2012-06-20 16:38:30 -07008451 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8452
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308453#ifdef FEATURE_WLAN_TDLS
8454 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8455 * invoked by other instances also) to protect the concurrent
8456 * access for the Adapters by TDLS module.
8457 */
8458 mutex_init(&pHddCtx->tdls_lock);
8459#endif
Agarwal Ashish1f422872014-07-22 00:11:55 +05308460 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308461
Agarwal Ashish1f422872014-07-22 00:11:55 +05308462 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 // Load all config first as TL config is needed during vos_open
8464 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8465 if(pHddCtx->cfg_ini == NULL)
8466 {
8467 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8468 goto err_free_hdd_context;
8469 }
8470
8471 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8472
8473 // Read and parse the qcom_cfg.ini file
8474 status = hdd_parse_config_ini( pHddCtx );
8475 if ( VOS_STATUS_SUCCESS != status )
8476 {
8477 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8478 __func__, WLAN_INI_FILE);
8479 goto err_config;
8480 }
Arif Hussaind5218912013-12-05 01:10:55 -08008481#ifdef MEMORY_DEBUG
8482 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8483 vos_mem_init();
8484
8485 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8486 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8487#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008488
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308489 /* INI has been read, initialise the configuredMcastBcastFilter with
8490 * INI value as this will serve as the default value
8491 */
8492 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8493 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8494 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308495
8496 if (false == hdd_is_5g_supported(pHddCtx))
8497 {
8498 //5Ghz is not supported.
8499 if (1 != pHddCtx->cfg_ini->nBandCapability)
8500 {
8501 hddLog(VOS_TRACE_LEVEL_INFO,
8502 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8503 pHddCtx->cfg_ini->nBandCapability = 1;
8504 }
8505 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308506
8507 /* If SNR Monitoring is enabled, FW has to parse all beacons
8508 * for calcaluting and storing the average SNR, so set Nth beacon
8509 * filter to 1 to enable FW to parse all the beaocons
8510 */
8511 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8512 {
8513 /* The log level is deliberately set to WARN as overriding
8514 * nthBeaconFilter to 1 will increase power cosumption and this
8515 * might just prove helpful to detect the power issue.
8516 */
8517 hddLog(VOS_TRACE_LEVEL_WARN,
8518 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8519 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8520 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008521 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308522 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008523 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008524 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008525 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008526 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8527 {
8528 hddLog(VOS_TRACE_LEVEL_FATAL,
8529 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8530 goto err_config;
8531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008533
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008534 // Update VOS trace levels based upon the cfg.ini
8535 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8536 pHddCtx->cfg_ini->vosTraceEnableBAP);
8537 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8538 pHddCtx->cfg_ini->vosTraceEnableTL);
8539 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8540 pHddCtx->cfg_ini->vosTraceEnableWDI);
8541 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8542 pHddCtx->cfg_ini->vosTraceEnableHDD);
8543 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8544 pHddCtx->cfg_ini->vosTraceEnableSME);
8545 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8546 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308547 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8548 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008549 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8550 pHddCtx->cfg_ini->vosTraceEnableWDA);
8551 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8552 pHddCtx->cfg_ini->vosTraceEnableSYS);
8553 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8554 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008555 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8556 pHddCtx->cfg_ini->vosTraceEnableSAP);
8557 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8558 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008559
Jeff Johnson295189b2012-06-20 16:38:30 -07008560 // Update WDI trace levels based upon the cfg.ini
8561 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8562 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8563 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8564 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8565 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8566 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8567 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8568 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008569
Jeff Johnson88ba7742013-02-27 14:36:02 -08008570 if (VOS_FTM_MODE == hdd_get_conparam())
8571 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008572 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8573 {
8574 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8575 goto err_free_hdd_context;
8576 }
8577 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308578
8579 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008581 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008582
Jeff Johnson88ba7742013-02-27 14:36:02 -08008583 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8585 {
8586 status = vos_watchdog_open(pVosContext,
8587 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8588
8589 if(!VOS_IS_STATUS_SUCCESS( status ))
8590 {
8591 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308592 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008593 }
8594 }
8595
8596 pHddCtx->isLogpInProgress = FALSE;
8597 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8598
Jeff Johnson295189b2012-06-20 16:38:30 -07008599 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8600 if(!VOS_IS_STATUS_SUCCESS(status))
8601 {
8602 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008603 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008604 }
8605
Amar Singhala49cbc52013-10-08 18:37:44 -07008606#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008607 /* initialize the NV module. This is required so that
8608 we can initialize the channel information in wiphy
8609 from the NV.bin data. The channel information in
8610 wiphy needs to be initialized before wiphy registration */
8611
8612 status = vos_nv_open();
8613 if (!VOS_IS_STATUS_SUCCESS(status))
8614 {
8615 /* NV module cannot be initialized */
8616 hddLog( VOS_TRACE_LEVEL_FATAL,
8617 "%s: vos_nv_open failed", __func__);
8618 goto err_clkvote;
8619 }
8620
8621 status = vos_init_wiphy_from_nv_bin();
8622 if (!VOS_IS_STATUS_SUCCESS(status))
8623 {
8624 /* NV module cannot be initialized */
8625 hddLog( VOS_TRACE_LEVEL_FATAL,
8626 "%s: vos_init_wiphy failed", __func__);
8627 goto err_vos_nv_close;
8628 }
8629
Amar Singhala49cbc52013-10-08 18:37:44 -07008630#endif
8631
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308632 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008633 if ( !VOS_IS_STATUS_SUCCESS( status ))
8634 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008635 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308636 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008637 }
8638
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8640
8641 if ( NULL == pHddCtx->hHal )
8642 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008643 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008644 goto err_vosclose;
8645 }
8646
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008647 status = vos_preStart( pHddCtx->pvosContext );
8648 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8649 {
8650 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308651 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008652 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008653
Arif Hussaineaf68602013-12-30 23:10:44 -08008654 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8655 {
8656 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8658 __func__, enable_dfs_chan_scan);
8659 }
8660 if (0 == enable_11d || 1 == enable_11d)
8661 {
8662 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8663 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8664 __func__, enable_11d);
8665 }
8666
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008667 /* Note that the vos_preStart() sequence triggers the cfg download.
8668 The cfg download must occur before we update the SME config
8669 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008670 status = hdd_set_sme_config( pHddCtx );
8671
8672 if ( VOS_STATUS_SUCCESS != status )
8673 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008674 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308675 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008676 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008677
Jeff Johnson295189b2012-06-20 16:38:30 -07008678 /* In the integrated architecture we update the configuration from
8679 the INI file and from NV before vOSS has been started so that
8680 the final contents are available to send down to the cCPU */
8681
8682 // Apply the cfg.ini to cfg.dat
8683 if (FALSE == hdd_update_config_dat(pHddCtx))
8684 {
8685 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308686 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008687 }
8688
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308689 // Get mac addr from platform driver
8690 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8691
8692 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008693 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308694 /* Store the mac addr for first interface */
8695 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8696
8697 hddLog(VOS_TRACE_LEVEL_ERROR,
8698 "%s: WLAN Mac Addr: "
8699 MAC_ADDRESS_STR, __func__,
8700 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8701
8702 /* Here, passing Arg2 as 1 because we do not want to change the
8703 last 3 bytes (means non OUI bytes) of first interface mac
8704 addr.
8705 */
8706 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8707 {
8708 hddLog(VOS_TRACE_LEVEL_ERROR,
8709 "%s: Failed to generate wlan interface mac addr "
8710 "using MAC from ini file ", __func__);
8711 }
8712 }
8713 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8714 {
8715 // Apply the NV to cfg.dat
8716 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008717#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8718 /* There was not a valid set of MAC Addresses in NV. See if the
8719 default addresses were modified by the cfg.ini settings. If so,
8720 we'll use them, but if not, we'll autogenerate a set of MAC
8721 addresses based upon the device serial number */
8722
8723 static const v_MACADDR_t default_address =
8724 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008725
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308726 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8727 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 {
8729 /* cfg.ini has the default address, invoke autogen logic */
8730
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308731 /* Here, passing Arg2 as 0 because we want to change the
8732 last 3 bytes (means non OUI bytes) of all the interfaces
8733 mac addr.
8734 */
8735 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8736 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008737 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308738 hddLog(VOS_TRACE_LEVEL_ERROR,
8739 "%s: Failed to generate wlan interface mac addr "
8740 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8741 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008742 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008743 }
8744 else
8745#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8746 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008747 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008748 "%s: Invalid MAC address in NV, using MAC from ini file "
8749 MAC_ADDRESS_STR, __func__,
8750 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8751 }
8752 }
8753 {
8754 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308755
8756 /* Set the MAC Address Currently this is used by HAL to
8757 * add self sta. Remove this once self sta is added as
8758 * part of session open.
8759 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008760 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8761 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8762 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308763
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 if (!HAL_STATUS_SUCCESS( halStatus ))
8765 {
8766 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8767 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308768 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 }
8770 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008771
8772 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8773 Note: Firmware image will be read and downloaded inside vos_start API */
8774 status = vos_start( pHddCtx->pvosContext );
8775 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8776 {
8777 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308778 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008779 }
8780
Leo Chang6cec3e22014-01-21 15:33:49 -08008781#ifdef FEATURE_WLAN_CH_AVOID
8782 /* Plug in avoid channel notification callback
8783 * This should happen before ADD_SELF_STA
8784 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05308785
8786 /* check the Channel Avoidance is enabled */
8787 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
8788 {
8789 sme_AddChAvoidCallback(pHddCtx->hHal,
8790 hdd_hostapd_ch_avoid_cb);
8791 }
Leo Chang6cec3e22014-01-21 15:33:49 -08008792#endif /* FEATURE_WLAN_CH_AVOID */
8793
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008794 /* Exchange capability info between Host and FW and also get versioning info from FW */
8795 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008796
Agarwal Ashishad9281b2014-06-10 14:57:30 +05308797#ifdef CONFIG_ENABLE_LINUX_REG
8798 status = wlan_hdd_init_channels(pHddCtx);
8799 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8800 {
8801 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8802 __func__);
8803 goto err_vosstop;
8804 }
8805#endif
8806
Jeff Johnson295189b2012-06-20 16:38:30 -07008807 status = hdd_post_voss_start_config( pHddCtx );
8808 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8809 {
8810 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8811 __func__);
8812 goto err_vosstop;
8813 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008814
8815#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308816 wlan_hdd_cfg80211_update_reg_info( wiphy );
8817
8818 /* registration of wiphy dev with cfg80211 */
8819 if (0 > wlan_hdd_cfg80211_register(wiphy))
8820 {
8821 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8822 goto err_vosstop;
8823 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008824#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008825
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308826#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308827 /* registration of wiphy dev with cfg80211 */
8828 if (0 > wlan_hdd_cfg80211_register(wiphy))
8829 {
8830 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8831 goto err_vosstop;
8832 }
8833
8834 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8835 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8836 {
8837 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8838 __func__);
8839 goto err_unregister_wiphy;
8840 }
8841#endif
8842
Jeff Johnson295189b2012-06-20 16:38:30 -07008843 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8844 {
8845 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8846 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8847 }
8848 else
8849 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008850 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8851 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8852 if (pAdapter != NULL)
8853 {
kaidde69982014-06-18 13:23:21 +08008854 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] &= 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07008855 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308856 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8857 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8858 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008859
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308860 /* Generate the P2P Device Address. This consists of the device's
8861 * primary MAC address with the locally administered bit set.
8862 */
8863 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008864 }
8865 else
8866 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308867 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8868 if (p2p_dev_addr != NULL)
8869 {
8870 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8871 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8872 }
8873 else
8874 {
8875 hddLog(VOS_TRACE_LEVEL_FATAL,
8876 "%s: Failed to allocate mac_address for p2p_device",
8877 __func__);
8878 goto err_close_adapter;
8879 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008880 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008881
8882 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8883 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8884 if ( NULL == pP2pAdapter )
8885 {
8886 hddLog(VOS_TRACE_LEVEL_FATAL,
8887 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008888 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008889 goto err_close_adapter;
8890 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008891 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008892 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008893
8894 if( pAdapter == NULL )
8895 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008896 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8897 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008898 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008899
Arif Hussain66559122013-11-21 10:11:40 -08008900 if (country_code)
8901 {
8902 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008903 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008904 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8905#ifndef CONFIG_ENABLE_LINUX_REG
8906 hdd_checkandupdate_phymode(pAdapter, country_code);
8907#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008908 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8909 (void *)(tSmeChangeCountryCallback)
8910 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008911 country_code,
8912 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308913 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008914 if (eHAL_STATUS_SUCCESS == ret)
8915 {
Arif Hussaincb607082013-12-20 11:57:42 -08008916 ret = wait_for_completion_interruptible_timeout(
8917 &pAdapter->change_country_code,
8918 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8919
8920 if (0 >= ret)
8921 {
8922 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8923 "%s: SME while setting country code timed out", __func__);
8924 }
Arif Hussain66559122013-11-21 10:11:40 -08008925 }
8926 else
8927 {
Arif Hussaincb607082013-12-20 11:57:42 -08008928 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8929 "%s: SME Change Country code from module param fail ret=%d",
8930 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008931 }
8932 }
8933
Jeff Johnson295189b2012-06-20 16:38:30 -07008934#ifdef WLAN_BTAMP_FEATURE
8935 vStatus = WLANBAP_Open(pVosContext);
8936 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8937 {
8938 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8939 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008940 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008941 }
8942
8943 vStatus = BSL_Init(pVosContext);
8944 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8945 {
8946 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8947 "%s: Failed to Init BSL",__func__);
8948 goto err_bap_close;
8949 }
8950 vStatus = WLANBAP_Start(pVosContext);
8951 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8952 {
8953 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8954 "%s: Failed to start TL",__func__);
8955 goto err_bap_close;
8956 }
8957
8958 pConfig = pHddCtx->cfg_ini;
8959 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8960 status = WLANBAP_SetConfig(&btAmpConfig);
8961
8962#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008963
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008964#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8965 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8966 {
8967 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8968 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8969 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8970 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8971 }
8972#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008973
Agarwal Ashish4b87f922014-06-18 03:03:21 +05308974 wlan_hdd_tdls_init(pHddCtx);
8975
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308976 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8977
Jeff Johnson295189b2012-06-20 16:38:30 -07008978 /* Register with platform driver as client for Suspend/Resume */
8979 status = hddRegisterPmOps(pHddCtx);
8980 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8981 {
8982 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8983#ifdef WLAN_BTAMP_FEATURE
8984 goto err_bap_stop;
8985#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008986 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008987#endif //WLAN_BTAMP_FEATURE
8988 }
8989
Yue Ma0d4891e2013-08-06 17:01:45 -07008990 /* Open debugfs interface */
8991 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8992 {
8993 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8994 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008995 }
8996
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 /* Register TM level change handler function to the platform */
8998 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8999 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9000 {
9001 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9002 goto err_unregister_pmops;
9003 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009004
9005 /* register for riva power on lock to platform driver */
9006 if (req_riva_power_on_lock("wlan"))
9007 {
9008 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9009 __func__);
9010 goto err_unregister_pmops;
9011 }
9012
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 // register net device notifier for device change notification
9014 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9015
9016 if(ret < 0)
9017 {
9018 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9019 goto err_free_power_on_lock;
9020 }
9021
9022 //Initialize the nlink service
9023 if(nl_srv_init() != 0)
9024 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309025 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 goto err_reg_netdev;
9027 }
9028
Leo Chang4ce1cc52013-10-21 18:27:15 -07009029#ifdef WLAN_KD_READY_NOTIFIER
9030 pHddCtx->kd_nl_init = 1;
9031#endif /* WLAN_KD_READY_NOTIFIER */
9032
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 //Initialize the BTC service
9034 if(btc_activate_service(pHddCtx) != 0)
9035 {
9036 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9037 goto err_nl_srv;
9038 }
9039
9040#ifdef PTT_SOCK_SVC_ENABLE
9041 //Initialize the PTT service
9042 if(ptt_sock_activate_svc(pHddCtx) != 0)
9043 {
9044 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9045 goto err_nl_srv;
9046 }
9047#endif
9048
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309049#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9050 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9051 {
9052 if(wlan_logging_sock_activate_svc(
9053 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9054 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9055 {
9056 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9057 " failed", __func__);
9058 goto err_nl_srv;
9059 }
9060 }
9061#endif
9062
Jeff Johnson295189b2012-06-20 16:38:30 -07009063 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009064 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009065 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009066 /* Action frame registered in one adapter which will
9067 * applicable to all interfaces
9068 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309069 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009070 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009071
9072 mutex_init(&pHddCtx->sap_lock);
9073
Jeff Johnson295189b2012-06-20 16:38:30 -07009074
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009075#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009076#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9077 /* Initialize the wake lcok */
9078 wake_lock_init(&pHddCtx->rx_wake_lock,
9079 WAKE_LOCK_SUSPEND,
9080 "qcom_rx_wakelock");
9081#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009082 /* Initialize the wake lcok */
9083 wake_lock_init(&pHddCtx->sap_wake_lock,
9084 WAKE_LOCK_SUSPEND,
9085 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009086#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009087
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009088 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9089 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009090
Katya Nigam5c306ea2014-06-19 15:39:54 +05309091 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009092 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9093 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309094
9095#ifdef FEATURE_WLAN_SCAN_PNO
9096 /*SME must send channel update configuration to RIVA*/
9097 sme_UpdateChannelConfig(pHddCtx->hHal);
9098#endif
9099
Abhishek Singha306a442013-11-07 18:39:01 +05309100#ifndef CONFIG_ENABLE_LINUX_REG
9101 /*updating wiphy so that regulatory user hints can be processed*/
9102 if (wiphy)
9103 {
9104 regulatory_hint(wiphy, "00");
9105 }
9106#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009107 // Initialize the restart logic
9108 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309109
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009110 //Register the traffic monitor timer now
9111 if ( pHddCtx->cfg_ini->dynSplitscan)
9112 {
9113 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9114 VOS_TIMER_TYPE_SW,
9115 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9116 (void *)pHddCtx);
9117 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309118#ifdef WLAN_FEATURE_EXTSCAN
9119 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9120 wlan_hdd_cfg80211_extscan_callback,
9121 pHddCtx);
9122#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009123 goto success;
9124
9125err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009126#ifdef WLAN_KD_READY_NOTIFIER
9127 nl_srv_exit(pHddCtx->ptt_pid);
9128#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009129 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009130#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009131err_reg_netdev:
9132 unregister_netdevice_notifier(&hdd_netdev_notifier);
9133
9134err_free_power_on_lock:
9135 free_riva_power_on_lock("wlan");
9136
9137err_unregister_pmops:
9138 hddDevTmUnregisterNotifyCallback(pHddCtx);
9139 hddDeregisterPmOps(pHddCtx);
9140
Yue Ma0d4891e2013-08-06 17:01:45 -07009141 hdd_debugfs_exit(pHddCtx);
9142
Jeff Johnson295189b2012-06-20 16:38:30 -07009143#ifdef WLAN_BTAMP_FEATURE
9144err_bap_stop:
9145 WLANBAP_Stop(pVosContext);
9146#endif
9147
9148#ifdef WLAN_BTAMP_FEATURE
9149err_bap_close:
9150 WLANBAP_Close(pVosContext);
9151#endif
9152
Jeff Johnson295189b2012-06-20 16:38:30 -07009153err_close_adapter:
9154 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309155#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309156err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309157#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309158 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009159err_vosstop:
9160 vos_stop(pVosContext);
9161
Amar Singhala49cbc52013-10-08 18:37:44 -07009162err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 status = vos_sched_close( pVosContext );
9164 if (!VOS_IS_STATUS_SUCCESS(status)) {
9165 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9166 "%s: Failed to close VOSS Scheduler", __func__);
9167 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9168 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009169 vos_close(pVosContext );
9170
Amar Singhal0a402232013-10-11 20:57:16 -07009171err_vos_nv_close:
9172
c_hpothue6a36282014-03-19 12:27:38 +05309173#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009174 vos_nv_close();
9175
Jeff Johnson295189b2012-06-20 16:38:30 -07009176err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309177#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009178 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009179
9180err_wdclose:
9181 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9182 vos_watchdog_close(pVosContext);
9183
Jeff Johnson295189b2012-06-20 16:38:30 -07009184err_config:
9185 kfree(pHddCtx->cfg_ini);
9186 pHddCtx->cfg_ini= NULL;
9187
9188err_free_hdd_context:
9189 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009190 wiphy_free(wiphy) ;
9191 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 VOS_BUG(1);
9193
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009194 if (hdd_is_ssr_required())
9195 {
9196 /* WDI timeout had happened during load, so SSR is needed here */
9197 subsystem_restart("wcnss");
9198 msleep(5000);
9199 }
9200 hdd_set_ssr_required (VOS_FALSE);
9201
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009202 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009203
9204success:
9205 EXIT();
9206 return 0;
9207}
9208
9209/**---------------------------------------------------------------------------
9210
Jeff Johnson32d95a32012-09-10 13:15:23 -07009211 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009212
Jeff Johnson32d95a32012-09-10 13:15:23 -07009213 This is the driver entry point - called in different timeline depending
9214 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009215
9216 \param - None
9217
9218 \return - 0 for success, non zero for failure
9219
9220 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009221static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009222{
9223 VOS_STATUS status;
9224 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 struct device *dev = NULL;
9226 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009227#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9228 int max_retries = 0;
9229#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009230
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309231#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9232 wlan_logging_sock_init_svc();
9233#endif
9234
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 ENTER();
9236
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009237#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009239#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009240
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309241 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009242 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9243 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9244
9245 //Power Up Libra WLAN card first if not already powered up
9246 status = vos_chipPowerUp(NULL,NULL,NULL);
9247 if (!VOS_IS_STATUS_SUCCESS(status))
9248 {
9249 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9250 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309251#ifdef WLAN_OPEN_SOURCE
9252 wake_lock_destroy(&wlan_wake_lock);
9253#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309254
9255#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9256 wlan_logging_sock_deinit_svc();
9257#endif
9258
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009259 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 }
9261
Jeff Johnson295189b2012-06-20 16:38:30 -07009262#ifdef ANI_BUS_TYPE_PCI
9263
9264 dev = wcnss_wlan_get_device();
9265
9266#endif // ANI_BUS_TYPE_PCI
9267
9268#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009269
9270#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9271 /* wait until WCNSS driver downloads NV */
9272 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9273 msleep(1000);
9274 }
9275 if (max_retries >= 5) {
9276 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309277#ifdef WLAN_OPEN_SOURCE
9278 wake_lock_destroy(&wlan_wake_lock);
9279#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309280
9281#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9282 wlan_logging_sock_deinit_svc();
9283#endif
9284
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009285 return -ENODEV;
9286 }
9287#endif
9288
Jeff Johnson295189b2012-06-20 16:38:30 -07009289 dev = wcnss_wlan_get_device();
9290#endif // ANI_BUS_TYPE_PLATFORM
9291
9292
9293 do {
9294 if (NULL == dev) {
9295 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9296 ret_status = -1;
9297 break;
9298 }
9299
Jeff Johnson295189b2012-06-20 16:38:30 -07009300#ifdef TIMER_MANAGER
9301 vos_timer_manager_init();
9302#endif
9303
9304 /* Preopen VOSS so that it is ready to start at least SAL */
9305 status = vos_preOpen(&pVosContext);
9306
9307 if (!VOS_IS_STATUS_SUCCESS(status))
9308 {
9309 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9310 ret_status = -1;
9311 break;
9312 }
9313
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009314#ifndef MODULE
9315 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9316 */
9317 hdd_set_conparam((v_UINT_t)con_mode);
9318#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009319
9320 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009321 if (hdd_wlan_startup(dev))
9322 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009324 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009325 vos_preClose( &pVosContext );
9326 ret_status = -1;
9327 break;
9328 }
9329
9330 /* Cancel the vote for XO Core ON
9331 * This is done here for safety purposes in case we re-initialize without turning
9332 * it OFF in any error scenario.
9333 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009334 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009336 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009337 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9338 {
9339 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009340 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 }
9342 } while (0);
9343
9344 if (0 != ret_status)
9345 {
9346 //Assert Deep sleep signal now to put Libra HW in lowest power state
9347 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9348 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9349
9350 //Vote off any PMIC voltage supplies
9351 vos_chipPowerDown(NULL, NULL, NULL);
9352#ifdef TIMER_MANAGER
9353 vos_timer_exit();
9354#endif
9355#ifdef MEMORY_DEBUG
9356 vos_mem_exit();
9357#endif
9358
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009359#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009360 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009361#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309362
9363#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9364 wlan_logging_sock_deinit_svc();
9365#endif
9366
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9368 }
9369 else
9370 {
9371 //Send WLAN UP indication to Nlink Service
9372 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9373
9374 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 }
9376
9377 EXIT();
9378
9379 return ret_status;
9380}
9381
Jeff Johnson32d95a32012-09-10 13:15:23 -07009382/**---------------------------------------------------------------------------
9383
9384 \brief hdd_module_init() - Init Function
9385
9386 This is the driver entry point (invoked when module is loaded using insmod)
9387
9388 \param - None
9389
9390 \return - 0 for success, non zero for failure
9391
9392 --------------------------------------------------------------------------*/
9393#ifdef MODULE
9394static int __init hdd_module_init ( void)
9395{
9396 return hdd_driver_init();
9397}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009398#else /* #ifdef MODULE */
9399static int __init hdd_module_init ( void)
9400{
9401 /* Driver initialization is delayed to fwpath_changed_handler */
9402 return 0;
9403}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009404#endif /* #ifdef MODULE */
9405
Jeff Johnson295189b2012-06-20 16:38:30 -07009406
9407/**---------------------------------------------------------------------------
9408
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009409 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009410
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009411 This is the driver exit point (invoked when module is unloaded using rmmod
9412 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009413
9414 \param - None
9415
9416 \return - None
9417
9418 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009419static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009420{
9421 hdd_context_t *pHddCtx = NULL;
9422 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309423 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309424 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009425
9426 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9427
9428 //Get the global vos context
9429 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9430
9431 if(!pVosContext)
9432 {
9433 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9434 goto done;
9435 }
9436
9437 //Get the HDD context.
9438 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9439
9440 if(!pHddCtx)
9441 {
9442 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9443 }
9444 else
9445 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309446 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9447
9448 if (pHddCtx->isLogpInProgress)
9449 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309451 "%s:SSR in Progress; block rmmod !!!", __func__);
9452 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9453 msecs_to_jiffies(30000));
9454 if(!rc)
9455 {
9456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9457 "%s:SSR timedout, fatal error", __func__);
9458 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009459 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309460 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009461
Mihir Shete18156292014-03-11 15:38:30 +05309462 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009463 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9464
Agarwal Ashish8db39882014-07-30 21:56:07 +05309465 /* Driver Need to send country code 00 in below condition
9466 * 1) If gCountryCodePriority is set to 1; and last country
9467 * code set is through 11d. This needs to be done in case
9468 * when NV country code is 00.
9469 * This Needs to be done as when kernel store last country
9470 * code and if stored country code is not through 11d,
9471 * in sme_HandleChangeCountryCodeByUser we will disable 11d
9472 * in next load/unload as soon as we get any country through
9473 * 11d. In sme_HandleChangeCountryCodeByUser
9474 * pMsg->countryCode will be last countryCode and
9475 * pMac->scan.countryCode11d will be country through 11d so
9476 * due to mismatch driver will disable 11d.
9477 *
9478 * 2) When NV country Code is non-zero ;
9479 * There are chances that kernel last country and default
9480 * country can be same. In this case if Driver doesn't pass 00 to
9481 * kernel, at the time of driver loading next timer, driver will not
9482 * call any hint to kernel as country is same. This can add 3 sec
9483 * delay in driver loading.
9484 */
9485
9486 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309487 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Agarwal Ashish8db39882014-07-30 21:56:07 +05309488 sme_Is11dSupported(pHddCtx->hHal)) || (vos_is_nv_country_non_zero() ))
Agarwal Ashish5e414792014-06-08 15:25:23 +05309489 {
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309490 hddLog(VOS_TRACE_LEVEL_INFO,
9491 FL("CountryCode 00 is being set while unloading driver"));
Agarwal Ashish5e414792014-06-08 15:25:23 +05309492 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9493 }
9494
Jeff Johnson295189b2012-06-20 16:38:30 -07009495 //Do all the cleanup before deregistering the driver
9496 hdd_wlan_exit(pHddCtx);
9497 }
9498
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 vos_preClose( &pVosContext );
9500
9501#ifdef TIMER_MANAGER
9502 vos_timer_exit();
9503#endif
9504#ifdef MEMORY_DEBUG
9505 vos_mem_exit();
9506#endif
9507
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309508#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9509 wlan_logging_sock_deinit_svc();
9510#endif
9511
Jeff Johnson295189b2012-06-20 16:38:30 -07009512done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009513#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009515#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309516
Jeff Johnson295189b2012-06-20 16:38:30 -07009517 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9518}
9519
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009520/**---------------------------------------------------------------------------
9521
9522 \brief hdd_module_exit() - Exit function
9523
9524 This is the driver exit point (invoked when module is unloaded using rmmod)
9525
9526 \param - None
9527
9528 \return - None
9529
9530 --------------------------------------------------------------------------*/
9531static void __exit hdd_module_exit(void)
9532{
9533 hdd_driver_exit();
9534}
9535
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009536#ifdef MODULE
9537static int fwpath_changed_handler(const char *kmessage,
9538 struct kernel_param *kp)
9539{
Jeff Johnson76052702013-04-16 13:55:05 -07009540 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009541}
9542
9543static int con_mode_handler(const char *kmessage,
9544 struct kernel_param *kp)
9545{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009546 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009547}
9548#else /* #ifdef MODULE */
9549/**---------------------------------------------------------------------------
9550
Jeff Johnson76052702013-04-16 13:55:05 -07009551 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009552
Jeff Johnson76052702013-04-16 13:55:05 -07009553 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009554 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009555 - invoked when module parameter fwpath is modified from userspace to signal
9556 initializing the WLAN driver or when con_mode is modified from userspace
9557 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009558
9559 \return - 0 for success, non zero for failure
9560
9561 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009562static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009563{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009564 int ret_status;
9565
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009566 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009567 ret_status = hdd_driver_init();
9568 wlan_hdd_inited = ret_status ? 0 : 1;
9569 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009570 }
9571
9572 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009573
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009574 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009575
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009576 ret_status = hdd_driver_init();
9577 wlan_hdd_inited = ret_status ? 0 : 1;
9578 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009579}
9580
Jeff Johnson295189b2012-06-20 16:38:30 -07009581/**---------------------------------------------------------------------------
9582
Jeff Johnson76052702013-04-16 13:55:05 -07009583 \brief fwpath_changed_handler() - Handler Function
9584
9585 Handle changes to the fwpath parameter
9586
9587 \return - 0 for success, non zero for failure
9588
9589 --------------------------------------------------------------------------*/
9590static int fwpath_changed_handler(const char *kmessage,
9591 struct kernel_param *kp)
9592{
9593 int ret;
9594
9595 ret = param_set_copystring(kmessage, kp);
9596 if (0 == ret)
9597 ret = kickstart_driver();
9598 return ret;
9599}
9600
9601/**---------------------------------------------------------------------------
9602
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009603 \brief con_mode_handler() -
9604
9605 Handler function for module param con_mode when it is changed by userspace
9606 Dynamically linked - do nothing
9607 Statically linked - exit and init driver, as in rmmod and insmod
9608
Jeff Johnson76052702013-04-16 13:55:05 -07009609 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009610
Jeff Johnson76052702013-04-16 13:55:05 -07009611 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009612
9613 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009614static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009615{
Jeff Johnson76052702013-04-16 13:55:05 -07009616 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009617
Jeff Johnson76052702013-04-16 13:55:05 -07009618 ret = param_set_int(kmessage, kp);
9619 if (0 == ret)
9620 ret = kickstart_driver();
9621 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009622}
9623#endif /* #ifdef MODULE */
9624
9625/**---------------------------------------------------------------------------
9626
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 \brief hdd_get_conparam() -
9628
9629 This is the driver exit point (invoked when module is unloaded using rmmod)
9630
9631 \param - None
9632
9633 \return - tVOS_CON_MODE
9634
9635 --------------------------------------------------------------------------*/
9636tVOS_CON_MODE hdd_get_conparam ( void )
9637{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009638#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009640#else
9641 return (tVOS_CON_MODE)curr_con_mode;
9642#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009643}
9644void hdd_set_conparam ( v_UINT_t newParam )
9645{
9646 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009647#ifndef MODULE
9648 curr_con_mode = con_mode;
9649#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009650}
9651/**---------------------------------------------------------------------------
9652
9653 \brief hdd_softap_sta_deauth() - function
9654
9655 This to take counter measure to handle deauth req from HDD
9656
9657 \param - pAdapter - Pointer to the HDD
9658
9659 \param - enable - boolean value
9660
9661 \return - None
9662
9663 --------------------------------------------------------------------------*/
9664
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009665VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009666{
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009668 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009669
9670 ENTER();
9671
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009672 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9673 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009674
9675 //Ignore request to deauth bcmc station
9676 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009677 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009678
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009679 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009680
9681 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009682 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009683}
9684
9685/**---------------------------------------------------------------------------
9686
9687 \brief hdd_softap_sta_disassoc() - function
9688
9689 This to take counter measure to handle deauth req from HDD
9690
9691 \param - pAdapter - Pointer to the HDD
9692
9693 \param - enable - boolean value
9694
9695 \return - None
9696
9697 --------------------------------------------------------------------------*/
9698
9699void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9700{
9701 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9702
9703 ENTER();
9704
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309705 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009706
9707 //Ignore request to disassoc bcmc station
9708 if( pDestMacAddress[0] & 0x1 )
9709 return;
9710
9711 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9712}
9713
9714void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9715{
9716 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9717
9718 ENTER();
9719
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309720 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009721
9722 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9723}
9724
Jeff Johnson295189b2012-06-20 16:38:30 -07009725/**---------------------------------------------------------------------------
9726 *
9727 * \brief hdd_get__concurrency_mode() -
9728 *
9729 *
9730 * \param - None
9731 *
9732 * \return - CONCURRENCY MODE
9733 *
9734 * --------------------------------------------------------------------------*/
9735tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9736{
9737 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9738 hdd_context_t *pHddCtx;
9739
9740 if (NULL != pVosContext)
9741 {
9742 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9743 if (NULL != pHddCtx)
9744 {
9745 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9746 }
9747 }
9748
9749 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009750 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 return VOS_STA;
9752}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309753v_BOOL_t
9754wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
9755{
9756 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009757
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309758 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
9759 if (pAdapter == NULL)
9760 {
9761 hddLog(VOS_TRACE_LEVEL_INFO,
9762 FL("GO doesn't exist"));
9763 return TRUE;
9764 }
9765 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9766 {
9767 hddLog(VOS_TRACE_LEVEL_INFO,
9768 FL("GO started"));
9769 return TRUE;
9770 }
9771 else
9772 /* wait till GO changes its interface to p2p device */
9773 hddLog(VOS_TRACE_LEVEL_INFO,
9774 FL("Del_bss called, avoid apps suspend"));
9775 return FALSE;
9776
9777}
Jeff Johnson295189b2012-06-20 16:38:30 -07009778/* Decide whether to allow/not the apps power collapse.
9779 * Allow apps power collapse if we are in connected state.
9780 * if not, allow only if we are in IMPS */
9781v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9782{
9783 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009784 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009785 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9787 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9788 hdd_adapter_t *pAdapter = NULL;
9789 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009790 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009791
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9793 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009794
Yathish9f22e662012-12-10 14:21:35 -08009795 concurrent_state = hdd_get_concurrency_mode();
9796
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309797 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
9798 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
9799 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -08009800#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309801
Yathish9f22e662012-12-10 14:21:35 -08009802 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309803 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -08009804 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9805 return TRUE;
9806#endif
9807
Jeff Johnson295189b2012-06-20 16:38:30 -07009808 /*loop through all adapters. TBD fix for Concurrency */
9809 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9810 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9811 {
9812 pAdapter = pAdapterNode->pAdapter;
9813 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9814 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9815 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009816 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +05309817 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -08009818 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009819 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9820 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009822 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009823 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9824 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 return FALSE;
9826 }
9827 }
9828 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9829 pAdapterNode = pNext;
9830 }
9831 return TRUE;
9832}
9833
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009834/* Decides whether to send suspend notification to Riva
9835 * if any adapter is in BMPS; then it is required */
9836v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9837{
9838 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9839 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9840
9841 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9842 {
9843 return TRUE;
9844 }
9845 return FALSE;
9846}
9847
Jeff Johnson295189b2012-06-20 16:38:30 -07009848void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9849{
9850 switch(mode)
9851 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009852 case VOS_STA_MODE:
9853 case VOS_P2P_CLIENT_MODE:
9854 case VOS_P2P_GO_MODE:
9855 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009856 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309857 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 break;
9859 default:
9860 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309862 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9863 "Number of open sessions for mode %d = %d"),
9864 pHddCtx->concurrency_mode, mode,
9865 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009866}
9867
9868
9869void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9870{
9871 switch(mode)
9872 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009873 case VOS_STA_MODE:
9874 case VOS_P2P_CLIENT_MODE:
9875 case VOS_P2P_GO_MODE:
9876 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +05309877 pHddCtx->no_of_open_sessions[mode]--;
9878 if (!(pHddCtx->no_of_open_sessions[mode]))
9879 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 break;
9881 default:
9882 break;
9883 }
Agarwal Ashish51325b52014-06-16 16:50:49 +05309884 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
9885 "Number of open sessions for mode %d = %d"),
9886 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
9887
9888}
9889/**---------------------------------------------------------------------------
9890 *
9891 * \brief wlan_hdd_incr_active_session()
9892 *
9893 * This function increments the number of active sessions
9894 * maintained per device mode
9895 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
9896 * Incase of SAP/P2P GO upon bss start it is incremented
9897 *
9898 * \param pHddCtx - HDD Context
9899 * \param mode - device mode
9900 *
9901 * \return - None
9902 *
9903 * --------------------------------------------------------------------------*/
9904void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9905{
9906 switch (mode) {
9907 case VOS_STA_MODE:
9908 case VOS_P2P_CLIENT_MODE:
9909 case VOS_P2P_GO_MODE:
9910 case VOS_STA_SAP_MODE:
9911 pHddCtx->no_of_active_sessions[mode]++;
9912 break;
9913 default:
9914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
9915 break;
9916 }
9917 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
9918 mode,
9919 pHddCtx->no_of_active_sessions[mode]);
9920}
9921
9922/**---------------------------------------------------------------------------
9923 *
9924 * \brief wlan_hdd_decr_active_session()
9925 *
9926 * This function decrements the number of active sessions
9927 * maintained per device mode
9928 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
9929 * Incase of SAP/P2P GO upon bss stop it is decremented
9930 *
9931 * \param pHddCtx - HDD Context
9932 * \param mode - device mode
9933 *
9934 * \return - None
9935 *
9936 * --------------------------------------------------------------------------*/
9937void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9938{
9939 switch (mode) {
9940 case VOS_STA_MODE:
9941 case VOS_P2P_CLIENT_MODE:
9942 case VOS_P2P_GO_MODE:
9943 case VOS_STA_SAP_MODE:
9944 pHddCtx->no_of_active_sessions[mode]--;
9945 break;
9946 default:
9947 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
9948 break;
9949 }
9950 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
9951 mode,
9952 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -07009953}
9954
Jeff Johnsone7245742012-09-05 17:12:55 -07009955/**---------------------------------------------------------------------------
9956 *
9957 * \brief wlan_hdd_restart_init
9958 *
9959 * This function initalizes restart timer/flag. An internal function.
9960 *
9961 * \param - pHddCtx
9962 *
9963 * \return - None
9964 *
9965 * --------------------------------------------------------------------------*/
9966
9967static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9968{
9969 /* Initialize */
9970 pHddCtx->hdd_restart_retries = 0;
9971 atomic_set(&pHddCtx->isRestartInProgress, 0);
9972 vos_timer_init(&pHddCtx->hdd_restart_timer,
9973 VOS_TIMER_TYPE_SW,
9974 wlan_hdd_restart_timer_cb,
9975 pHddCtx);
9976}
9977/**---------------------------------------------------------------------------
9978 *
9979 * \brief wlan_hdd_restart_deinit
9980 *
9981 * This function cleans up the resources used. An internal function.
9982 *
9983 * \param - pHddCtx
9984 *
9985 * \return - None
9986 *
9987 * --------------------------------------------------------------------------*/
9988
9989static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9990{
9991
9992 VOS_STATUS vos_status;
9993 /* Block any further calls */
9994 atomic_set(&pHddCtx->isRestartInProgress, 1);
9995 /* Cleanup */
9996 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9997 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309998 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009999 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10000 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010001 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010002
10003}
10004
10005/**---------------------------------------------------------------------------
10006 *
10007 * \brief wlan_hdd_framework_restart
10008 *
10009 * This function uses a cfg80211 API to start a framework initiated WLAN
10010 * driver module unload/load.
10011 *
10012 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10013 *
10014 *
10015 * \param - pHddCtx
10016 *
10017 * \return - VOS_STATUS_SUCCESS: Success
10018 * VOS_STATUS_E_EMPTY: Adapter is Empty
10019 * VOS_STATUS_E_NOMEM: No memory
10020
10021 * --------------------------------------------------------------------------*/
10022
10023static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10024{
10025 VOS_STATUS status = VOS_STATUS_SUCCESS;
10026 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010027 int len = (sizeof (struct ieee80211_mgmt));
10028 struct ieee80211_mgmt *mgmt = NULL;
10029
10030 /* Prepare the DEAUTH managment frame with reason code */
10031 mgmt = kzalloc(len, GFP_KERNEL);
10032 if(mgmt == NULL)
10033 {
10034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10035 "%s: memory allocation failed (%d bytes)", __func__, len);
10036 return VOS_STATUS_E_NOMEM;
10037 }
10038 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010039
10040 /* Iterate over all adapters/devices */
10041 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10042 do
10043 {
10044 if( (status == VOS_STATUS_SUCCESS) &&
10045 pAdapterNode &&
10046 pAdapterNode->pAdapter)
10047 {
10048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10049 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10050 pAdapterNode->pAdapter->dev->name,
10051 pAdapterNode->pAdapter->device_mode,
10052 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010053 /*
10054 * CFG80211 event to restart the driver
10055 *
10056 * 'cfg80211_send_unprot_deauth' sends a
10057 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10058 * of SME(Linux Kernel) state machine.
10059 *
10060 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10061 * the driver.
10062 *
10063 */
10064
10065 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010066 }
10067 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10068 pAdapterNode = pNext;
10069 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10070
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010071
10072 /* Free the allocated management frame */
10073 kfree(mgmt);
10074
Jeff Johnsone7245742012-09-05 17:12:55 -070010075 /* Retry until we unload or reach max count */
10076 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10077 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10078
10079 return status;
10080
10081}
10082/**---------------------------------------------------------------------------
10083 *
10084 * \brief wlan_hdd_restart_timer_cb
10085 *
10086 * Restart timer callback. An internal function.
10087 *
10088 * \param - User data:
10089 *
10090 * \return - None
10091 *
10092 * --------------------------------------------------------------------------*/
10093
10094void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10095{
10096 hdd_context_t *pHddCtx = usrDataForCallback;
10097 wlan_hdd_framework_restart(pHddCtx);
10098 return;
10099
10100}
10101
10102
10103/**---------------------------------------------------------------------------
10104 *
10105 * \brief wlan_hdd_restart_driver
10106 *
10107 * This function sends an event to supplicant to restart the WLAN driver.
10108 *
10109 * This function is called from vos_wlanRestart.
10110 *
10111 * \param - pHddCtx
10112 *
10113 * \return - VOS_STATUS_SUCCESS: Success
10114 * VOS_STATUS_E_EMPTY: Adapter is Empty
10115 * VOS_STATUS_E_ALREADY: Request already in progress
10116
10117 * --------------------------------------------------------------------------*/
10118VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10119{
10120 VOS_STATUS status = VOS_STATUS_SUCCESS;
10121
10122 /* A tight check to make sure reentrancy */
10123 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10124 {
Mihir Shetefd528652014-06-23 19:07:50 +053010125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010126 "%s: WLAN restart is already in progress", __func__);
10127
10128 return VOS_STATUS_E_ALREADY;
10129 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010130 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010131#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010132 wcnss_reset_intr();
10133#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010134
Jeff Johnsone7245742012-09-05 17:12:55 -070010135 return status;
10136}
10137
Mihir Shetee1093ba2014-01-21 20:13:32 +053010138/**---------------------------------------------------------------------------
10139 *
10140 * \brief wlan_hdd_init_channels
10141 *
10142 * This function is used to initialize the channel list in CSR
10143 *
10144 * This function is called from hdd_wlan_startup
10145 *
10146 * \param - pHddCtx: HDD context
10147 *
10148 * \return - VOS_STATUS_SUCCESS: Success
10149 * VOS_STATUS_E_FAULT: Failure reported by SME
10150
10151 * --------------------------------------------------------------------------*/
10152static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10153{
10154 eHalStatus status;
10155
10156 status = sme_InitChannels(pHddCtx->hHal);
10157 if (HAL_STATUS_SUCCESS(status))
10158 {
10159 return VOS_STATUS_SUCCESS;
10160 }
10161 else
10162 {
10163 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10164 __func__, status);
10165 return VOS_STATUS_E_FAULT;
10166 }
10167}
10168
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010169static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
10170{
10171 eHalStatus status;
10172
10173 status = sme_InitChannelsForCC(pHddCtx->hHal);
10174 if (HAL_STATUS_SUCCESS(status))
10175 {
10176 return VOS_STATUS_SUCCESS;
10177 }
10178 else
10179 {
10180 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10181 __func__, status);
10182 return VOS_STATUS_E_FAULT;
10183 }
10184}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010185/*
10186 * API to find if there is any STA or P2P-Client is connected
10187 */
10188VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10189{
10190 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10191}
Jeff Johnsone7245742012-09-05 17:12:55 -070010192
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010193int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10194{
10195 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10196 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010197 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010198
10199 pScanInfo = &pHddCtx->scan_info;
10200 if (pScanInfo->mScanPending)
10201 {
10202 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10203 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10204 eCSR_SCAN_ABORT_DEFAULT);
10205
10206 status = wait_for_completion_interruptible_timeout(
10207 &pScanInfo->abortscan_event_var,
10208 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010209 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010210 {
10211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010212 "%s: Timeout or Interrupt occurred while waiting for abort"
10213 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010214 return -ETIMEDOUT;
10215 }
10216 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010217 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010218}
10219
Jeff Johnson295189b2012-06-20 16:38:30 -070010220//Register the module init/exit functions
10221module_init(hdd_module_init);
10222module_exit(hdd_module_exit);
10223
10224MODULE_LICENSE("Dual BSD/GPL");
10225MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10226MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10227
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010228module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10229 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010230
Jeff Johnson76052702013-04-16 13:55:05 -070010231module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010232 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010233
10234module_param(enable_dfs_chan_scan, int,
10235 S_IRUSR | S_IRGRP | S_IROTH);
10236
10237module_param(enable_11d, int,
10238 S_IRUSR | S_IRGRP | S_IROTH);
10239
10240module_param(country_code, charp,
10241 S_IRUSR | S_IRGRP | S_IROTH);