blob: 9efc8b21a2ec75dcf16df680d8b0344a8c790d74 [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 Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/*========================================================================
31
32 \file wlan_hdd_main.c
33
34 \brief WLAN Host Device Driver implementation
35
36 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
37
38 Qualcomm Confidential and Proprietary.
39
40 ========================================================================*/
41
42/**=========================================================================
43
44 EDIT HISTORY FOR FILE
45
46
47 This section contains comments describing changes made to the module.
48 Notice that changes are listed in reverse chronological order.
49
50
51 $Header:$ $DateTime: $ $Author: $
52
53
54 when who what, where, why
55 -------- --- --------------------------------------------------------
56 04/5/09 Shailender Created module.
57 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
58 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
59 ==========================================================================*/
60
61/*--------------------------------------------------------------------------
62 Include Files
63 ------------------------------------------------------------------------*/
64//#include <wlan_qct_driver.h>
65#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <vos_api.h>
67#include <vos_sched.h>
68#include <vos_power.h>
69#include <linux/etherdevice.h>
70#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070071#ifdef ANI_BUS_TYPE_PLATFORM
72#include <linux/wcnss_wlan.h>
73#endif //ANI_BUS_TYPE_PLATFORM
74#ifdef ANI_BUS_TYPE_PCI
75#include "wcnss_wlan.h"
76#endif /* ANI_BUS_TYPE_PCI */
77#include <wlan_hdd_tx_rx.h>
78#include <palTimer.h>
79#include <wniApi.h>
80#include <wlan_nlink_srv.h>
81#include <wlan_btc_svc.h>
82#include <wlan_hdd_cfg.h>
83#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053084#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070085#include <wlan_hdd_wowl.h>
86#include <wlan_hdd_misc.h>
87#include <wlan_hdd_wext.h>
88#ifdef WLAN_BTAMP_FEATURE
89#include <bap_hdd_main.h>
90#include <bapInternal.h>
91#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053092#include "wlan_hdd_trace.h"
93#include "vos_types.h"
94#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070095#include <linux/wireless.h>
96#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053097#include <linux/inetdevice.h>
98#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099#include "wlan_hdd_cfg80211.h"
100#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700101#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700102int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700103#include "sapApi.h"
104#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700105#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
107#include <soc/qcom/subsystem_restart.h>
108#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include <wlan_hdd_hostapd.h>
112#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "wlan_hdd_dev_pwr.h"
115#ifdef WLAN_BTAMP_FEATURE
116#include "bap_hdd_misc.h"
117#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700118#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800120#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530121#ifdef FEATURE_WLAN_TDLS
122#include "wlan_hdd_tdls.h"
123#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700124#include "wlan_hdd_debugfs.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
126#ifdef MODULE
127#define WLAN_MODULE_NAME module_name(THIS_MODULE)
128#else
129#define WLAN_MODULE_NAME "wlan"
130#endif
131
132#ifdef TIMER_MANAGER
133#define TIMER_MANAGER_STR " +TIMER_MANAGER"
134#else
135#define TIMER_MANAGER_STR ""
136#endif
137
138#ifdef MEMORY_DEBUG
139#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
140#else
141#define MEMORY_DEBUG_STR ""
142#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530143#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700144/* the Android framework expects this param even though we don't use it */
145#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700146static char fwpath_buffer[BUF_LEN];
147static struct kparam_string fwpath = {
148 .string = fwpath_buffer,
149 .maxlen = BUF_LEN,
150};
Arif Hussain66559122013-11-21 10:11:40 -0800151
152static char *country_code;
153static int enable_11d = -1;
154static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530155static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800156
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700158static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700159#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700160
Jeff Johnsone7245742012-09-05 17:12:55 -0700161/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800162 * spinlock for synchronizing asynchronous request/response
163 * (full description of use in wlan_hdd_main.h)
164 */
165DEFINE_SPINLOCK(hdd_context_lock);
166
167/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700168 * The rate at which the driver sends RESTART event to supplicant
169 * once the function 'vos_wlanRestart()' is called
170 *
171 */
172#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
173#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700174
175/*
176 * Size of Driver command strings from upper layer
177 */
178#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
179#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
180
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800181#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700182#define TID_MIN_VALUE 0
183#define TID_MAX_VALUE 15
184static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
185 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800186static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
187 tCsrEseBeaconReq *pEseBcnReq);
188#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700189
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +0530190static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx);
Atul Mittal1d722422014-03-19 11:15:07 +0530191/*
192 * Maximum buffer size used for returning the data back to user space
193 */
194#define WLAN_MAX_BUF_SIZE 1024
195#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700196/*
197 * Driver miracast parameters 0-Disabled
198 * 1-Source, 2-Sink
199 */
200#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0
201#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2
202
c_hpothu92367912014-05-01 15:18:17 +0530203//wait time for beacon miss rate.
204#define BCN_MISS_RATE_TIME 500
205
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800206#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700207static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700210static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700211
212//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700213static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
214static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
215static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
216void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800217void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700218
Jeff Johnson295189b2012-06-20 16:38:30 -0700219v_U16_t hdd_select_queue(struct net_device *dev,
220 struct sk_buff *skb);
221
222#ifdef WLAN_FEATURE_PACKET_FILTERING
223static void hdd_set_multicast_list(struct net_device *dev);
224#endif
225
226void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
227
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800228#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800229void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
230static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700231static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
232 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
233 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700234static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
235 tANI_U8 *pTargetApBssid,
236 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800237#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800238#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700239VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800240#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700241
Mihir Shetee1093ba2014-01-21 20:13:32 +0530242static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530243const char * hdd_device_modetoString(v_U8_t device_mode)
244{
245 switch(device_mode)
246 {
247 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
248 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
249 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
250 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
251 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
252 CASE_RETURN_STRING( WLAN_HDD_FTM );
253 CASE_RETURN_STRING( WLAN_HDD_IBSS );
254 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
255 default:
256 return "device_mode Unknown";
257 }
258}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530259
Jeff Johnson295189b2012-06-20 16:38:30 -0700260static int hdd_netdev_notifier_call(struct notifier_block * nb,
261 unsigned long state,
262 void *ndev)
263{
264 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700265 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700266 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700267#ifdef WLAN_BTAMP_FEATURE
268 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700269#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530270 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700271
272 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700274 (strncmp(dev->name, "p2p", 3)))
275 return NOTIFY_DONE;
276
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700278 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700279
Jeff Johnson27cee452013-03-27 11:10:24 -0700280 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800282 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700283 VOS_ASSERT(0);
284 return NOTIFY_DONE;
285 }
286
Jeff Johnson27cee452013-03-27 11:10:24 -0700287 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
288 if (NULL == pHddCtx)
289 {
290 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
291 VOS_ASSERT(0);
292 return NOTIFY_DONE;
293 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800294 if (pHddCtx->isLogpInProgress)
295 return NOTIFY_DONE;
296
Jeff Johnson27cee452013-03-27 11:10:24 -0700297
298 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
299 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700300
301 switch (state) {
302 case NETDEV_REGISTER:
303 break;
304
305 case NETDEV_UNREGISTER:
306 break;
307
308 case NETDEV_UP:
309 break;
310
311 case NETDEV_DOWN:
312 break;
313
314 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700315 if(TRUE == pAdapter->isLinkUpSvcNeeded)
316 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700317 break;
318
319 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530320 result = wlan_hdd_scan_abort(pAdapter);
321 if (result <= 0)
322 {
323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
324 "%s: Timeout occurred while waiting for abortscan %ld",
325 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 }
327 else
328 {
329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530330 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700331 }
332#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700334 status = WLANBAP_StopAmp();
335 if(VOS_STATUS_SUCCESS != status )
336 {
337 pHddCtx->isAmpAllowed = VOS_TRUE;
338 hddLog(VOS_TRACE_LEVEL_FATAL,
339 "%s: Failed to stop AMP", __func__);
340 }
341 else
342 {
343 //a state m/c implementation in PAL is TBD to avoid this delay
344 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700345 if ( pHddCtx->isAmpAllowed )
346 {
347 WLANBAP_DeregisterFromHCI();
348 pHddCtx->isAmpAllowed = VOS_FALSE;
349 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 }
351#endif //WLAN_BTAMP_FEATURE
352 break;
353
354 default:
355 break;
356 }
357
358 return NOTIFY_DONE;
359}
360
361struct notifier_block hdd_netdev_notifier = {
362 .notifier_call = hdd_netdev_notifier_call,
363};
364
365/*---------------------------------------------------------------------------
366 * Function definitions
367 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700368void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
369void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700371static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700372#ifndef MODULE
373/* current con_mode - used only for statically linked driver
374 * con_mode is changed by userspace to indicate a mode change which will
375 * result in calling the module exit and init functions. The module
376 * exit function will clean up based on the value of con_mode prior to it
377 * being changed by userspace. So curr_con_mode records the current con_mode
378 * for exit when con_mode becomes the next mode for init
379 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700380static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700381#endif
382
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800383/**---------------------------------------------------------------------------
384
385 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
386
387 Called immediately after the cfg.ini is read in order to configure
388 the desired trace levels.
389
390 \param - moduleId - module whose trace level is being configured
391 \param - bitmask - bitmask of log levels to be enabled
392
393 \return - void
394
395 --------------------------------------------------------------------------*/
396static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
397{
398 wpt_tracelevel level;
399
400 /* if the bitmask is the default value, then a bitmask was not
401 specified in cfg.ini, so leave the logging level alone (it
402 will remain at the "compiled in" default value) */
403 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
404 {
405 return;
406 }
407
408 /* a mask was specified. start by disabling all logging */
409 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
410
411 /* now cycle through the bitmask until all "set" bits are serviced */
412 level = VOS_TRACE_LEVEL_FATAL;
413 while (0 != bitmask)
414 {
415 if (bitmask & 1)
416 {
417 vos_trace_setValue(moduleId, level, 1);
418 }
419 level++;
420 bitmask >>= 1;
421 }
422}
423
424
Jeff Johnson295189b2012-06-20 16:38:30 -0700425/**---------------------------------------------------------------------------
426
427 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
428
429 Called immediately after the cfg.ini is read in order to configure
430 the desired trace levels in the WDI.
431
432 \param - moduleId - module whose trace level is being configured
433 \param - bitmask - bitmask of log levels to be enabled
434
435 \return - void
436
437 --------------------------------------------------------------------------*/
438static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
439{
440 wpt_tracelevel level;
441
442 /* if the bitmask is the default value, then a bitmask was not
443 specified in cfg.ini, so leave the logging level alone (it
444 will remain at the "compiled in" default value) */
445 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
446 {
447 return;
448 }
449
450 /* a mask was specified. start by disabling all logging */
451 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
452
453 /* now cycle through the bitmask until all "set" bits are serviced */
454 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
455 while (0 != bitmask)
456 {
457 if (bitmask & 1)
458 {
459 wpalTraceSetLevel(moduleId, level, 1);
460 }
461 level++;
462 bitmask >>= 1;
463 }
464}
Jeff Johnson295189b2012-06-20 16:38:30 -0700465
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530466/*
467 * FUNCTION: wlan_hdd_validate_context
468 * This function is used to check the HDD context
469 */
470int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
471{
472 ENTER();
473
474 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
475 {
476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
477 "%s: HDD context is Null", __func__);
478 return -ENODEV;
479 }
480
481 if (pHddCtx->isLogpInProgress)
482 {
483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
484 "%s: LOGP in Progress. Ignore!!!", __func__);
485 return -EAGAIN;
486 }
487
Mihir Shete18156292014-03-11 15:38:30 +0530488 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530489 {
490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
491 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
492 return -EAGAIN;
493 }
494 return 0;
495}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700496#ifdef CONFIG_ENABLE_LINUX_REG
497void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
498{
499 hdd_adapter_t *pAdapter = NULL;
500 hdd_station_ctx_t *pHddStaCtx = NULL;
501 eCsrPhyMode phyMode;
502 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530503
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700504 if (NULL == pHddCtx)
505 {
506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
507 "HDD Context is null !!");
508 return ;
509 }
510
511 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
512 if (NULL == pAdapter)
513 {
514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
515 "pAdapter is null !!");
516 return ;
517 }
518
519 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
520 if (NULL == pHddStaCtx)
521 {
522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
523 "pHddStaCtx is null !!");
524 return ;
525 }
526
527 cfg_param = pHddCtx->cfg_ini;
528 if (NULL == cfg_param)
529 {
530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
531 "cfg_params not available !!");
532 return ;
533 }
534
535 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
536
537 if (!pHddCtx->isVHT80Allowed)
538 {
539 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
540 (eCSR_DOT11_MODE_11ac == phyMode) ||
541 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
542 {
543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
544 "Setting phymode to 11n!!");
545 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
546 }
547 }
548 else
549 {
550 /*New country Supports 11ac as well resetting value back from .ini*/
551 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
552 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
553 return ;
554 }
555
556 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
557 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
558 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
559 {
560 VOS_STATUS vosStatus;
561
562 // need to issue a disconnect to CSR.
563 INIT_COMPLETION(pAdapter->disconnect_comp_var);
564 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
565 pAdapter->sessionId,
566 eCSR_DISCONNECT_REASON_UNSPECIFIED );
567
568 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530569 {
570 long ret;
571
572 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700573 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530574 if (0 >= ret)
575 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
576 ret);
577 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700578
579 }
580}
581#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530582void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
583{
584 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
585 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
586 hdd_config_t *cfg_param;
587 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530588 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530589
590 if (NULL == pHddCtx)
591 {
592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
593 "HDD Context is null !!");
594 return ;
595 }
596
597 cfg_param = pHddCtx->cfg_ini;
598
599 if (NULL == cfg_param)
600 {
601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
602 "cfg_params not available !!");
603 return ;
604 }
605
606 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
607
608 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
609 {
610 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
611 (eCSR_DOT11_MODE_11ac == phyMode) ||
612 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
613 {
614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
615 "Setting phymode to 11n!!");
616 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
617 }
618 }
619 else
620 {
621 /*New country Supports 11ac as well resetting value back from .ini*/
622 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
623 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
624 return ;
625 }
626
627 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
628 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
629 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
630 {
631 VOS_STATUS vosStatus;
632
633 // need to issue a disconnect to CSR.
634 INIT_COMPLETION(pAdapter->disconnect_comp_var);
635 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
636 pAdapter->sessionId,
637 eCSR_DISCONNECT_REASON_UNSPECIFIED );
638
639 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530640 {
641 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530642 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530643 if (ret <= 0)
644 {
645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
646 "wait on disconnect_comp_var is failed %ld", ret);
647 }
648 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530649
650 }
651}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700652#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530653
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700654void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
655{
656 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
657 hdd_config_t *cfg_param;
658
659 if (NULL == pHddCtx)
660 {
661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
662 "HDD Context is null !!");
663 return ;
664 }
665
666 cfg_param = pHddCtx->cfg_ini;
667
668 if (NULL == cfg_param)
669 {
670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
671 "cfg_params not available !!");
672 return ;
673 }
674
675 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code))
676 {
677 /*New country doesn't support DFS */
678 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
679 }
680 else
681 {
682 /*New country Supports DFS as well resetting value back from .ini*/
683 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
684 }
685
686}
687
Rajeev79dbe4c2013-10-05 11:03:42 +0530688#ifdef FEATURE_WLAN_BATCH_SCAN
689
690/**---------------------------------------------------------------------------
691
692 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
693 input string
694
695 This function extracts assigned integer from string in below format:
696 "STRING=10" : extracts integer 10 from this string
697
698 \param - pInPtr Pointer to input string
699 \param - base Base for string to int conversion(10 for decimal 16 for hex)
700 \param - pOutPtr Pointer to variable in which extracted integer needs to be
701 assigned
702 \param - pLastArg to tell whether it is last arguement in input string or
703 not
704
705 \return - NULL for failure cases
706 pointer to next arguement in input string for success cases
707 --------------------------------------------------------------------------*/
708static tANI_U8 *
709hdd_extract_assigned_int_from_str
710(
711 tANI_U8 *pInPtr,
712 tANI_U8 base,
713 tANI_U32 *pOutPtr,
714 tANI_U8 *pLastArg
715)
716{
717 int tempInt;
718 int v = 0;
719 char buf[32];
720 int val = 0;
721 *pLastArg = FALSE;
722
723 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
724 if (NULL == pInPtr)
725 {
726 return NULL;
727 }
728
729 pInPtr++;
730
731 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
732
733 val = sscanf(pInPtr, "%32s ", buf);
734 if (val < 0 && val > strlen(pInPtr))
735 {
736 return NULL;
737 }
738 pInPtr += val;
739 v = kstrtos32(buf, base, &tempInt);
740 if (v < 0)
741 {
742 return NULL;
743 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800744 if (tempInt < 0)
745 {
746 tempInt = 0;
747 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530748 *pOutPtr = tempInt;
749
750 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
751 if (NULL == pInPtr)
752 {
753 *pLastArg = TRUE;
754 return NULL;
755 }
756 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
757
758 return pInPtr;
759}
760
761/**---------------------------------------------------------------------------
762
763 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
764 input string
765
766 This function extracts assigned character from string in below format:
767 "STRING=A" : extracts char 'A' from this string
768
769 \param - pInPtr Pointer to input string
770 \param - pOutPtr Pointer to variable in which extracted char needs to be
771 assigned
772 \param - pLastArg to tell whether it is last arguement in input string or
773 not
774
775 \return - NULL for failure cases
776 pointer to next arguement in input string for success cases
777 --------------------------------------------------------------------------*/
778static tANI_U8 *
779hdd_extract_assigned_char_from_str
780(
781 tANI_U8 *pInPtr,
782 tANI_U8 *pOutPtr,
783 tANI_U8 *pLastArg
784)
785{
786 *pLastArg = FALSE;
787
788 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
789 if (NULL == pInPtr)
790 {
791 return NULL;
792 }
793
794 pInPtr++;
795
796 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
797
798 *pOutPtr = *pInPtr;
799
800 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
801 if (NULL == pInPtr)
802 {
803 *pLastArg = TRUE;
804 return NULL;
805 }
806 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
807
808 return pInPtr;
809}
810
811
812/**---------------------------------------------------------------------------
813
814 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
815
816 This function parses set batch scan command in below format:
817 WLS_BATCHING_SET <space> followed by below arguements
818 "SCANFREQ=XX" : Optional defaults to 30 sec
819 "MSCAN=XX" : Required number of scans to attempt to batch
820 "BESTN=XX" : Best Network (RSSI) defaults to 16
821 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
822 A. implies only 5 GHz , B. implies only 2.4GHz
823 "RTT=X" : optional defaults to 0
824 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
825 error
826
827 For example input commands:
828 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
829 translated into set batch scan with following parameters:
830 a) Frequence 60 seconds
831 b) Batch 10 scans together
832 c) Best RSSI to be 20
833 d) 5GHz band only
834 e) RTT is equal to 0
835
836 \param - pValue Pointer to input channel list
837 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
838
839 \return - 0 for success non-zero for failure
840
841 --------------------------------------------------------------------------*/
842static int
843hdd_parse_set_batchscan_command
844(
845 tANI_U8 *pValue,
846 tSirSetBatchScanReq *pHddSetBatchScanReq
847)
848{
849 tANI_U8 *inPtr = pValue;
850 tANI_U8 val = 0;
851 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800852 tANI_U32 nScanFreq;
853 tANI_U32 nMscan;
854 tANI_U32 nBestN;
855 tANI_U8 ucRfBand;
856 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800857 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530858
859 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800860 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
861 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
862 nRtt = 0;
863 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530864
865 /*go to space after WLS_BATCHING_SET command*/
866 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
867 /*no argument after the command*/
868 if (NULL == inPtr)
869 {
870 return -EINVAL;
871 }
872
873 /*no space after the command*/
874 else if (SPACE_ASCII_VALUE != *inPtr)
875 {
876 return -EINVAL;
877 }
878
879 /*removing empty spaces*/
880 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
881
882 /*no argument followed by spaces*/
883 if ('\0' == *inPtr)
884 {
885 return -EINVAL;
886 }
887
888 /*check and parse SCANFREQ*/
889 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
890 {
891 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800892 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800893
Rajeev Kumarc933d982013-11-18 20:04:20 -0800894 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800895 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800896 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800897 }
898
Rajeev79dbe4c2013-10-05 11:03:42 +0530899 if ( (NULL == inPtr) || (TRUE == lastArg))
900 {
901 return -EINVAL;
902 }
903 }
904
905 /*check and parse MSCAN*/
906 if ((strncmp(inPtr, "MSCAN", 5) == 0))
907 {
908 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800909 &nMscan, &lastArg);
910
911 if (0 == nMscan)
912 {
913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
914 "invalid MSCAN=%d", nMscan);
915 return -EINVAL;
916 }
917
Rajeev79dbe4c2013-10-05 11:03:42 +0530918 if (TRUE == lastArg)
919 {
920 goto done;
921 }
922 else if (NULL == inPtr)
923 {
924 return -EINVAL;
925 }
926 }
927 else
928 {
929 return -EINVAL;
930 }
931
932 /*check and parse BESTN*/
933 if ((strncmp(inPtr, "BESTN", 5) == 0))
934 {
935 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800936 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800937
Rajeev Kumarc933d982013-11-18 20:04:20 -0800938 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800939 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800940 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800941 }
942
Rajeev79dbe4c2013-10-05 11:03:42 +0530943 if (TRUE == lastArg)
944 {
945 goto done;
946 }
947 else if (NULL == inPtr)
948 {
949 return -EINVAL;
950 }
951 }
952
953 /*check and parse CHANNEL*/
954 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
955 {
956 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800957
Rajeev79dbe4c2013-10-05 11:03:42 +0530958 if (('A' == val) || ('a' == val))
959 {
c_hpothuebf89732014-02-25 13:00:24 +0530960 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530961 }
962 else if (('B' == val) || ('b' == val))
963 {
c_hpothuebf89732014-02-25 13:00:24 +0530964 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530965 }
966 else
967 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800968 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
969 }
970
971 if (TRUE == lastArg)
972 {
973 goto done;
974 }
975 else if (NULL == inPtr)
976 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530977 return -EINVAL;
978 }
979 }
980
981 /*check and parse RTT*/
982 if ((strncmp(inPtr, "RTT", 3) == 0))
983 {
984 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800985 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530986 if (TRUE == lastArg)
987 {
988 goto done;
989 }
990 if (NULL == inPtr)
991 {
992 return -EINVAL;
993 }
994 }
995
996
997done:
998
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800999 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1000 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1001 pHddSetBatchScanReq->bestNetwork = nBestN;
1002 pHddSetBatchScanReq->rfBand = ucRfBand;
1003 pHddSetBatchScanReq->rtt = nRtt;
1004
Rajeev79dbe4c2013-10-05 11:03:42 +05301005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1006 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1007 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1008 pHddSetBatchScanReq->scanFrequency,
1009 pHddSetBatchScanReq->numberOfScansToBatch,
1010 pHddSetBatchScanReq->bestNetwork,
1011 pHddSetBatchScanReq->rfBand,
1012 pHddSetBatchScanReq->rtt);
1013
1014 return 0;
1015}/*End of hdd_parse_set_batchscan_command*/
1016
1017/**---------------------------------------------------------------------------
1018
1019 \brief hdd_set_batch_scan_req_callback () - This function is called after
1020 receiving set batch scan response from FW and it saves set batch scan
1021 response data FW to HDD context and sets the completion event on
1022 which hdd_ioctl is waiting
1023
1024 \param - callbackContext Pointer to HDD adapter
1025 \param - pRsp Pointer to set batch scan response data received from FW
1026
1027 \return - nothing
1028
1029 --------------------------------------------------------------------------*/
1030static void hdd_set_batch_scan_req_callback
1031(
1032 void *callbackContext,
1033 tSirSetBatchScanRsp *pRsp
1034)
1035{
1036 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1037 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1038
1039 /*sanity check*/
1040 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1041 {
1042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1043 "%s: Invalid pAdapter magic", __func__);
1044 VOS_ASSERT(0);
1045 return;
1046 }
1047 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1048
1049 /*save set batch scan response*/
1050 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1051
1052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1053 "Received set batch scan rsp from FW with nScansToBatch=%d",
1054 pHddSetBatchScanRsp->nScansToBatch);
1055
1056 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1057 complete(&pAdapter->hdd_set_batch_scan_req_var);
1058
1059 return;
1060}/*End of hdd_set_batch_scan_req_callback*/
1061
1062
1063/**---------------------------------------------------------------------------
1064
1065 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1066 info in hdd batch scan response queue
1067
1068 \param - pAdapter Pointer to hdd adapter
1069 \param - pAPMetaInfo Pointer to access point meta info
1070 \param - scanId scan ID of batch scan response
1071 \param - isLastAp tells whether AP is last AP in batch scan response or not
1072
1073 \return - nothing
1074
1075 --------------------------------------------------------------------------*/
1076static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1077 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1078{
1079 tHddBatchScanRsp *pHead;
1080 tHddBatchScanRsp *pNode;
1081 tHddBatchScanRsp *pPrev;
1082 tHddBatchScanRsp *pTemp;
1083 tANI_U8 ssidLen;
1084
1085 /*head of hdd batch scan response queue*/
1086 pHead = pAdapter->pBatchScanRsp;
1087
1088 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1089 if (NULL == pNode)
1090 {
1091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1092 "%s: Could not allocate memory", __func__);
1093 VOS_ASSERT(0);
1094 return;
1095 }
1096
1097 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1098 sizeof(pNode->ApInfo.bssid));
1099 ssidLen = strlen(pApMetaInfo->ssid);
1100 if (SIR_MAX_SSID_SIZE < ssidLen)
1101 {
1102 /*invalid scan result*/
1103 vos_mem_free(pNode);
1104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1105 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1106 return;
1107 }
1108 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1109 /*null terminate ssid*/
1110 pNode->ApInfo.ssid[ssidLen] = '\0';
1111 pNode->ApInfo.ch = pApMetaInfo->ch;
1112 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1113 pNode->ApInfo.age = pApMetaInfo->timestamp;
1114 pNode->ApInfo.batchId = scanId;
1115 pNode->ApInfo.isLastAp = isLastAp;
1116
1117 pNode->pNext = NULL;
1118 if (NULL == pHead)
1119 {
1120 pAdapter->pBatchScanRsp = pNode;
1121 }
1122 else
1123 {
1124 pTemp = pHead;
1125 while (NULL != pTemp)
1126 {
1127 pPrev = pTemp;
1128 pTemp = pTemp->pNext;
1129 }
1130 pPrev->pNext = pNode;
1131 }
1132
1133 return;
1134}/*End of hdd_populate_batch_scan_rsp_queue*/
1135
1136/**---------------------------------------------------------------------------
1137
1138 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1139 receiving batch scan response indication from FW. It saves get batch scan
1140 response data in HDD batch scan response queue. This callback sets the
1141 completion event on which hdd_ioctl is waiting only after getting complete
1142 batch scan response data from FW
1143
1144 \param - callbackContext Pointer to HDD adapter
1145 \param - pRsp Pointer to get batch scan response data received from FW
1146
1147 \return - nothing
1148
1149 --------------------------------------------------------------------------*/
1150static void hdd_batch_scan_result_ind_callback
1151(
1152 void *callbackContext,
1153 void *pRsp
1154)
1155{
1156 v_BOOL_t isLastAp;
1157 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001158 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301159 tANI_U32 numberScanList;
1160 tANI_U32 nextScanListOffset;
1161 tANI_U32 nextApMetaInfoOffset;
1162 hdd_adapter_t* pAdapter;
1163 tpSirBatchScanList pScanList;
1164 tpSirBatchScanNetworkInfo pApMetaInfo;
1165 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1166 tSirSetBatchScanReq *pReq;
1167
1168 pAdapter = (hdd_adapter_t *)callbackContext;
1169 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001170 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301171 {
1172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1173 "%s: Invalid pAdapter magic", __func__);
1174 VOS_ASSERT(0);
1175 return;
1176 }
1177
1178 /*initialize locals*/
1179 pReq = &pAdapter->hddSetBatchScanReq;
1180 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1181 isLastAp = FALSE;
1182 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001183 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301184 numberScanList = 0;
1185 nextScanListOffset = 0;
1186 nextApMetaInfoOffset = 0;
1187 pScanList = NULL;
1188 pApMetaInfo = NULL;
1189
1190 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1191 {
1192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1193 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1194 isLastAp = TRUE;
1195 goto done;
1196 }
1197
1198 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1200 "Batch scan rsp: numberScalList %d", numberScanList);
1201
1202 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1203 {
1204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1205 "%s: numberScanList %d", __func__, numberScanList);
1206 isLastAp = TRUE;
1207 goto done;
1208 }
1209
1210 while (numberScanList)
1211 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001212 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301213 nextScanListOffset);
1214 if (NULL == pScanList)
1215 {
1216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1217 "%s: pScanList is %p", __func__, pScanList);
1218 isLastAp = TRUE;
1219 goto done;
1220 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001221 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001223 "Batch scan rsp: numApMetaInfo %d scanId %d",
1224 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301225
1226 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1227 {
1228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1229 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1230 isLastAp = TRUE;
1231 goto done;
1232 }
1233
Rajeev Kumarce651e42013-10-21 18:57:15 -07001234 /*Initialize next AP meta info offset for next scan list*/
1235 nextApMetaInfoOffset = 0;
1236
Rajeev79dbe4c2013-10-05 11:03:42 +05301237 while (numApMetaInfo)
1238 {
1239 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1240 nextApMetaInfoOffset);
1241 if (NULL == pApMetaInfo)
1242 {
1243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1244 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1245 isLastAp = TRUE;
1246 goto done;
1247 }
1248 /*calculate AP age*/
1249 pApMetaInfo->timestamp =
1250 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1251
1252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001253 "%s: bssId "MAC_ADDRESS_STR
1254 " ch %d rssi %d timestamp %d", __func__,
1255 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1256 pApMetaInfo->ch, pApMetaInfo->rssi,
1257 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301258
1259 /*mark last AP in batch scan response*/
1260 if ((TRUE == pBatchScanRsp->isLastResult) &&
1261 (1 == numberScanList) && (1 == numApMetaInfo))
1262 {
1263 isLastAp = TRUE;
1264 }
1265
1266 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1267 /*store batch scan repsonse in hdd queue*/
1268 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1269 pScanList->scanId, isLastAp);
1270 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1271
1272 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1273 numApMetaInfo--;
1274 }
1275
Rajeev Kumarce651e42013-10-21 18:57:15 -07001276 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1277 + (sizeof(tSirBatchScanNetworkInfo)
1278 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301279 numberScanList--;
1280 }
1281
1282done:
1283
1284 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1285 requested from hdd_ioctl*/
1286 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1287 (TRUE == isLastAp))
1288 {
1289 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1290 complete(&pAdapter->hdd_get_batch_scan_req_var);
1291 }
1292
1293 return;
1294}/*End of hdd_batch_scan_result_ind_callback*/
1295
1296/**---------------------------------------------------------------------------
1297
1298 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1299 response as per batch scan FR request format by putting proper markers
1300
1301 \param - pDest pointer to destination buffer
1302 \param - cur_len current length
1303 \param - tot_len total remaining size which can be written to user space
1304 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1305 \param - pAdapter Pointer to HDD adapter
1306
1307 \return - ret no of characters written
1308
1309 --------------------------------------------------------------------------*/
1310static tANI_U32
1311hdd_format_batch_scan_rsp
1312(
1313 tANI_U8 *pDest,
1314 tANI_U32 cur_len,
1315 tANI_U32 tot_len,
1316 tHddBatchScanRsp *pApMetaInfo,
1317 hdd_adapter_t* pAdapter
1318)
1319{
1320 tANI_U32 ret = 0;
1321 tANI_U32 rem_len = 0;
1322 tANI_U8 temp_len = 0;
1323 tANI_U8 temp_total_len = 0;
1324 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1325 tANI_U8 *pTemp = temp;
1326
1327 /*Batch scan reponse needs to be returned to user space in
1328 following format:
1329 "scancount=X\n" where X is the number of scans in current batch
1330 batch
1331 "trunc\n" optional present if current scan truncated
1332 "bssid=XX:XX:XX:XX:XX:XX\n"
1333 "ssid=XXXX\n"
1334 "freq=X\n" frequency in Mhz
1335 "level=XX\n"
1336 "age=X\n" ms
1337 "dist=X\n" cm (-1 if not available)
1338 "errror=X\n" (-1if not available)
1339 "====\n" (end of ap marker)
1340 "####\n" (end of scan marker)
1341 "----\n" (end of results)*/
1342 /*send scan result in above format to user space based on
1343 available length*/
1344 /*The GET response may have more data than the driver can return in its
1345 buffer. In that case the buffer should be filled to the nearest complete
1346 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1347 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1348 The final buffer should end with "----\n"*/
1349
1350 /*sanity*/
1351 if (cur_len > tot_len)
1352 {
1353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1354 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1355 return 0;
1356 }
1357 else
1358 {
1359 rem_len = (tot_len - cur_len);
1360 }
1361
1362 /*end scan marker*/
1363 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1364 {
1365 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1366 pTemp += temp_len;
1367 temp_total_len += temp_len;
1368 }
1369
1370 /*bssid*/
1371 temp_len = snprintf(pTemp, sizeof(temp),
1372 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1373 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1374 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1375 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1376 pTemp += temp_len;
1377 temp_total_len += temp_len;
1378
1379 /*ssid*/
1380 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1381 pApMetaInfo->ApInfo.ssid);
1382 pTemp += temp_len;
1383 temp_total_len += temp_len;
1384
1385 /*freq*/
1386 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001387 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301388 pTemp += temp_len;
1389 temp_total_len += temp_len;
1390
1391 /*level*/
1392 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1393 pApMetaInfo->ApInfo.rssi);
1394 pTemp += temp_len;
1395 temp_total_len += temp_len;
1396
1397 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001398 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301399 pApMetaInfo->ApInfo.age);
1400 pTemp += temp_len;
1401 temp_total_len += temp_len;
1402
1403 /*dist*/
1404 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1405 pTemp += temp_len;
1406 temp_total_len += temp_len;
1407
1408 /*error*/
1409 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1410 pTemp += temp_len;
1411 temp_total_len += temp_len;
1412
1413 /*end AP marker*/
1414 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1415 pTemp += temp_len;
1416 temp_total_len += temp_len;
1417
1418 /*last AP in batch scan response*/
1419 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1420 {
1421 /*end scan marker*/
1422 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1423 pTemp += temp_len;
1424 temp_total_len += temp_len;
1425
1426 /*end batch scan result marker*/
1427 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1428 pTemp += temp_len;
1429 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001430
Rajeev79dbe4c2013-10-05 11:03:42 +05301431 }
1432
1433 if (temp_total_len < rem_len)
1434 {
1435 ret = temp_total_len + 1;
1436 strlcpy(pDest, temp, ret);
1437 pAdapter->isTruncated = FALSE;
1438 }
1439 else
1440 {
1441 pAdapter->isTruncated = TRUE;
1442 if (rem_len >= strlen("%%%%"))
1443 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001444 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301445 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001446 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301447 {
1448 ret = 0;
1449 }
1450 }
1451
1452 return ret;
1453
1454}/*End of hdd_format_batch_scan_rsp*/
1455
1456/**---------------------------------------------------------------------------
1457
1458 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1459 buffer starting with head of hdd batch scan response queue
1460
1461 \param - pAdapter Pointer to HDD adapter
1462 \param - pDest Pointer to user data buffer
1463 \param - cur_len current offset in user buffer
1464 \param - rem_len remaining no of bytes in user buffer
1465
1466 \return - number of bytes written in user buffer
1467
1468 --------------------------------------------------------------------------*/
1469
1470tANI_U32 hdd_populate_user_batch_scan_rsp
1471(
1472 hdd_adapter_t* pAdapter,
1473 tANI_U8 *pDest,
1474 tANI_U32 cur_len,
1475 tANI_U32 rem_len
1476)
1477{
1478 tHddBatchScanRsp *pHead;
1479 tHddBatchScanRsp *pPrev;
1480 tANI_U32 len;
1481
Rajeev79dbe4c2013-10-05 11:03:42 +05301482 pAdapter->isTruncated = FALSE;
1483
1484 /*head of hdd batch scan response queue*/
1485 pHead = pAdapter->pBatchScanRsp;
1486 while (pHead)
1487 {
1488 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1489 pAdapter);
1490 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001491 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301492 cur_len += len;
1493 if(TRUE == pAdapter->isTruncated)
1494 {
1495 /*result is truncated return rest of scan rsp in next req*/
1496 cur_len = rem_len;
1497 break;
1498 }
1499 pPrev = pHead;
1500 pHead = pHead->pNext;
1501 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001502 if (TRUE == pPrev->ApInfo.isLastAp)
1503 {
1504 pAdapter->prev_batch_id = 0;
1505 }
1506 else
1507 {
1508 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1509 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301510 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001511 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301512 }
1513
1514 return cur_len;
1515}/*End of hdd_populate_user_batch_scan_rsp*/
1516
1517/**---------------------------------------------------------------------------
1518
1519 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1520 scan response data from HDD queue to user space
1521 It does following in detail:
1522 a) if HDD has enough data in its queue then it 1st copies data to user
1523 space and then send get batch scan indication message to FW. In this
1524 case it does not wait on any event and batch scan response data will
1525 be populated in HDD response queue in MC thread context after receiving
1526 indication from FW
1527 b) else send get batch scan indication message to FW and wait on an event
1528 which will be set once HDD receives complete batch scan response from
1529 FW and then this function returns batch scan response to user space
1530
1531 \param - pAdapter Pointer to HDD adapter
1532 \param - pPrivData Pointer to priv_data
1533
1534 \return - 0 for success -EFAULT for failure
1535
1536 --------------------------------------------------------------------------*/
1537
1538int hdd_return_batch_scan_rsp_to_user
1539(
1540 hdd_adapter_t* pAdapter,
1541 hdd_priv_data_t *pPrivData,
1542 tANI_U8 *command
1543)
1544{
1545 tANI_U8 *pDest;
1546 tANI_U32 count = 0;
1547 tANI_U32 len = 0;
1548 tANI_U32 cur_len = 0;
1549 tANI_U32 rem_len = 0;
1550 eHalStatus halStatus;
1551 unsigned long rc;
1552 tSirTriggerBatchScanResultInd *pReq;
1553
1554 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1555 pReq->param = 0;/*batch scan client*/
1556 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1557 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1558
1559 cur_len = pPrivData->used_len;
1560 if (pPrivData->total_len > pPrivData->used_len)
1561 {
1562 rem_len = pPrivData->total_len - pPrivData->used_len;
1563 }
1564 else
1565 {
1566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1567 "%s: Invalid user data buffer total_len %d used_len %d",
1568 __func__, pPrivData->total_len, pPrivData->used_len);
1569 return -EFAULT;
1570 }
1571
1572 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1573 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1574 cur_len, rem_len);
1575 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1576
1577 /*enough scan result available in cache to return to user space or
1578 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001579 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301580 {
1581 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1582 halStatus = sme_TriggerBatchScanResultInd(
1583 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1584 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1585 pAdapter);
1586 if ( eHAL_STATUS_SUCCESS == halStatus )
1587 {
1588 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1589 {
1590 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1591 rc = wait_for_completion_timeout(
1592 &pAdapter->hdd_get_batch_scan_req_var,
1593 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1594 if (0 == rc)
1595 {
1596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1597 "%s: Timeout waiting to fetch batch scan rsp from fw",
1598 __func__);
1599 return -EFAULT;
1600 }
1601 }
1602
1603 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001604 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301605 pDest += len;
1606 cur_len += len;
1607
1608 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1609 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1610 cur_len, rem_len);
1611 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1612
1613 count = 0;
1614 len = (len - pPrivData->used_len);
1615 pDest = (command + pPrivData->used_len);
1616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001617 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301618 while(count < len)
1619 {
1620 printk("%c", *(pDest + count));
1621 count++;
1622 }
1623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1624 "%s: copy %d data to user buffer", __func__, len);
1625 if (copy_to_user(pPrivData->buf, pDest, len))
1626 {
1627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1628 "%s: failed to copy data to user buffer", __func__);
1629 return -EFAULT;
1630 }
1631 }
1632 else
1633 {
1634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1635 "sme_GetBatchScanScan returned failure halStatus %d",
1636 halStatus);
1637 return -EINVAL;
1638 }
1639 }
1640 else
1641 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301642 count = 0;
1643 len = (len - pPrivData->used_len);
1644 pDest = (command + pPrivData->used_len);
1645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001646 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301647 while(count < len)
1648 {
1649 printk("%c", *(pDest + count));
1650 count++;
1651 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1653 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301654 if (copy_to_user(pPrivData->buf, pDest, len))
1655 {
1656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1657 "%s: failed to copy data to user buffer", __func__);
1658 return -EFAULT;
1659 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301660 }
1661
1662 return 0;
1663} /*End of hdd_return_batch_scan_rsp_to_user*/
1664
Rajeev Kumar8b373292014-01-08 20:36:55 -08001665
1666/**---------------------------------------------------------------------------
1667
1668 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1669 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1670 WLS_BATCHING VERSION
1671 WLS_BATCHING SET
1672 WLS_BATCHING GET
1673 WLS_BATCHING STOP
1674
1675 \param - pAdapter Pointer to HDD adapter
1676 \param - pPrivdata Pointer to priv_data
1677 \param - command Pointer to command
1678
1679 \return - 0 for success -EFAULT for failure
1680
1681 --------------------------------------------------------------------------*/
1682
1683int hdd_handle_batch_scan_ioctl
1684(
1685 hdd_adapter_t *pAdapter,
1686 hdd_priv_data_t *pPrivdata,
1687 tANI_U8 *command
1688)
1689{
1690 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001691 hdd_context_t *pHddCtx;
1692
1693 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1694 ret = wlan_hdd_validate_context(pHddCtx);
1695 if (ret)
1696 {
1697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1698 "%s: HDD context is not valid!", __func__);
1699 goto exit;
1700 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001701
1702 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1703 {
1704 char extra[32];
1705 tANI_U8 len = 0;
1706 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1707
1708 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1709 {
1710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1711 "%s: Batch scan feature is not supported by FW", __func__);
1712 ret = -EINVAL;
1713 goto exit;
1714 }
1715
1716 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1717 version);
1718 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1719 {
1720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1721 "%s: failed to copy data to user buffer", __func__);
1722 ret = -EFAULT;
1723 goto exit;
1724 }
1725 ret = HDD_BATCH_SCAN_VERSION;
1726 }
1727 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1728 {
1729 int status;
1730 tANI_U8 *value = (command + 16);
1731 eHalStatus halStatus;
1732 unsigned long rc;
1733 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1734 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1735
1736 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1737 {
1738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1739 "%s: Batch scan feature is not supported by FW", __func__);
1740 ret = -EINVAL;
1741 goto exit;
1742 }
1743
1744 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1745 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1746 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1747 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1748 {
1749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301750 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001751 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301752 hdd_device_modetoString(pAdapter->device_mode),
1753 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001754 ret = -EINVAL;
1755 goto exit;
1756 }
1757
1758 status = hdd_parse_set_batchscan_command(value, pReq);
1759 if (status)
1760 {
1761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1762 "Invalid WLS_BATCHING SET command");
1763 ret = -EINVAL;
1764 goto exit;
1765 }
1766
1767
1768 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1769 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1770 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1771 pAdapter);
1772
1773 if ( eHAL_STATUS_SUCCESS == halStatus )
1774 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301775 char extra[32];
1776 tANI_U8 len = 0;
1777 tANI_U8 mScan = 0;
1778
Rajeev Kumar8b373292014-01-08 20:36:55 -08001779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1780 "sme_SetBatchScanReq returned success halStatus %d",
1781 halStatus);
1782 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1783 {
1784 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1785 rc = wait_for_completion_timeout(
1786 &pAdapter->hdd_set_batch_scan_req_var,
1787 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1788 if (0 == rc)
1789 {
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1791 "%s: Timeout waiting for set batch scan to complete",
1792 __func__);
1793 ret = -EINVAL;
1794 goto exit;
1795 }
1796 }
1797 if ( !pRsp->nScansToBatch )
1798 {
1799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1800 "%s: Received set batch scan failure response from FW",
1801 __func__);
1802 ret = -EINVAL;
1803 goto exit;
1804 }
1805 /*As per the Batch Scan Framework API we should return the MIN of
1806 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301807 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001808
1809 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1810
1811 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1812 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301813 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1814 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1815 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1816 {
1817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1818 "%s: failed to copy MSCAN value to user buffer", __func__);
1819 ret = -EFAULT;
1820 goto exit;
1821 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001822 }
1823 else
1824 {
1825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1826 "sme_SetBatchScanReq returned failure halStatus %d",
1827 halStatus);
1828 ret = -EINVAL;
1829 goto exit;
1830 }
1831 }
1832 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1833 {
1834 eHalStatus halStatus;
1835 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1836 pInd->param = 0;
1837
1838 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1839 {
1840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1841 "%s: Batch scan feature is not supported by FW", __func__);
1842 ret = -EINVAL;
1843 goto exit;
1844 }
1845
1846 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1847 {
1848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 "Batch scan is not yet enabled batch scan state %d",
1850 pAdapter->batchScanState);
1851 ret = -EINVAL;
1852 goto exit;
1853 }
1854
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001855 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1856 hdd_deinit_batch_scan(pAdapter);
1857 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1858
Rajeev Kumar8b373292014-01-08 20:36:55 -08001859 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1860
1861 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1862 pAdapter->sessionId);
1863 if ( eHAL_STATUS_SUCCESS == halStatus )
1864 {
1865 ret = 0;
1866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1867 "sme_StopBatchScanInd returned success halStatus %d",
1868 halStatus);
1869 }
1870 else
1871 {
1872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1873 "sme_StopBatchScanInd returned failure halStatus %d",
1874 halStatus);
1875 ret = -EINVAL;
1876 goto exit;
1877 }
1878 }
1879 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1880 {
1881 tANI_U32 remain_len;
1882
1883 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1884 {
1885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1886 "%s: Batch scan feature is not supported by FW", __func__);
1887 ret = -EINVAL;
1888 goto exit;
1889 }
1890
1891 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1892 {
1893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1894 "Batch scan is not yet enabled could not return results"
1895 "Batch Scan state %d",
1896 pAdapter->batchScanState);
1897 ret = -EINVAL;
1898 goto exit;
1899 }
1900
1901 pPrivdata->used_len = 16;
1902 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1903 if (remain_len < pPrivdata->total_len)
1904 {
1905 /*Clear previous batch scan response data if any*/
1906 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1907 }
1908 else
1909 {
1910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1911 "Invalid total length from user space can't fetch batch"
1912 " scan response total_len %d used_len %d remain len %d",
1913 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1914 ret = -EINVAL;
1915 goto exit;
1916 }
1917 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1918 }
1919
1920exit:
1921
1922 return ret;
1923}
1924
1925
Rajeev79dbe4c2013-10-05 11:03:42 +05301926#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1927
c_hpothu92367912014-05-01 15:18:17 +05301928static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1929{
1930 bcnMissRateContext_t *pCBCtx = (bcnMissRateContext_t *)data;
1931
1932 /* there is a race condition that exists between this callback
1933 function and the caller since the caller could time out either
1934 before or while this code is executing. we use a spinlock to
1935 serialize these actions */
1936 spin_lock(&hdd_context_lock);
1937
1938 gbcnMissRate = -1;
1939
1940 if(pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC || NULL == data)
1941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR,
1943 FL("invalid context magic: %08x data: %p"), pCBCtx->magic, data );
1944 spin_unlock(&hdd_context_lock);
1945 return ;
1946 }
1947
1948 if (VOS_STATUS_SUCCESS == status)
1949 {
1950 gbcnMissRate = bcnMissRate;
1951 }
1952 complete(&(pCBCtx->completion));
1953 spin_unlock(&hdd_context_lock);
1954
1955 return;
1956}
1957
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001958static int hdd_driver_command(hdd_adapter_t *pAdapter,
1959 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07001960{
Jeff Johnson295189b2012-06-20 16:38:30 -07001961 hdd_priv_data_t priv_data;
1962 tANI_U8 *command = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001963 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001964
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001965 /*
1966 * Note that valid pointers are provided by caller
1967 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001968
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001969 /* copy to local struct to avoid numerous changes to legacy code */
1970 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07001971
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001972 if (priv_data.total_len <= 0 ||
1973 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07001974 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001975 hddLog(VOS_TRACE_LEVEL_WARN,
1976 "%s:invalid priv_data.total_len(%d)!!!", __func__,
1977 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001978 ret = -EINVAL;
1979 goto exit;
1980 }
1981
1982 /* Allocate +1 for '\0' */
1983 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07001984 if (!command)
1985 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001986 hddLog(VOS_TRACE_LEVEL_ERROR,
1987 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001988 ret = -ENOMEM;
1989 goto exit;
1990 }
1991
1992 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
1993 {
1994 ret = -EFAULT;
1995 goto exit;
1996 }
1997
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07001998 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07001999 command[priv_data.total_len] = '\0';
2000
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002001 /* at one time the following block of code was conditional. braces
2002 * have been retained to avoid re-indenting the legacy code
2003 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 {
2005 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2006
2007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002008 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002009
2010 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2011 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302012 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2013 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2014 pAdapter->sessionId, (unsigned)
2015 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2016 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2017 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2018 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002019 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2020 sizeof(tSirMacAddr)))
2021 {
2022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002023 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002024 ret = -EFAULT;
2025 }
2026 }
Amar Singhal0974e402013-02-12 14:27:46 -08002027 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002028 {
Amar Singhal0974e402013-02-12 14:27:46 -08002029 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002030
Jeff Johnson295189b2012-06-20 16:38:30 -07002031 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002032
2033 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002034 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002036 "%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 -07002037 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002038 ret = hdd_setBand_helper(pAdapter->dev, ptr);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302039 if(ret != 0)
2040 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002041 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002042 }
Kiet Lamf040f472013-11-20 21:15:23 +05302043 else if(strncmp(command, "SETWMMPS", 8) == 0)
2044 {
2045 tANI_U8 *ptr = command;
2046 ret = hdd_wmmps_helper(pAdapter, ptr);
2047 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002048 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2049 {
2050 char *country_code;
2051
2052 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002053
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002054 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002055 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002056#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302057 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002058#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002059 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2060 (void *)(tSmeChangeCountryCallback)
2061 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302062 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002063 if (eHAL_STATUS_SUCCESS == ret)
2064 {
2065 ret = wait_for_completion_interruptible_timeout(
2066 &pAdapter->change_country_code,
2067 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2068 if (0 >= ret)
2069 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002070 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302071 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002072 }
2073 }
2074 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002075 {
2076 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002077 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002078 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002079 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002080
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002081 }
2082 /*
2083 command should be a string having format
2084 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2085 */
Amar Singhal0974e402013-02-12 14:27:46 -08002086 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002087 {
Amar Singhal0974e402013-02-12 14:27:46 -08002088 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002089
2090 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002091 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002092
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002093 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002094 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002095 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2096 {
2097 int suspend = 0;
2098 tANI_U8 *ptr = (tANI_U8*)command + 15;
2099
2100 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302101 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2102 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2103 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002104 hdd_set_wlan_suspend_mode(suspend);
2105 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002106#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2107 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2108 {
2109 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002110 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002111 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2112 eHalStatus status = eHAL_STATUS_SUCCESS;
2113
2114 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2115 value = value + 15;
2116
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002117 /* Convert the value from ascii to integer */
2118 ret = kstrtos8(value, 10, &rssi);
2119 if (ret < 0)
2120 {
2121 /* If the input value is greater than max value of datatype, then also
2122 kstrtou8 fails */
2123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2124 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002125 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002126 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2127 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2128 ret = -EINVAL;
2129 goto exit;
2130 }
2131
Srinivas Girigowdade697412013-02-14 16:31:48 -08002132 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002133
Srinivas Girigowdade697412013-02-14 16:31:48 -08002134 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2135 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2136 {
2137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2138 "Neighbor lookup threshold value %d is out of range"
2139 " (Min: %d Max: %d)", lookUpThreshold,
2140 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2141 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2142 ret = -EINVAL;
2143 goto exit;
2144 }
2145
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302146 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2147 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2148 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2150 "%s: Received Command to Set Roam trigger"
2151 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2152
2153 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2154 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2155 if (eHAL_STATUS_SUCCESS != status)
2156 {
2157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2158 "%s: Failed to set roam trigger, try again", __func__);
2159 ret = -EPERM;
2160 goto exit;
2161 }
2162
2163 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
2164 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2165 }
2166 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2167 {
2168 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2169 int rssi = (-1) * lookUpThreshold;
2170 char extra[32];
2171 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302172 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2173 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2174 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002175 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002176 if (copy_to_user(priv_data.buf, &extra, len + 1))
2177 {
2178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2179 "%s: failed to copy data to user buffer", __func__);
2180 ret = -EFAULT;
2181 goto exit;
2182 }
2183 }
2184 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2185 {
2186 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002187 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002188 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002189
Srinivas Girigowdade697412013-02-14 16:31:48 -08002190 /* input refresh period is in terms of seconds */
2191 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2192 value = value + 18;
2193 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002194 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002195 if (ret < 0)
2196 {
2197 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002198 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002200 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002201 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002202 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2203 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002204 ret = -EINVAL;
2205 goto exit;
2206 }
2207
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002208 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2209 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002210 {
2211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002212 "Roam scan period value %d is out of range"
2213 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002214 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2215 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002216 ret = -EINVAL;
2217 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302218 }
2219 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2220 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2221 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002222 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002223
2224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2225 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002226 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002227
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002228 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2229 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002230 }
2231 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2232 {
2233 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2234 char extra[32];
2235 tANI_U8 len = 0;
2236
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302237 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2238 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2239 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002240 len = scnprintf(extra, sizeof(extra), "%s %d",
2241 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002242 /* Returned value is in units of seconds */
2243 if (copy_to_user(priv_data.buf, &extra, len + 1))
2244 {
2245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2246 "%s: failed to copy data to user buffer", __func__);
2247 ret = -EFAULT;
2248 goto exit;
2249 }
2250 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002251 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2252 {
2253 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002254 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002255 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002256
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002257 /* input refresh period is in terms of seconds */
2258 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2259 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002260
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002261 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002262 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002263 if (ret < 0)
2264 {
2265 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002266 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002268 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002269 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002270 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2271 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2272 ret = -EINVAL;
2273 goto exit;
2274 }
2275
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002276 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2277 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2278 {
2279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2280 "Neighbor scan results refresh period value %d is out of range"
2281 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2282 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2283 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2284 ret = -EINVAL;
2285 goto exit;
2286 }
2287 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2288
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2290 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002291 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002292
2293 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2294 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2295 }
2296 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2297 {
2298 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2299 char extra[32];
2300 tANI_U8 len = 0;
2301
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002302 len = scnprintf(extra, sizeof(extra), "%s %d",
2303 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002304 /* Returned value is in units of seconds */
2305 if (copy_to_user(priv_data.buf, &extra, len + 1))
2306 {
2307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2308 "%s: failed to copy data to user buffer", __func__);
2309 ret = -EFAULT;
2310 goto exit;
2311 }
2312 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002313#ifdef FEATURE_WLAN_LFR
2314 /* SETROAMMODE */
2315 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2316 {
2317 tANI_U8 *value = command;
2318 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2319
2320 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2321 value = value + SIZE_OF_SETROAMMODE + 1;
2322
2323 /* Convert the value from ascii to integer */
2324 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2325 if (ret < 0)
2326 {
2327 /* If the input value is greater than max value of datatype, then also
2328 kstrtou8 fails */
2329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2330 "%s: kstrtou8 failed range [%d - %d]", __func__,
2331 CFG_LFR_FEATURE_ENABLED_MIN,
2332 CFG_LFR_FEATURE_ENABLED_MAX);
2333 ret = -EINVAL;
2334 goto exit;
2335 }
2336 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2337 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2338 {
2339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2340 "Roam Mode value %d is out of range"
2341 " (Min: %d Max: %d)", roamMode,
2342 CFG_LFR_FEATURE_ENABLED_MIN,
2343 CFG_LFR_FEATURE_ENABLED_MAX);
2344 ret = -EINVAL;
2345 goto exit;
2346 }
2347
2348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2349 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2350 /*
2351 * Note that
2352 * SETROAMMODE 0 is to enable LFR while
2353 * SETROAMMODE 1 is to disable LFR, but
2354 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2355 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2356 */
2357 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2358 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2359 else
2360 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2361
2362 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2363 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2364 }
2365 /* GETROAMMODE */
2366 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2367 {
2368 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2369 char extra[32];
2370 tANI_U8 len = 0;
2371
2372 /*
2373 * roamMode value shall be inverted because the sementics is different.
2374 */
2375 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2376 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2377 else
2378 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2379
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002380 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002381 if (copy_to_user(priv_data.buf, &extra, len + 1))
2382 {
2383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2384 "%s: failed to copy data to user buffer", __func__);
2385 ret = -EFAULT;
2386 goto exit;
2387 }
2388 }
2389#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002390#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002391#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002392 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2393 {
2394 tANI_U8 *value = command;
2395 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2396
2397 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2398 value = value + 13;
2399 /* Convert the value from ascii to integer */
2400 ret = kstrtou8(value, 10, &roamRssiDiff);
2401 if (ret < 0)
2402 {
2403 /* If the input value is greater than max value of datatype, then also
2404 kstrtou8 fails */
2405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2406 "%s: kstrtou8 failed range [%d - %d]", __func__,
2407 CFG_ROAM_RSSI_DIFF_MIN,
2408 CFG_ROAM_RSSI_DIFF_MAX);
2409 ret = -EINVAL;
2410 goto exit;
2411 }
2412
2413 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2414 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2415 {
2416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2417 "Roam rssi diff value %d is out of range"
2418 " (Min: %d Max: %d)", roamRssiDiff,
2419 CFG_ROAM_RSSI_DIFF_MIN,
2420 CFG_ROAM_RSSI_DIFF_MAX);
2421 ret = -EINVAL;
2422 goto exit;
2423 }
2424
2425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2426 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2427
2428 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2429 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2430 }
2431 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2432 {
2433 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2434 char extra[32];
2435 tANI_U8 len = 0;
2436
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302437 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2438 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2439 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002440 len = scnprintf(extra, sizeof(extra), "%s %d",
2441 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002442 if (copy_to_user(priv_data.buf, &extra, len + 1))
2443 {
2444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2445 "%s: failed to copy data to user buffer", __func__);
2446 ret = -EFAULT;
2447 goto exit;
2448 }
2449 }
2450#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002451#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002452 else if (strncmp(command, "GETBAND", 7) == 0)
2453 {
2454 int band = -1;
2455 char extra[32];
2456 tANI_U8 len = 0;
2457 hdd_getBand_helper(pHddCtx, &band);
2458
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2460 TRACE_CODE_HDD_GETBAND_IOCTL,
2461 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002462 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002463 if (copy_to_user(priv_data.buf, &extra, len + 1))
2464 {
2465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2466 "%s: failed to copy data to user buffer", __func__);
2467 ret = -EFAULT;
2468 goto exit;
2469 }
2470 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002471 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2472 {
2473 tANI_U8 *value = command;
2474 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2475 tANI_U8 numChannels = 0;
2476 eHalStatus status = eHAL_STATUS_SUCCESS;
2477
2478 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2479 if (eHAL_STATUS_SUCCESS != status)
2480 {
2481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2482 "%s: Failed to parse channel list information", __func__);
2483 ret = -EINVAL;
2484 goto exit;
2485 }
2486
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302487 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2488 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2489 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002490 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2491 {
2492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2493 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2494 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2495 ret = -EINVAL;
2496 goto exit;
2497 }
2498 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2499 numChannels);
2500 if (eHAL_STATUS_SUCCESS != status)
2501 {
2502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2503 "%s: Failed to update channel list information", __func__);
2504 ret = -EINVAL;
2505 goto exit;
2506 }
2507 }
2508 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2509 {
2510 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2511 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002512 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002513 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002514 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002515
2516 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2517 ChannelList, &numChannels ))
2518 {
2519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2520 "%s: failed to get roam scan channel list", __func__);
2521 ret = -EFAULT;
2522 goto exit;
2523 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2525 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2526 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002527 /* output channel list is of the format
2528 [Number of roam scan channels][Channel1][Channel2]... */
2529 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002530 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002531 for (j = 0; (j < numChannels); j++)
2532 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002533 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2534 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002535 }
2536
2537 if (copy_to_user(priv_data.buf, &extra, len + 1))
2538 {
2539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2540 "%s: failed to copy data to user buffer", __func__);
2541 ret = -EFAULT;
2542 goto exit;
2543 }
2544 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002545 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2546 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002547 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002548 char extra[32];
2549 tANI_U8 len = 0;
2550
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002551 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002552 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002553 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002554 hdd_is_okc_mode_enabled(pHddCtx) &&
2555 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2556 {
2557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002558 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002559 " hence this operation is not permitted!", __func__);
2560 ret = -EPERM;
2561 goto exit;
2562 }
2563
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002564 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002565 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002566 if (copy_to_user(priv_data.buf, &extra, len + 1))
2567 {
2568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2569 "%s: failed to copy data to user buffer", __func__);
2570 ret = -EFAULT;
2571 goto exit;
2572 }
2573 }
2574 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2575 {
2576 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2577 char extra[32];
2578 tANI_U8 len = 0;
2579
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002580 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002581 then this operation is not permitted (return FAILURE) */
2582 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002583 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002584 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2585 {
2586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002587 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002588 " hence this operation is not permitted!", __func__);
2589 ret = -EPERM;
2590 goto exit;
2591 }
2592
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002593 len = scnprintf(extra, sizeof(extra), "%s %d",
2594 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002595 if (copy_to_user(priv_data.buf, &extra, len + 1))
2596 {
2597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2598 "%s: failed to copy data to user buffer", __func__);
2599 ret = -EFAULT;
2600 goto exit;
2601 }
2602 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002603 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002604 {
2605 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2606 char extra[32];
2607 tANI_U8 len = 0;
2608
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002609 len = scnprintf(extra, sizeof(extra), "%s %d",
2610 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002611 if (copy_to_user(priv_data.buf, &extra, len + 1))
2612 {
2613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2614 "%s: failed to copy data to user buffer", __func__);
2615 ret = -EFAULT;
2616 goto exit;
2617 }
2618 }
2619 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2620 {
2621 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2622 char extra[32];
2623 tANI_U8 len = 0;
2624
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002625 len = scnprintf(extra, sizeof(extra), "%s %d",
2626 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002627 if (copy_to_user(priv_data.buf, &extra, len + 1))
2628 {
2629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2630 "%s: failed to copy data to user buffer", __func__);
2631 ret = -EFAULT;
2632 goto exit;
2633 }
2634 }
2635 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2636 {
2637 tANI_U8 *value = command;
2638 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2639
2640 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2641 value = value + 26;
2642 /* Convert the value from ascii to integer */
2643 ret = kstrtou8(value, 10, &minTime);
2644 if (ret < 0)
2645 {
2646 /* If the input value is greater than max value of datatype, then also
2647 kstrtou8 fails */
2648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2649 "%s: kstrtou8 failed range [%d - %d]", __func__,
2650 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2651 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2652 ret = -EINVAL;
2653 goto exit;
2654 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002655 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2656 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2657 {
2658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2659 "scan min channel time value %d is out of range"
2660 " (Min: %d Max: %d)", minTime,
2661 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2662 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2663 ret = -EINVAL;
2664 goto exit;
2665 }
2666
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302667 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2668 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2669 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2671 "%s: Received Command to change channel min time = %d", __func__, minTime);
2672
2673 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2674 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2675 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002676 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2677 {
2678 tANI_U8 *value = command;
2679 tANI_U8 channel = 0;
2680 tANI_U8 dwellTime = 0;
2681 tANI_U8 bufLen = 0;
2682 tANI_U8 *buf = NULL;
2683 tSirMacAddr targetApBssid;
2684 eHalStatus status = eHAL_STATUS_SUCCESS;
2685 struct ieee80211_channel chan;
2686 tANI_U8 finalLen = 0;
2687 tANI_U8 *finalBuf = NULL;
2688 tANI_U8 temp = 0;
2689 u64 cookie;
2690 hdd_station_ctx_t *pHddStaCtx = NULL;
2691 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2692
2693 /* if not associated, no need to send action frame */
2694 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2695 {
2696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2697 ret = -EINVAL;
2698 goto exit;
2699 }
2700
2701 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2702 &dwellTime, &buf, &bufLen);
2703 if (eHAL_STATUS_SUCCESS != status)
2704 {
2705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2706 "%s: Failed to parse send action frame data", __func__);
2707 ret = -EINVAL;
2708 goto exit;
2709 }
2710
2711 /* if the target bssid is different from currently associated AP,
2712 then no need to send action frame */
2713 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2714 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2715 {
2716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2717 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002718 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002719 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002720 goto exit;
2721 }
2722
2723 /* if the channel number is different from operating channel then
2724 no need to send action frame */
2725 if (channel != pHddStaCtx->conn_info.operationChannel)
2726 {
2727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2728 "%s: channel(%d) is different from operating channel(%d)",
2729 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2730 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002731 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002732 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002733 goto exit;
2734 }
2735 chan.center_freq = sme_ChnToFreq(channel);
2736
2737 finalLen = bufLen + 24;
2738 finalBuf = vos_mem_malloc(finalLen);
2739 if (NULL == finalBuf)
2740 {
2741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2742 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002743 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002744 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002745 goto exit;
2746 }
2747 vos_mem_zero(finalBuf, finalLen);
2748
2749 /* Fill subtype */
2750 temp = SIR_MAC_MGMT_ACTION << 4;
2751 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2752
2753 /* Fill type */
2754 temp = SIR_MAC_MGMT_FRAME;
2755 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2756
2757 /* Fill destination address (bssid of the AP) */
2758 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2759
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002760 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002761 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2762
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002763 /* Fill BSSID (AP mac address) */
2764 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002765
2766 /* Fill received buffer from 24th address */
2767 vos_mem_copy(finalBuf + 24, buf, bufLen);
2768
Jeff Johnson11c33152013-04-16 17:52:40 -07002769 /* done with the parsed buffer */
2770 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002771 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002772
DARAM SUDHA39eede62014-02-12 11:16:40 +05302773 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002774#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2775 &(pAdapter->wdev),
2776#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002777 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002778#endif
2779 &chan, 0,
2780#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2781 NL80211_CHAN_HT20, 1,
2782#endif
2783 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002784 1, &cookie );
2785 vos_mem_free(finalBuf);
2786 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002787 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2788 {
2789 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2790 char extra[32];
2791 tANI_U8 len = 0;
2792
2793 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002794 len = scnprintf(extra, sizeof(extra), "%s %d",
2795 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302796 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2797 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2798 pAdapter->sessionId, val));
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, "SETSCANCHANNELTIME", 18) == 0)
2808 {
2809 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002810 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002811
2812 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2813 value = value + 19;
2814 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002815 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002816 if (ret < 0)
2817 {
2818 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002819 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002821 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002822 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2823 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2824 ret = -EINVAL;
2825 goto exit;
2826 }
2827
2828 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
2829 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
2830 {
2831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2832 "lfr mode value %d is out of range"
2833 " (Min: %d Max: %d)", maxTime,
2834 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2835 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2836 ret = -EINVAL;
2837 goto exit;
2838 }
2839
2840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2841 "%s: Received Command to change channel max time = %d", __func__, maxTime);
2842
2843 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
2844 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
2845 }
2846 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
2847 {
2848 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
2849 char extra[32];
2850 tANI_U8 len = 0;
2851
2852 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002853 len = scnprintf(extra, sizeof(extra), "%s %d",
2854 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002855 if (copy_to_user(priv_data.buf, &extra, len + 1))
2856 {
2857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2858 "%s: failed to copy data to user buffer", __func__);
2859 ret = -EFAULT;
2860 goto exit;
2861 }
2862 }
2863 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
2864 {
2865 tANI_U8 *value = command;
2866 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
2867
2868 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
2869 value = value + 16;
2870 /* Convert the value from ascii to integer */
2871 ret = kstrtou16(value, 10, &val);
2872 if (ret < 0)
2873 {
2874 /* If the input value is greater than max value of datatype, then also
2875 kstrtou16 fails */
2876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2877 "%s: kstrtou16 failed range [%d - %d]", __func__,
2878 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2879 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2880 ret = -EINVAL;
2881 goto exit;
2882 }
2883
2884 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
2885 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
2886 {
2887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2888 "scan home time value %d is out of range"
2889 " (Min: %d Max: %d)", val,
2890 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
2891 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
2892 ret = -EINVAL;
2893 goto exit;
2894 }
2895
2896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2897 "%s: Received Command to change scan home time = %d", __func__, val);
2898
2899 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
2900 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
2901 }
2902 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
2903 {
2904 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
2905 char extra[32];
2906 tANI_U8 len = 0;
2907
2908 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002909 len = scnprintf(extra, sizeof(extra), "%s %d",
2910 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002911 if (copy_to_user(priv_data.buf, &extra, len + 1))
2912 {
2913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2914 "%s: failed to copy data to user buffer", __func__);
2915 ret = -EFAULT;
2916 goto exit;
2917 }
2918 }
2919 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
2920 {
2921 tANI_U8 *value = command;
2922 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
2923
2924 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
2925 value = value + 17;
2926 /* Convert the value from ascii to integer */
2927 ret = kstrtou8(value, 10, &val);
2928 if (ret < 0)
2929 {
2930 /* If the input value is greater than max value of datatype, then also
2931 kstrtou8 fails */
2932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2933 "%s: kstrtou8 failed range [%d - %d]", __func__,
2934 CFG_ROAM_INTRA_BAND_MIN,
2935 CFG_ROAM_INTRA_BAND_MAX);
2936 ret = -EINVAL;
2937 goto exit;
2938 }
2939
2940 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
2941 (val > CFG_ROAM_INTRA_BAND_MAX))
2942 {
2943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2944 "intra band mode value %d is out of range"
2945 " (Min: %d Max: %d)", val,
2946 CFG_ROAM_INTRA_BAND_MIN,
2947 CFG_ROAM_INTRA_BAND_MAX);
2948 ret = -EINVAL;
2949 goto exit;
2950 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2952 "%s: Received Command to change intra band = %d", __func__, val);
2953
2954 pHddCtx->cfg_ini->nRoamIntraBand = val;
2955 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
2956 }
2957 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
2958 {
2959 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
2960 char extra[32];
2961 tANI_U8 len = 0;
2962
2963 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002964 len = scnprintf(extra, sizeof(extra), "%s %d",
2965 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002966 if (copy_to_user(priv_data.buf, &extra, len + 1))
2967 {
2968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2969 "%s: failed to copy data to user buffer", __func__);
2970 ret = -EFAULT;
2971 goto exit;
2972 }
2973 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07002974 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
2975 {
2976 tANI_U8 *value = command;
2977 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
2978
2979 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
2980 value = value + 15;
2981 /* Convert the value from ascii to integer */
2982 ret = kstrtou8(value, 10, &nProbes);
2983 if (ret < 0)
2984 {
2985 /* If the input value is greater than max value of datatype, then also
2986 kstrtou8 fails */
2987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2988 "%s: kstrtou8 failed range [%d - %d]", __func__,
2989 CFG_ROAM_SCAN_N_PROBES_MIN,
2990 CFG_ROAM_SCAN_N_PROBES_MAX);
2991 ret = -EINVAL;
2992 goto exit;
2993 }
2994
2995 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
2996 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
2997 {
2998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2999 "NProbes value %d is out of range"
3000 " (Min: %d Max: %d)", nProbes,
3001 CFG_ROAM_SCAN_N_PROBES_MIN,
3002 CFG_ROAM_SCAN_N_PROBES_MAX);
3003 ret = -EINVAL;
3004 goto exit;
3005 }
3006
3007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3008 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3009
3010 pHddCtx->cfg_ini->nProbes = nProbes;
3011 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3012 }
3013 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3014 {
3015 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3016 char extra[32];
3017 tANI_U8 len = 0;
3018
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003019 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003020 if (copy_to_user(priv_data.buf, &extra, len + 1))
3021 {
3022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3023 "%s: failed to copy data to user buffer", __func__);
3024 ret = -EFAULT;
3025 goto exit;
3026 }
3027 }
3028 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3029 {
3030 tANI_U8 *value = command;
3031 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3032
3033 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3034 /* input value is in units of msec */
3035 value = value + 20;
3036 /* Convert the value from ascii to integer */
3037 ret = kstrtou16(value, 10, &homeAwayTime);
3038 if (ret < 0)
3039 {
3040 /* If the input value is greater than max value of datatype, then also
3041 kstrtou8 fails */
3042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3043 "%s: kstrtou8 failed range [%d - %d]", __func__,
3044 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3045 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3046 ret = -EINVAL;
3047 goto exit;
3048 }
3049
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003050 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3051 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3052 {
3053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3054 "homeAwayTime value %d is out of range"
3055 " (Min: %d Max: %d)", homeAwayTime,
3056 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3057 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3058 ret = -EINVAL;
3059 goto exit;
3060 }
3061
3062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3063 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003064 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3065 {
3066 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3067 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3068 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003069 }
3070 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3071 {
3072 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3073 char extra[32];
3074 tANI_U8 len = 0;
3075
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003076 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003077 if (copy_to_user(priv_data.buf, &extra, len + 1))
3078 {
3079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3080 "%s: failed to copy data to user buffer", __func__);
3081 ret = -EFAULT;
3082 goto exit;
3083 }
3084 }
3085 else if (strncmp(command, "REASSOC", 7) == 0)
3086 {
3087 tANI_U8 *value = command;
3088 tANI_U8 channel = 0;
3089 tSirMacAddr targetApBssid;
3090 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003091#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3092 tCsrHandoffRequest handoffInfo;
3093#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003094 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003095 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3096
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003097 /* if not associated, no need to proceed with reassoc */
3098 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3099 {
3100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3101 ret = -EINVAL;
3102 goto exit;
3103 }
3104
3105 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3106 if (eHAL_STATUS_SUCCESS != status)
3107 {
3108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3109 "%s: Failed to parse reassoc command data", __func__);
3110 ret = -EINVAL;
3111 goto exit;
3112 }
3113
3114 /* if the target bssid is same as currently associated AP,
3115 then no need to proceed with reassoc */
3116 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3117 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3118 {
3119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3120 ret = -EINVAL;
3121 goto exit;
3122 }
3123
3124 /* Check channel number is a valid channel number */
3125 if(VOS_STATUS_SUCCESS !=
3126 wlan_hdd_validate_operation_channel(pAdapter, channel))
3127 {
3128 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003129 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003130 return -EINVAL;
3131 }
3132
3133 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003134#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3135 handoffInfo.channel = channel;
3136 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3137 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3138#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003139 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003140 else if (strncmp(command, "SETWESMODE", 10) == 0)
3141 {
3142 tANI_U8 *value = command;
3143 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3144
3145 /* Move pointer to ahead of SETWESMODE<delimiter> */
3146 value = value + 11;
3147 /* Convert the value from ascii to integer */
3148 ret = kstrtou8(value, 10, &wesMode);
3149 if (ret < 0)
3150 {
3151 /* If the input value is greater than max value of datatype, then also
3152 kstrtou8 fails */
3153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3154 "%s: kstrtou8 failed range [%d - %d]", __func__,
3155 CFG_ENABLE_WES_MODE_NAME_MIN,
3156 CFG_ENABLE_WES_MODE_NAME_MAX);
3157 ret = -EINVAL;
3158 goto exit;
3159 }
3160
3161 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3162 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3163 {
3164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3165 "WES Mode value %d is out of range"
3166 " (Min: %d Max: %d)", wesMode,
3167 CFG_ENABLE_WES_MODE_NAME_MIN,
3168 CFG_ENABLE_WES_MODE_NAME_MAX);
3169 ret = -EINVAL;
3170 goto exit;
3171 }
3172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3173 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3174
3175 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3176 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3177 }
3178 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3179 {
3180 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3181 char extra[32];
3182 tANI_U8 len = 0;
3183
Arif Hussain826d9412013-11-12 16:44:54 -08003184 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003185 if (copy_to_user(priv_data.buf, &extra, len + 1))
3186 {
3187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3188 "%s: failed to copy data to user buffer", __func__);
3189 ret = -EFAULT;
3190 goto exit;
3191 }
3192 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003193#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003194#ifdef FEATURE_WLAN_LFR
3195 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3196 {
3197 tANI_U8 *value = command;
3198 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3199
3200 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3201 value = value + 12;
3202 /* Convert the value from ascii to integer */
3203 ret = kstrtou8(value, 10, &lfrMode);
3204 if (ret < 0)
3205 {
3206 /* If the input value is greater than max value of datatype, then also
3207 kstrtou8 fails */
3208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3209 "%s: kstrtou8 failed range [%d - %d]", __func__,
3210 CFG_LFR_FEATURE_ENABLED_MIN,
3211 CFG_LFR_FEATURE_ENABLED_MAX);
3212 ret = -EINVAL;
3213 goto exit;
3214 }
3215
3216 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3217 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3218 {
3219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3220 "lfr mode value %d is out of range"
3221 " (Min: %d Max: %d)", lfrMode,
3222 CFG_LFR_FEATURE_ENABLED_MIN,
3223 CFG_LFR_FEATURE_ENABLED_MAX);
3224 ret = -EINVAL;
3225 goto exit;
3226 }
3227
3228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3229 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3230
3231 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3232 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3233 }
3234#endif
3235#ifdef WLAN_FEATURE_VOWIFI_11R
3236 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3237 {
3238 tANI_U8 *value = command;
3239 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3240
3241 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3242 value = value + 18;
3243 /* Convert the value from ascii to integer */
3244 ret = kstrtou8(value, 10, &ft);
3245 if (ret < 0)
3246 {
3247 /* If the input value is greater than max value of datatype, then also
3248 kstrtou8 fails */
3249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3250 "%s: kstrtou8 failed range [%d - %d]", __func__,
3251 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3252 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3253 ret = -EINVAL;
3254 goto exit;
3255 }
3256
3257 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3258 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3259 {
3260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3261 "ft mode value %d is out of range"
3262 " (Min: %d Max: %d)", ft,
3263 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3264 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3265 ret = -EINVAL;
3266 goto exit;
3267 }
3268
3269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3270 "%s: Received Command to change ft mode = %d", __func__, ft);
3271
3272 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3273 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3274 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303275
3276 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3277 {
3278 tANI_U8 *value = command;
3279 tSirMacAddr targetApBssid;
3280 tANI_U8 trigger = 0;
3281 eHalStatus status = eHAL_STATUS_SUCCESS;
3282 hdd_station_ctx_t *pHddStaCtx = NULL;
3283 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3284
3285 /* if not associated, no need to proceed with reassoc */
3286 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3287 {
3288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3289 ret = -EINVAL;
3290 goto exit;
3291 }
3292
3293 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3294 if (eHAL_STATUS_SUCCESS != status)
3295 {
3296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3297 "%s: Failed to parse reassoc command data", __func__);
3298 ret = -EINVAL;
3299 goto exit;
3300 }
3301
3302 /* if the target bssid is same as currently associated AP,
3303 then no need to proceed with reassoc */
3304 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3305 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3306 {
3307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3308 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3309 __func__);
3310 ret = -EINVAL;
3311 goto exit;
3312 }
3313
3314 /* Proceed with scan/roam */
3315 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3316 &targetApBssid[0],
3317 (tSmeFastRoamTrigger)(trigger));
3318 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003319#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003320#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003321 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3322 {
3323 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003324 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003325
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003326 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003327 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003328 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003329 hdd_is_okc_mode_enabled(pHddCtx) &&
3330 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3331 {
3332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003333 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003334 " hence this operation is not permitted!", __func__);
3335 ret = -EPERM;
3336 goto exit;
3337 }
3338
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003339 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3340 value = value + 11;
3341 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003342 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003343 if (ret < 0)
3344 {
3345 /* If the input value is greater than max value of datatype, then also
3346 kstrtou8 fails */
3347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3348 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003349 CFG_ESE_FEATURE_ENABLED_MIN,
3350 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003351 ret = -EINVAL;
3352 goto exit;
3353 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003354 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3355 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003356 {
3357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003358 "Ese mode value %d is out of range"
3359 " (Min: %d Max: %d)", eseMode,
3360 CFG_ESE_FEATURE_ENABLED_MIN,
3361 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003362 ret = -EINVAL;
3363 goto exit;
3364 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003366 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003367
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003368 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3369 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003370 }
3371#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003372 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3373 {
3374 tANI_U8 *value = command;
3375 tANI_BOOLEAN roamScanControl = 0;
3376
3377 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3378 value = value + 19;
3379 /* Convert the value from ascii to integer */
3380 ret = kstrtou8(value, 10, &roamScanControl);
3381 if (ret < 0)
3382 {
3383 /* If the input value is greater than max value of datatype, then also
3384 kstrtou8 fails */
3385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3386 "%s: kstrtou8 failed ", __func__);
3387 ret = -EINVAL;
3388 goto exit;
3389 }
3390
3391 if (0 != roamScanControl)
3392 {
3393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3394 "roam scan control invalid value = %d",
3395 roamScanControl);
3396 ret = -EINVAL;
3397 goto exit;
3398 }
3399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3400 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3401
3402 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3403 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003404#ifdef FEATURE_WLAN_OKC
3405 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3406 {
3407 tANI_U8 *value = command;
3408 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3409
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003410 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003411 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003412 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003413 hdd_is_okc_mode_enabled(pHddCtx) &&
3414 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3415 {
3416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003417 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003418 " hence this operation is not permitted!", __func__);
3419 ret = -EPERM;
3420 goto exit;
3421 }
3422
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003423 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3424 value = value + 11;
3425 /* Convert the value from ascii to integer */
3426 ret = kstrtou8(value, 10, &okcMode);
3427 if (ret < 0)
3428 {
3429 /* If the input value is greater than max value of datatype, then also
3430 kstrtou8 fails */
3431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3432 "%s: kstrtou8 failed range [%d - %d]", __func__,
3433 CFG_OKC_FEATURE_ENABLED_MIN,
3434 CFG_OKC_FEATURE_ENABLED_MAX);
3435 ret = -EINVAL;
3436 goto exit;
3437 }
3438
3439 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3440 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3441 {
3442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3443 "Okc mode value %d is out of range"
3444 " (Min: %d Max: %d)", okcMode,
3445 CFG_OKC_FEATURE_ENABLED_MIN,
3446 CFG_OKC_FEATURE_ENABLED_MAX);
3447 ret = -EINVAL;
3448 goto exit;
3449 }
3450
3451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3452 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3453
3454 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3455 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003456#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003457 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3458 {
3459 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3460 char extra[32];
3461 tANI_U8 len = 0;
3462
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003463 len = scnprintf(extra, sizeof(extra), "%s %d",
3464 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003465 if (copy_to_user(priv_data.buf, &extra, len + 1))
3466 {
3467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3468 "%s: failed to copy data to user buffer", __func__);
3469 ret = -EFAULT;
3470 goto exit;
3471 }
3472 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303473#ifdef WLAN_FEATURE_PACKET_FILTERING
3474 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3475 {
3476 tANI_U8 filterType = 0;
3477 tANI_U8 *value = command;
3478
3479 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3480 value = value + 22;
3481
3482 /* Convert the value from ascii to integer */
3483 ret = kstrtou8(value, 10, &filterType);
3484 if (ret < 0)
3485 {
3486 /* If the input value is greater than max value of datatype,
3487 * then also kstrtou8 fails
3488 */
3489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3490 "%s: kstrtou8 failed range ", __func__);
3491 ret = -EINVAL;
3492 goto exit;
3493 }
3494
3495 if (filterType != 0 && filterType != 1)
3496 {
3497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3498 "%s: Accepted Values are 0 and 1 ", __func__);
3499 ret = -EINVAL;
3500 goto exit;
3501 }
3502 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3503 pAdapter->sessionId);
3504 }
3505#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303506 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3507 {
3508 char *dhcpPhase;
c_hpothu9b781ba2013-12-30 20:57:45 +05303509 dhcpPhase = command + 11;
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303510 if ('1' == *dhcpPhase)
3511 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303513 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303514
3515 pHddCtx->btCoexModeSet = TRUE;
3516
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303517 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303518 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303519 }
3520 else if ('2' == *dhcpPhase)
3521 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu0b0cab72014-02-13 21:52:40 +05303523 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303524
3525 pHddCtx->btCoexModeSet = FALSE;
3526
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303527 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
c_hpothu0b0cab72014-02-13 21:52:40 +05303528 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303529 }
3530 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003531 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3532 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3534 FL("making default scan to ACTIVE"));
3535 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003536 }
3537 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3538 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3540 FL("making default scan to PASSIVE"));
3541 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003542 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303543 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3544 {
3545 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3546 char extra[32];
3547 tANI_U8 len = 0;
3548
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003549 len = scnprintf(extra, sizeof(extra), "GETDWELLTIME %u\n",
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303550 (int)pCfg->nActiveMaxChnTime);
3551 if (copy_to_user(priv_data.buf, &extra, len + 1))
3552 {
3553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3554 "%s: failed to copy data to user buffer", __func__);
3555 ret = -EFAULT;
3556 goto exit;
3557 }
3558 ret = len;
3559 }
3560 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3561 {
3562 tANI_U8 *value = command;
3563 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3564 int val = 0, temp;
3565
3566 value = value + 13;
3567 temp = kstrtou32(value, 10, &val);
3568 if ( temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3569 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3570 {
3571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3572 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3573 ret = -EFAULT;
3574 goto exit;
3575 }
3576 pCfg->nActiveMaxChnTime = val;
3577 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003578 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3579 {
3580 tANI_U8 filterType = 0;
3581 tANI_U8 *value;
3582 value = command + 9;
3583
3584 /* Convert the value from ascii to integer */
3585 ret = kstrtou8(value, 10, &filterType);
3586 if (ret < 0)
3587 {
3588 /* If the input value is greater than max value of datatype,
3589 * then also kstrtou8 fails
3590 */
3591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3592 "%s: kstrtou8 failed range ", __func__);
3593 ret = -EINVAL;
3594 goto exit;
3595 }
3596 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3597 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3598 {
3599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3600 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3601 " 2-Sink ", __func__);
3602 ret = -EINVAL;
3603 goto exit;
3604 }
3605 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3606 pHddCtx->drvr_miracast = filterType;
3607 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
3608 }
Leo Chang614d2072013-08-22 14:59:44 -07003609 else if (strncmp(command, "SETMCRATE", 9) == 0)
3610 {
Leo Chang614d2072013-08-22 14:59:44 -07003611 tANI_U8 *value = command;
3612 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003613 tSirRateUpdateInd *rateUpdate;
3614 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003615
3616 /* Only valid for SAP mode */
3617 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3618 {
3619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3620 "%s: SAP mode is not running", __func__);
3621 ret = -EFAULT;
3622 goto exit;
3623 }
3624
3625 /* Move pointer to ahead of SETMCRATE<delimiter> */
3626 /* input value is in units of hundred kbps */
3627 value = value + 10;
3628 /* Convert the value from ascii to integer, decimal base */
3629 ret = kstrtouint(value, 10, &targetRate);
3630
Leo Chang1f98cbd2013-10-17 15:03:52 -07003631 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3632 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003633 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003634 hddLog(VOS_TRACE_LEVEL_ERROR,
3635 "%s: SETMCRATE indication alloc fail", __func__);
3636 ret = -EFAULT;
3637 goto exit;
3638 }
3639 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3640
3641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3642 "MC Target rate %d", targetRate);
3643 /* Ignore unicast */
3644 rateUpdate->ucastDataRate = -1;
3645 rateUpdate->mcastDataRate24GHz = targetRate;
3646 rateUpdate->mcastDataRate5GHz = targetRate;
3647 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3648 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3649 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3650 if (eHAL_STATUS_SUCCESS != status)
3651 {
3652 hddLog(VOS_TRACE_LEVEL_ERROR,
3653 "%s: SET_MC_RATE failed", __func__);
3654 vos_mem_free(rateUpdate);
3655 ret = -EFAULT;
3656 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003657 }
3658 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303659#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003660 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303661 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003662 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303663 }
3664#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003665#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003666 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3667 {
3668 tANI_U8 *value = command;
3669 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3670 tANI_U8 numChannels = 0;
3671 eHalStatus status = eHAL_STATUS_SUCCESS;
3672
3673 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3674 if (eHAL_STATUS_SUCCESS != status)
3675 {
3676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3677 "%s: Failed to parse channel list information", __func__);
3678 ret = -EINVAL;
3679 goto exit;
3680 }
3681
3682 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3683 {
3684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3685 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3686 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3687 ret = -EINVAL;
3688 goto exit;
3689 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003690 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003691 ChannelList,
3692 numChannels);
3693 if (eHAL_STATUS_SUCCESS != status)
3694 {
3695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3696 "%s: Failed to update channel list information", __func__);
3697 ret = -EINVAL;
3698 goto exit;
3699 }
3700 }
3701 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3702 {
3703 tANI_U8 *value = command;
3704 char extra[128] = {0};
3705 int len = 0;
3706 tANI_U8 tid = 0;
3707 hdd_station_ctx_t *pHddStaCtx = NULL;
3708 tAniTrafStrmMetrics tsmMetrics;
3709 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3710
3711 /* if not associated, return error */
3712 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3713 {
3714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3715 ret = -EINVAL;
3716 goto exit;
3717 }
3718
3719 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3720 value = value + 12;
3721 /* Convert the value from ascii to integer */
3722 ret = kstrtou8(value, 10, &tid);
3723 if (ret < 0)
3724 {
3725 /* If the input value is greater than max value of datatype, then also
3726 kstrtou8 fails */
3727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3728 "%s: kstrtou8 failed range [%d - %d]", __func__,
3729 TID_MIN_VALUE,
3730 TID_MAX_VALUE);
3731 ret = -EINVAL;
3732 goto exit;
3733 }
3734
3735 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3736 {
3737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3738 "tid value %d is out of range"
3739 " (Min: %d Max: %d)", tid,
3740 TID_MIN_VALUE,
3741 TID_MAX_VALUE);
3742 ret = -EINVAL;
3743 goto exit;
3744 }
3745
3746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3747 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3748
3749 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3750 {
3751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3752 "%s: failed to get tsm stats", __func__);
3753 ret = -EFAULT;
3754 goto exit;
3755 }
3756
3757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3758 "UplinkPktQueueDly(%d)\n"
3759 "UplinkPktQueueDlyHist[0](%d)\n"
3760 "UplinkPktQueueDlyHist[1](%d)\n"
3761 "UplinkPktQueueDlyHist[2](%d)\n"
3762 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303763 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003764 "UplinkPktLoss(%d)\n"
3765 "UplinkPktCount(%d)\n"
3766 "RoamingCount(%d)\n"
3767 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3768 tsmMetrics.UplinkPktQueueDlyHist[0],
3769 tsmMetrics.UplinkPktQueueDlyHist[1],
3770 tsmMetrics.UplinkPktQueueDlyHist[2],
3771 tsmMetrics.UplinkPktQueueDlyHist[3],
3772 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3773 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3774
3775 /* Output TSM stats is of the format
3776 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3777 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003778 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003779 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3780 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3781 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3782 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3783 tsmMetrics.RoamingDly);
3784
3785 if (copy_to_user(priv_data.buf, &extra, len + 1))
3786 {
3787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3788 "%s: failed to copy data to user buffer", __func__);
3789 ret = -EFAULT;
3790 goto exit;
3791 }
3792 }
3793 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3794 {
3795 tANI_U8 *value = command;
3796 tANI_U8 *cckmIe = NULL;
3797 tANI_U8 cckmIeLen = 0;
3798 eHalStatus status = eHAL_STATUS_SUCCESS;
3799
3800 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3801 if (eHAL_STATUS_SUCCESS != status)
3802 {
3803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3804 "%s: Failed to parse cckm ie data", __func__);
3805 ret = -EINVAL;
3806 goto exit;
3807 }
3808
3809 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3810 {
3811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3812 "%s: CCKM Ie input length is more than max[%d]", __func__,
3813 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003814 vos_mem_free(cckmIe);
3815 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003816 ret = -EINVAL;
3817 goto exit;
3818 }
3819 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003820 vos_mem_free(cckmIe);
3821 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003822 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003823 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
3824 {
3825 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003826 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003827 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003828 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003829 if (eHAL_STATUS_SUCCESS != status)
3830 {
3831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003832 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003833 ret = -EINVAL;
3834 goto exit;
3835 }
3836
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003837 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
3838 if (eHAL_STATUS_SUCCESS != status)
3839 {
3840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3841 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
3842 ret = -EINVAL;
3843 goto exit;
3844 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003845 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003846#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05303847 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
3848 {
3849 eHalStatus status;
3850 char buf[32], len;
3851 long waitRet;
3852 bcnMissRateContext_t getBcnMissRateCtx;
3853
3854 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3855
3856 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3857 {
3858 hddLog(VOS_TRACE_LEVEL_WARN,
3859 FL("GETBCNMISSRATE: STA is not in connected state"));
3860 ret = -1;
3861 goto exit;
3862 }
3863
3864 init_completion(&(getBcnMissRateCtx.completion));
3865 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
3866
3867 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
3868 pAdapter->sessionId,
3869 (void *)getBcnMissRateCB,
3870 (void *)(&getBcnMissRateCtx));
3871 if( eHAL_STATUS_SUCCESS != status)
3872 {
3873 hddLog(VOS_TRACE_LEVEL_INFO,
3874 FL("GETBCNMISSRATE: fail to post WDA cmd"));
3875 ret = -EINVAL;
3876 goto exit;
3877 }
3878
3879 waitRet = wait_for_completion_interruptible_timeout
3880 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
3881 if(waitRet <= 0)
3882 {
3883 hddLog(VOS_TRACE_LEVEL_ERROR,
3884 FL("failed to wait on bcnMissRateComp %d"), ret);
3885
3886 //Make magic number to zero so that callback is not called.
3887 spin_lock(&hdd_context_lock);
3888 getBcnMissRateCtx.magic = 0x0;
3889 spin_unlock(&hdd_context_lock);
3890 ret = -EINVAL;
3891 goto exit;
3892 }
3893
3894 hddLog(VOS_TRACE_LEVEL_INFO,
3895 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
3896
3897 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
3898 if (copy_to_user(priv_data.buf, &buf, len + 1))
3899 {
3900 hddLog(VOS_TRACE_LEVEL_ERROR,
3901 "%s: failed to copy data to user buffer", __func__);
3902 ret = -EFAULT;
3903 goto exit;
3904 }
3905 ret = len;
3906 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003907 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303908 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3909 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
3910 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003911 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
3912 __func__, command);
3913 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 }
3915exit:
3916 if (command)
3917 {
3918 kfree(command);
3919 }
3920 return ret;
3921}
3922
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003923#ifdef CONFIG_COMPAT
3924static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3925{
3926 struct {
3927 compat_uptr_t buf;
3928 int used_len;
3929 int total_len;
3930 } compat_priv_data;
3931 hdd_priv_data_t priv_data;
3932 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003933
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003934 /*
3935 * Note that pAdapter and ifr have already been verified by caller,
3936 * and HDD context has also been validated
3937 */
3938 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
3939 sizeof(compat_priv_data))) {
3940 ret = -EFAULT;
3941 goto exit;
3942 }
3943 priv_data.buf = compat_ptr(compat_priv_data.buf);
3944 priv_data.used_len = compat_priv_data.used_len;
3945 priv_data.total_len = compat_priv_data.total_len;
3946 ret = hdd_driver_command(pAdapter, &priv_data);
3947 exit:
3948 return ret;
3949}
3950#else /* CONFIG_COMPAT */
3951static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3952{
3953 /* will never be invoked */
3954 return 0;
3955}
3956#endif /* CONFIG_COMPAT */
3957
3958static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
3959{
3960 hdd_priv_data_t priv_data;
3961 int ret = 0;
3962
3963 /*
3964 * Note that pAdapter and ifr have already been verified by caller,
3965 * and HDD context has also been validated
3966 */
3967 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
3968 ret = -EFAULT;
3969 } else {
3970 ret = hdd_driver_command(pAdapter, &priv_data);
3971 }
3972 return ret;
3973}
3974
3975int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
3976{
3977 hdd_adapter_t *pAdapter;
3978 hdd_context_t *pHddCtx;
3979 int ret;
3980
3981 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3982 if (NULL == pAdapter) {
3983 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3984 "%s: HDD adapter context is Null", __func__);
3985 ret = -ENODEV;
3986 goto exit;
3987 }
3988 if (dev != pAdapter->dev) {
3989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3990 "%s: HDD adapter/dev inconsistency", __func__);
3991 ret = -ENODEV;
3992 goto exit;
3993 }
3994
3995 if ((!ifr) || (!ifr->ifr_data)) {
3996 ret = -EINVAL;
3997 goto exit;
3998 }
3999
4000 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4001 ret = wlan_hdd_validate_context(pHddCtx);
4002 if (ret) {
4003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4004 "%s: invalid context", __func__);
4005 ret = -EBUSY;
4006 goto exit;
4007 }
4008
4009 switch (cmd) {
4010 case (SIOCDEVPRIVATE + 1):
4011 if (is_compat_task())
4012 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4013 else
4014 ret = hdd_driver_ioctl(pAdapter, ifr);
4015 break;
4016 default:
4017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4018 __func__, cmd);
4019 ret = -EINVAL;
4020 break;
4021 }
4022 exit:
4023 return ret;
4024}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004025
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004026#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004027/**---------------------------------------------------------------------------
4028
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004029 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004030
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004031 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004032 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4033 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4034 <space>Scan Mode N<space>Meas Duration N
4035 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4036 then take N.
4037 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4038 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4039 This function does not take care of removing duplicate channels from the list
4040
4041 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004042 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004043
4044 \return - 0 for success non-zero for failure
4045
4046 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004047static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4048 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004049{
4050 tANI_U8 *inPtr = pValue;
4051 int tempInt = 0;
4052 int j = 0, i = 0, v = 0;
4053 char buf[32];
4054
4055 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4056 /*no argument after the command*/
4057 if (NULL == inPtr)
4058 {
4059 return -EINVAL;
4060 }
4061 /*no space after the command*/
4062 else if (SPACE_ASCII_VALUE != *inPtr)
4063 {
4064 return -EINVAL;
4065 }
4066
4067 /*removing empty spaces*/
4068 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4069
4070 /*no argument followed by spaces*/
4071 if ('\0' == *inPtr) return -EINVAL;
4072
4073 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004074 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004075 if (1 != v) return -EINVAL;
4076
4077 v = kstrtos32(buf, 10, &tempInt);
4078 if ( v < 0) return -EINVAL;
4079
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004080 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004081
4082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004083 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004084
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004085 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004086 {
4087 for (i = 0; i < 4; i++)
4088 {
4089 /*inPtr pointing to the beginning of first space after number of ie fields*/
4090 inPtr = strpbrk( inPtr, " " );
4091 /*no ie data after the number of ie fields argument*/
4092 if (NULL == inPtr) return -EINVAL;
4093
4094 /*removing empty space*/
4095 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4096
4097 /*no ie data after the number of ie fields argument and spaces*/
4098 if ( '\0' == *inPtr ) return -EINVAL;
4099
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004100 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004101 if (1 != v) return -EINVAL;
4102
4103 v = kstrtos32(buf, 10, &tempInt);
4104 if (v < 0) return -EINVAL;
4105
4106 switch (i)
4107 {
4108 case 0: /* Measurement token */
4109 if (tempInt <= 0)
4110 {
4111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4112 "Invalid Measurement Token(%d)", tempInt);
4113 return -EINVAL;
4114 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004115 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004116 break;
4117
4118 case 1: /* Channel number */
4119 if ((tempInt <= 0) ||
4120 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4121 {
4122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4123 "Invalid Channel Number(%d)", tempInt);
4124 return -EINVAL;
4125 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004126 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004127 break;
4128
4129 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004130 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004131 {
4132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4133 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4134 return -EINVAL;
4135 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004136 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004137 break;
4138
4139 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004140 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4141 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004142 {
4143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4144 "Invalid Measurement Duration(%d)", tempInt);
4145 return -EINVAL;
4146 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004147 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004148 break;
4149 }
4150 }
4151 }
4152
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004153 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004154 {
4155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304156 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004157 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004158 pEseBcnReq->bcnReq[j].measurementToken,
4159 pEseBcnReq->bcnReq[j].channel,
4160 pEseBcnReq->bcnReq[j].scanMode,
4161 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004162 }
4163
4164 return VOS_STATUS_SUCCESS;
4165}
4166
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004167static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4168{
4169 struct statsContext *pStatsContext = NULL;
4170 hdd_adapter_t *pAdapter = NULL;
4171
4172 if (NULL == pContext)
4173 {
4174 hddLog(VOS_TRACE_LEVEL_ERROR,
4175 "%s: Bad param, pContext [%p]",
4176 __func__, pContext);
4177 return;
4178 }
4179
Jeff Johnson72a40512013-12-19 10:14:15 -08004180 /* there is a race condition that exists between this callback
4181 function and the caller since the caller could time out either
4182 before or while this code is executing. we use a spinlock to
4183 serialize these actions */
4184 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004185
4186 pStatsContext = pContext;
4187 pAdapter = pStatsContext->pAdapter;
4188 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4189 {
4190 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004191 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004192 hddLog(VOS_TRACE_LEVEL_WARN,
4193 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4194 __func__, pAdapter, pStatsContext->magic);
4195 return;
4196 }
4197
Jeff Johnson72a40512013-12-19 10:14:15 -08004198 /* context is valid so caller is still waiting */
4199
4200 /* paranoia: invalidate the magic */
4201 pStatsContext->magic = 0;
4202
4203 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004204 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4205 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4206 tsmMetrics.UplinkPktQueueDlyHist,
4207 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4208 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4209 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4210 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4211 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4212 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4213 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4214
Jeff Johnson72a40512013-12-19 10:14:15 -08004215 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004216 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004217
4218 /* serialization is complete */
4219 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004220}
4221
4222
4223
4224static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4225 tAniTrafStrmMetrics* pTsmMetrics)
4226{
4227 hdd_station_ctx_t *pHddStaCtx = NULL;
4228 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004229 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004230 long lrc;
4231 struct statsContext context;
4232 hdd_context_t *pHddCtx = NULL;
4233
4234 if (NULL == pAdapter)
4235 {
4236 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4237 return VOS_STATUS_E_FAULT;
4238 }
4239
4240 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4241 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4242
4243 /* we are connected prepare our callback context */
4244 init_completion(&context.completion);
4245 context.pAdapter = pAdapter;
4246 context.magic = STATS_CONTEXT_MAGIC;
4247
4248 /* query tsm stats */
4249 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4250 pHddStaCtx->conn_info.staId[ 0 ],
4251 pHddStaCtx->conn_info.bssId,
4252 &context, pHddCtx->pvosContext, tid);
4253
4254 if (eHAL_STATUS_SUCCESS != hstatus)
4255 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4257 __func__);
4258 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004259 }
4260 else
4261 {
4262 /* request was sent -- wait for the response */
4263 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4264 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004265 if (lrc <= 0)
4266 {
4267 hddLog(VOS_TRACE_LEVEL_ERROR,
4268 "%s: SME %s while retrieving statistics",
4269 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004270 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004271 }
4272 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004273
Jeff Johnson72a40512013-12-19 10:14:15 -08004274 /* either we never sent a request, we sent a request and received a
4275 response or we sent a request and timed out. if we never sent a
4276 request or if we sent a request and got a response, we want to
4277 clear the magic out of paranoia. if we timed out there is a
4278 race condition such that the callback function could be
4279 executing at the same time we are. of primary concern is if the
4280 callback function had already verified the "magic" but had not
4281 yet set the completion variable when a timeout occurred. we
4282 serialize these activities by invalidating the magic while
4283 holding a shared spinlock which will cause us to block if the
4284 callback is currently executing */
4285 spin_lock(&hdd_context_lock);
4286 context.magic = 0;
4287 spin_unlock(&hdd_context_lock);
4288
4289 if (VOS_STATUS_SUCCESS == vstatus)
4290 {
4291 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4292 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4293 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4294 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4295 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4296 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4297 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4298 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4299 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4300 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4301 }
4302 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004303}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004304#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004305
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004306#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004307void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4308{
4309 eCsrBand band = -1;
4310 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4311 switch (band)
4312 {
4313 case eCSR_BAND_ALL:
4314 *pBand = WLAN_HDD_UI_BAND_AUTO;
4315 break;
4316
4317 case eCSR_BAND_24:
4318 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4319 break;
4320
4321 case eCSR_BAND_5G:
4322 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4323 break;
4324
4325 default:
4326 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4327 *pBand = -1;
4328 break;
4329 }
4330}
4331
4332/**---------------------------------------------------------------------------
4333
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004334 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4335
4336 This function parses the send action frame data passed in the format
4337 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4338
Srinivas Girigowda56076852013-08-20 14:00:50 -07004339 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004340 \param - pTargetApBssid Pointer to target Ap bssid
4341 \param - pChannel Pointer to the Target AP channel
4342 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4343 \param - pBuf Pointer to data
4344 \param - pBufLen Pointer to data length
4345
4346 \return - 0 for success non-zero for failure
4347
4348 --------------------------------------------------------------------------*/
4349VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4350 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4351{
4352 tANI_U8 *inPtr = pValue;
4353 tANI_U8 *dataEnd;
4354 int tempInt;
4355 int j = 0;
4356 int i = 0;
4357 int v = 0;
4358 tANI_U8 tempBuf[32];
4359 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004360 /* 12 hexa decimal digits, 5 ':' and '\0' */
4361 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004362
4363 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4364 /*no argument after the command*/
4365 if (NULL == inPtr)
4366 {
4367 return -EINVAL;
4368 }
4369
4370 /*no space after the command*/
4371 else if (SPACE_ASCII_VALUE != *inPtr)
4372 {
4373 return -EINVAL;
4374 }
4375
4376 /*removing empty spaces*/
4377 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4378
4379 /*no argument followed by spaces*/
4380 if ('\0' == *inPtr)
4381 {
4382 return -EINVAL;
4383 }
4384
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004385 v = sscanf(inPtr, "%17s", macAddress);
4386 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004387 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4389 "Invalid MAC address or All hex inputs are not read (%d)", v);
4390 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004391 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004392
4393 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4394 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4395 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4396 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4397 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4398 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004399
4400 /* point to the next argument */
4401 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4402 /*no argument after the command*/
4403 if (NULL == inPtr) return -EINVAL;
4404
4405 /*removing empty spaces*/
4406 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4407
4408 /*no argument followed by spaces*/
4409 if ('\0' == *inPtr)
4410 {
4411 return -EINVAL;
4412 }
4413
4414 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004415 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004416 if (1 != v) return -EINVAL;
4417
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004418 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304419 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304420 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004421
4422 *pChannel = tempInt;
4423
4424 /* point to the next argument */
4425 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4426 /*no argument after the command*/
4427 if (NULL == inPtr) return -EINVAL;
4428 /*removing empty spaces*/
4429 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4430
4431 /*no argument followed by spaces*/
4432 if ('\0' == *inPtr)
4433 {
4434 return -EINVAL;
4435 }
4436
4437 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004438 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004439 if (1 != v) return -EINVAL;
4440
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004441 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004442 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004443
4444 *pDwellTime = tempInt;
4445
4446 /* point to the next argument */
4447 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4448 /*no argument after the command*/
4449 if (NULL == inPtr) return -EINVAL;
4450 /*removing empty spaces*/
4451 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4452
4453 /*no argument followed by spaces*/
4454 if ('\0' == *inPtr)
4455 {
4456 return -EINVAL;
4457 }
4458
4459 /* find the length of data */
4460 dataEnd = inPtr;
4461 while(('\0' != *dataEnd) )
4462 {
4463 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004464 }
Kiet Lambe150c22013-11-21 16:30:32 +05304465 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004466 if ( *pBufLen <= 0) return -EINVAL;
4467
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004468 /* Allocate the number of bytes based on the number of input characters
4469 whether it is even or odd.
4470 if the number of input characters are even, then we need N/2 byte.
4471 if the number of input characters are odd, then we need do (N+1)/2 to
4472 compensate rounding off.
4473 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4474 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4475 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004476 if (NULL == *pBuf)
4477 {
4478 hddLog(VOS_TRACE_LEVEL_FATAL,
4479 "%s: vos_mem_alloc failed ", __func__);
4480 return -EINVAL;
4481 }
4482
4483 /* the buffer received from the upper layer is character buffer,
4484 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4485 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4486 and f0 in 3rd location */
4487 for (i = 0, j = 0; j < *pBufLen; j += 2)
4488 {
Kiet Lambe150c22013-11-21 16:30:32 +05304489 if( j+1 == *pBufLen)
4490 {
4491 tempByte = hdd_parse_hex(inPtr[j]);
4492 }
4493 else
4494 {
4495 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4496 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004497 (*pBuf)[i++] = tempByte;
4498 }
4499 *pBufLen = i;
4500 return VOS_STATUS_SUCCESS;
4501}
4502
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004503/**---------------------------------------------------------------------------
4504
Srinivas Girigowdade697412013-02-14 16:31:48 -08004505 \brief hdd_parse_channellist() - HDD Parse channel list
4506
4507 This function parses the channel list passed in the format
4508 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004509 if the Number of channels (N) does not match with the actual number of channels passed
4510 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4511 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4512 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4513 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004514
4515 \param - pValue Pointer to input channel list
4516 \param - ChannelList Pointer to local output array to record channel list
4517 \param - pNumChannels Pointer to number of roam scan channels
4518
4519 \return - 0 for success non-zero for failure
4520
4521 --------------------------------------------------------------------------*/
4522VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4523{
4524 tANI_U8 *inPtr = pValue;
4525 int tempInt;
4526 int j = 0;
4527 int v = 0;
4528 char buf[32];
4529
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*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004544 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004545
4546 /*no argument followed by spaces*/
4547 if ('\0' == *inPtr)
4548 {
4549 return -EINVAL;
4550 }
4551
4552 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004553 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004554 if (1 != v) return -EINVAL;
4555
Srinivas Girigowdade697412013-02-14 16:31:48 -08004556 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004557 if ((v < 0) ||
4558 (tempInt <= 0) ||
4559 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4560 {
4561 return -EINVAL;
4562 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004563
4564 *pNumChannels = tempInt;
4565
4566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4567 "Number of channels are: %d", *pNumChannels);
4568
4569 for (j = 0; j < (*pNumChannels); j++)
4570 {
4571 /*inPtr pointing to the beginning of first space after number of channels*/
4572 inPtr = strpbrk( inPtr, " " );
4573 /*no channel list after the number of channels argument*/
4574 if (NULL == inPtr)
4575 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004576 if (0 != j)
4577 {
4578 *pNumChannels = j;
4579 return VOS_STATUS_SUCCESS;
4580 }
4581 else
4582 {
4583 return -EINVAL;
4584 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004585 }
4586
4587 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004588 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004589
4590 /*no channel list after the number of channels argument and spaces*/
4591 if ( '\0' == *inPtr )
4592 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004593 if (0 != j)
4594 {
4595 *pNumChannels = j;
4596 return VOS_STATUS_SUCCESS;
4597 }
4598 else
4599 {
4600 return -EINVAL;
4601 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004602 }
4603
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004604 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004605 if (1 != v) return -EINVAL;
4606
Srinivas Girigowdade697412013-02-14 16:31:48 -08004607 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004608 if ((v < 0) ||
4609 (tempInt <= 0) ||
4610 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4611 {
4612 return -EINVAL;
4613 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004614 pChannelList[j] = tempInt;
4615
4616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4617 "Channel %d added to preferred channel list",
4618 pChannelList[j] );
4619 }
4620
Srinivas Girigowdade697412013-02-14 16:31:48 -08004621 return VOS_STATUS_SUCCESS;
4622}
4623
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004624
4625/**---------------------------------------------------------------------------
4626
4627 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4628
4629 This function parses the reasoc command data passed in the format
4630 REASSOC<space><bssid><space><channel>
4631
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004632 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004633 \param - pTargetApBssid Pointer to target Ap bssid
4634 \param - pChannel Pointer to the Target AP channel
4635
4636 \return - 0 for success non-zero for failure
4637
4638 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004639VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4640 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004641{
4642 tANI_U8 *inPtr = pValue;
4643 int tempInt;
4644 int v = 0;
4645 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004646 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004647 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004648
4649 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4650 /*no argument after the command*/
4651 if (NULL == inPtr)
4652 {
4653 return -EINVAL;
4654 }
4655
4656 /*no space after the command*/
4657 else if (SPACE_ASCII_VALUE != *inPtr)
4658 {
4659 return -EINVAL;
4660 }
4661
4662 /*removing empty spaces*/
4663 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4664
4665 /*no argument followed by spaces*/
4666 if ('\0' == *inPtr)
4667 {
4668 return -EINVAL;
4669 }
4670
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004671 v = sscanf(inPtr, "%17s", macAddress);
4672 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004673 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4675 "Invalid MAC address or All hex inputs are not read (%d)", v);
4676 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004677 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004678
4679 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4680 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4681 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4682 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4683 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4684 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004685
4686 /* point to the next argument */
4687 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4688 /*no argument after the command*/
4689 if (NULL == inPtr) return -EINVAL;
4690
4691 /*removing empty spaces*/
4692 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4693
4694 /*no argument followed by spaces*/
4695 if ('\0' == *inPtr)
4696 {
4697 return -EINVAL;
4698 }
4699
4700 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004701 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004702 if (1 != v) return -EINVAL;
4703
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004704 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004705 if ((v < 0) ||
4706 (tempInt <= 0) ||
4707 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4708 {
4709 return -EINVAL;
4710 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004711
4712 *pChannel = tempInt;
4713 return VOS_STATUS_SUCCESS;
4714}
4715
4716#endif
4717
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004718#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004719/**---------------------------------------------------------------------------
4720
4721 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4722
4723 This function parses the SETCCKM IE command
4724 SETCCKMIE<space><ie data>
4725
4726 \param - pValue Pointer to input data
4727 \param - pCckmIe Pointer to output cckm Ie
4728 \param - pCckmIeLen Pointer to output cckm ie length
4729
4730 \return - 0 for success non-zero for failure
4731
4732 --------------------------------------------------------------------------*/
4733VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4734 tANI_U8 *pCckmIeLen)
4735{
4736 tANI_U8 *inPtr = pValue;
4737 tANI_U8 *dataEnd;
4738 int j = 0;
4739 int i = 0;
4740 tANI_U8 tempByte = 0;
4741
4742 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4743 /*no argument after the command*/
4744 if (NULL == inPtr)
4745 {
4746 return -EINVAL;
4747 }
4748
4749 /*no space after the command*/
4750 else if (SPACE_ASCII_VALUE != *inPtr)
4751 {
4752 return -EINVAL;
4753 }
4754
4755 /*removing empty spaces*/
4756 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4757
4758 /*no argument followed by spaces*/
4759 if ('\0' == *inPtr)
4760 {
4761 return -EINVAL;
4762 }
4763
4764 /* find the length of data */
4765 dataEnd = inPtr;
4766 while(('\0' != *dataEnd) )
4767 {
4768 dataEnd++;
4769 ++(*pCckmIeLen);
4770 }
4771 if ( *pCckmIeLen <= 0) return -EINVAL;
4772
4773 /* Allocate the number of bytes based on the number of input characters
4774 whether it is even or odd.
4775 if the number of input characters are even, then we need N/2 byte.
4776 if the number of input characters are odd, then we need do (N+1)/2 to
4777 compensate rounding off.
4778 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4779 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4780 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
4781 if (NULL == *pCckmIe)
4782 {
4783 hddLog(VOS_TRACE_LEVEL_FATAL,
4784 "%s: vos_mem_alloc failed ", __func__);
4785 return -EINVAL;
4786 }
4787 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
4788 /* the buffer received from the upper layer is character buffer,
4789 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4790 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4791 and f0 in 3rd location */
4792 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
4793 {
4794 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4795 (*pCckmIe)[i++] = tempByte;
4796 }
4797 *pCckmIeLen = i;
4798
4799 return VOS_STATUS_SUCCESS;
4800}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004801#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004802
Jeff Johnson295189b2012-06-20 16:38:30 -07004803/**---------------------------------------------------------------------------
4804
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004805 \brief hdd_is_valid_mac_address() - Validate MAC address
4806
4807 This function validates whether the given MAC address is valid or not
4808 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
4809 where X is the hexa decimal digit character and separated by ':'
4810 This algorithm works even if MAC address is not separated by ':'
4811
4812 This code checks given input string mac contains exactly 12 hexadecimal digits.
4813 and a separator colon : appears in the input string only after
4814 an even number of hex digits.
4815
4816 \param - pMacAddr pointer to the input MAC address
4817 \return - 1 for valid and 0 for invalid
4818
4819 --------------------------------------------------------------------------*/
4820
4821v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
4822{
4823 int xdigit = 0;
4824 int separator = 0;
4825 while (*pMacAddr)
4826 {
4827 if (isxdigit(*pMacAddr))
4828 {
4829 xdigit++;
4830 }
4831 else if (':' == *pMacAddr)
4832 {
4833 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
4834 break;
4835
4836 ++separator;
4837 }
4838 else
4839 {
4840 separator = -1;
4841 /* Invalid MAC found */
4842 return 0;
4843 }
4844 ++pMacAddr;
4845 }
4846 return (xdigit == 12 && (separator == 5 || separator == 0));
4847}
4848
4849/**---------------------------------------------------------------------------
4850
Jeff Johnson295189b2012-06-20 16:38:30 -07004851 \brief hdd_open() - HDD Open function
4852
4853 This is called in response to ifconfig up
4854
4855 \param - dev Pointer to net_device structure
4856
4857 \return - 0 for success non-zero for failure
4858
4859 --------------------------------------------------------------------------*/
4860int hdd_open (struct net_device *dev)
4861{
4862 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4863 hdd_context_t *pHddCtx;
4864 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4865 VOS_STATUS status;
4866 v_BOOL_t in_standby = TRUE;
4867
4868 if (NULL == pAdapter)
4869 {
4870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304871 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004872 return -ENODEV;
4873 }
4874
4875 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304876 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4877 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004878 if (NULL == pHddCtx)
4879 {
4880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004881 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004882 return -ENODEV;
4883 }
4884
4885 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4886 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4887 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004888 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
4889 {
4890 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05304891 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004892 in_standby = FALSE;
4893 break;
4894 }
4895 else
4896 {
4897 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4898 pAdapterNode = pNext;
4899 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004900 }
4901
4902 if (TRUE == in_standby)
4903 {
4904 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
4905 {
4906 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
4907 "wlan out of power save", __func__);
4908 return -EINVAL;
4909 }
4910 }
4911
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004912 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004913 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
4914 {
4915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004916 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004917 /* Enable TX queues only when we are connected */
4918 netif_tx_start_all_queues(dev);
4919 }
4920
4921 return 0;
4922}
4923
4924int hdd_mon_open (struct net_device *dev)
4925{
4926 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4927
4928 if(pAdapter == NULL) {
4929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004930 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08004931 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 }
4933
4934 netif_start_queue(dev);
4935
4936 return 0;
4937}
4938/**---------------------------------------------------------------------------
4939
4940 \brief hdd_stop() - HDD stop function
4941
4942 This is called in response to ifconfig down
4943
4944 \param - dev Pointer to net_device structure
4945
4946 \return - 0 for success non-zero for failure
4947
4948 --------------------------------------------------------------------------*/
4949
4950int hdd_stop (struct net_device *dev)
4951{
4952 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4953 hdd_context_t *pHddCtx;
4954 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4955 VOS_STATUS status;
4956 v_BOOL_t enter_standby = TRUE;
4957
4958 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 if (NULL == pAdapter)
4960 {
4961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05304962 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004963 return -ENODEV;
4964 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304965 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
4966 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07004967 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
4968 if (NULL == pHddCtx)
4969 {
4970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004971 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004972 return -ENODEV;
4973 }
4974
Jeff Johnson6a81ca42013-04-05 10:37:08 -07004975 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07004976 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
4977 netif_tx_disable(pAdapter->dev);
4978 netif_carrier_off(pAdapter->dev);
4979
4980
4981 /* SoftAP ifaces should never go in power save mode
4982 making sure same here. */
4983 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
4984 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004985 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07004986 )
4987 {
4988 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4990 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004991 EXIT();
4992 return 0;
4993 }
4994
4995 /* Find if any iface is up then
4996 if any iface is up then can't put device to sleep/ power save mode. */
4997 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4998 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
4999 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005000 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5001 {
5002 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305003 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005004 enter_standby = FALSE;
5005 break;
5006 }
5007 else
5008 {
5009 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5010 pAdapterNode = pNext;
5011 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005012 }
5013
5014 if (TRUE == enter_standby)
5015 {
5016 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5017 "entering standby", __func__);
5018 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5019 {
5020 /*log and return success*/
5021 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5022 "wlan in power save", __func__);
5023 }
5024 }
5025
5026 EXIT();
5027 return 0;
5028}
5029
5030/**---------------------------------------------------------------------------
5031
5032 \brief hdd_uninit() - HDD uninit function
5033
5034 This is called during the netdev unregister to uninitialize all data
5035associated with the device
5036
5037 \param - dev Pointer to net_device structure
5038
5039 \return - void
5040
5041 --------------------------------------------------------------------------*/
5042static void hdd_uninit (struct net_device *dev)
5043{
5044 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5045
5046 ENTER();
5047
5048 do
5049 {
5050 if (NULL == pAdapter)
5051 {
5052 hddLog(VOS_TRACE_LEVEL_FATAL,
5053 "%s: NULL pAdapter", __func__);
5054 break;
5055 }
5056
5057 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5058 {
5059 hddLog(VOS_TRACE_LEVEL_FATAL,
5060 "%s: Invalid magic", __func__);
5061 break;
5062 }
5063
5064 if (NULL == pAdapter->pHddCtx)
5065 {
5066 hddLog(VOS_TRACE_LEVEL_FATAL,
5067 "%s: NULL pHddCtx", __func__);
5068 break;
5069 }
5070
5071 if (dev != pAdapter->dev)
5072 {
5073 hddLog(VOS_TRACE_LEVEL_FATAL,
5074 "%s: Invalid device reference", __func__);
5075 /* we haven't validated all cases so let this go for now */
5076 }
5077
5078 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5079
5080 /* after uninit our adapter structure will no longer be valid */
5081 pAdapter->dev = NULL;
5082 pAdapter->magic = 0;
5083 } while (0);
5084
5085 EXIT();
5086}
5087
5088/**---------------------------------------------------------------------------
5089
5090 \brief hdd_release_firmware() -
5091
5092 This function calls the release firmware API to free the firmware buffer.
5093
5094 \param - pFileName Pointer to the File Name.
5095 pCtx - Pointer to the adapter .
5096
5097
5098 \return - 0 for success, non zero for failure
5099
5100 --------------------------------------------------------------------------*/
5101
5102VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5103{
5104 VOS_STATUS status = VOS_STATUS_SUCCESS;
5105 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5106 ENTER();
5107
5108
5109 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5110
5111 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5112
5113 if(pHddCtx->fw) {
5114 release_firmware(pHddCtx->fw);
5115 pHddCtx->fw = NULL;
5116 }
5117 else
5118 status = VOS_STATUS_E_FAILURE;
5119 }
5120 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5121 if(pHddCtx->nv) {
5122 release_firmware(pHddCtx->nv);
5123 pHddCtx->nv = NULL;
5124 }
5125 else
5126 status = VOS_STATUS_E_FAILURE;
5127
5128 }
5129
5130 EXIT();
5131 return status;
5132}
5133
5134/**---------------------------------------------------------------------------
5135
5136 \brief hdd_request_firmware() -
5137
5138 This function reads the firmware file using the request firmware
5139 API and returns the the firmware data and the firmware file size.
5140
5141 \param - pfileName - Pointer to the file name.
5142 - pCtx - Pointer to the adapter .
5143 - ppfw_data - Pointer to the pointer of the firmware data.
5144 - pSize - Pointer to the file size.
5145
5146 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5147
5148 --------------------------------------------------------------------------*/
5149
5150
5151VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5152{
5153 int status;
5154 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5155 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5156 ENTER();
5157
5158 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5159
5160 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5161
5162 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5163 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5164 __func__, pfileName);
5165 retval = VOS_STATUS_E_FAILURE;
5166 }
5167
5168 else {
5169 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5170 *pSize = pHddCtx->fw->size;
5171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5172 __func__, *pSize);
5173 }
5174 }
5175 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5176
5177 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5178
5179 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5180 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5181 __func__, pfileName);
5182 retval = VOS_STATUS_E_FAILURE;
5183 }
5184
5185 else {
5186 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5187 *pSize = pHddCtx->nv->size;
5188 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5189 __func__, *pSize);
5190 }
5191 }
5192
5193 EXIT();
5194 return retval;
5195}
5196/**---------------------------------------------------------------------------
5197 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5198
5199 This is the function invoked by SME to inform the result of a full power
5200 request issued by HDD
5201
5202 \param - callbackcontext - Pointer to cookie
5203 status - result of request
5204
5205 \return - None
5206
5207--------------------------------------------------------------------------*/
5208void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5209{
5210 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5211
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005212 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005213 if(&pHddCtx->full_pwr_comp_var)
5214 {
5215 complete(&pHddCtx->full_pwr_comp_var);
5216 }
5217}
5218
5219/**---------------------------------------------------------------------------
5220
5221 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5222
5223 This is the function invoked by SME to inform the result of BMPS
5224 request issued by HDD
5225
5226 \param - callbackcontext - Pointer to cookie
5227 status - result of request
5228
5229 \return - None
5230
5231--------------------------------------------------------------------------*/
5232void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5233{
5234
5235 struct completion *completion_var = (struct completion*) callbackContext;
5236
Arif Hussain6d2a3322013-11-17 19:50:10 -08005237 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005238 if(completion_var != NULL)
5239 {
5240 complete(completion_var);
5241 }
5242}
5243
5244/**---------------------------------------------------------------------------
5245
5246 \brief hdd_get_cfg_file_size() -
5247
5248 This function reads the configuration file using the request firmware
5249 API and returns the configuration file size.
5250
5251 \param - pCtx - Pointer to the adapter .
5252 - pFileName - Pointer to the file name.
5253 - pBufSize - Pointer to the buffer size.
5254
5255 \return - 0 for success, non zero for failure
5256
5257 --------------------------------------------------------------------------*/
5258
5259VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5260{
5261 int status;
5262 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5263
5264 ENTER();
5265
5266 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5267
5268 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5269 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5270 status = VOS_STATUS_E_FAILURE;
5271 }
5272 else {
5273 *pBufSize = pHddCtx->fw->size;
5274 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5275 release_firmware(pHddCtx->fw);
5276 pHddCtx->fw = NULL;
5277 }
5278
5279 EXIT();
5280 return VOS_STATUS_SUCCESS;
5281}
5282
5283/**---------------------------------------------------------------------------
5284
5285 \brief hdd_read_cfg_file() -
5286
5287 This function reads the configuration file using the request firmware
5288 API and returns the cfg data and the buffer size of the configuration file.
5289
5290 \param - pCtx - Pointer to the adapter .
5291 - pFileName - Pointer to the file name.
5292 - pBuffer - Pointer to the data buffer.
5293 - pBufSize - Pointer to the buffer size.
5294
5295 \return - 0 for success, non zero for failure
5296
5297 --------------------------------------------------------------------------*/
5298
5299VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5300 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5301{
5302 int status;
5303 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5304
5305 ENTER();
5306
5307 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5308
5309 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5310 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5311 return VOS_STATUS_E_FAILURE;
5312 }
5313 else {
5314 if(*pBufSize != pHddCtx->fw->size) {
5315 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5316 "file size", __func__);
5317 release_firmware(pHddCtx->fw);
5318 pHddCtx->fw = NULL;
5319 return VOS_STATUS_E_FAILURE;
5320 }
5321 else {
5322 if(pBuffer) {
5323 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5324 }
5325 release_firmware(pHddCtx->fw);
5326 pHddCtx->fw = NULL;
5327 }
5328 }
5329
5330 EXIT();
5331
5332 return VOS_STATUS_SUCCESS;
5333}
5334
5335/**---------------------------------------------------------------------------
5336
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 \brief hdd_set_mac_address() -
5338
5339 This function sets the user specified mac address using
5340 the command ifconfig wlanX hw ether <mac adress>.
5341
5342 \param - dev - Pointer to the net device.
5343 - addr - Pointer to the sockaddr.
5344 \return - 0 for success, non zero for failure
5345
5346 --------------------------------------------------------------------------*/
5347
5348static int hdd_set_mac_address(struct net_device *dev, void *addr)
5349{
5350 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5351 struct sockaddr *psta_mac_addr = addr;
5352 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5353
5354 ENTER();
5355
5356 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
5357
5358#ifdef HDD_SESSIONIZE
5359 // set the MAC address though the STA ID CFG.
5360 halStatus = ccmCfgSetStr( pAdapter->hHal, WNI_CFG_STA_ID,
5361 (v_U8_t *)&pAdapter->macAddressCurrent,
5362 sizeof( pAdapter->macAddressCurrent ),
5363 hdd_set_mac_addr_cb, VOS_FALSE );
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305364
5365 if(eHAL_STATUS_SUCCESS != halStatus)
5366 {
5367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5368 "%s: failed to set MAC address in CFG", __func__);
5369 }
5370
Jeff Johnson295189b2012-06-20 16:38:30 -07005371#endif
5372
5373 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5374
5375 EXIT();
5376 return halStatus;
5377}
5378
5379tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5380{
5381 int i;
5382 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5383 {
Abhishek Singheb183782014-02-06 13:37:21 +05305384 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005385 break;
5386 }
5387
5388 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5389 return NULL;
5390
5391 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5392 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5393}
5394
5395void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5396{
5397 int i;
5398 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5399 {
5400 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5401 {
5402 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5403 break;
5404 }
5405 }
5406 return;
5407}
5408
5409#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5410 static struct net_device_ops wlan_drv_ops = {
5411 .ndo_open = hdd_open,
5412 .ndo_stop = hdd_stop,
5413 .ndo_uninit = hdd_uninit,
5414 .ndo_start_xmit = hdd_hard_start_xmit,
5415 .ndo_tx_timeout = hdd_tx_timeout,
5416 .ndo_get_stats = hdd_stats,
5417 .ndo_do_ioctl = hdd_ioctl,
5418 .ndo_set_mac_address = hdd_set_mac_address,
5419 .ndo_select_queue = hdd_select_queue,
5420#ifdef WLAN_FEATURE_PACKET_FILTERING
5421#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5422 .ndo_set_rx_mode = hdd_set_multicast_list,
5423#else
5424 .ndo_set_multicast_list = hdd_set_multicast_list,
5425#endif //LINUX_VERSION_CODE
5426#endif
5427 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005428 static struct net_device_ops wlan_mon_drv_ops = {
5429 .ndo_open = hdd_mon_open,
5430 .ndo_stop = hdd_stop,
5431 .ndo_uninit = hdd_uninit,
5432 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5433 .ndo_tx_timeout = hdd_tx_timeout,
5434 .ndo_get_stats = hdd_stats,
5435 .ndo_do_ioctl = hdd_ioctl,
5436 .ndo_set_mac_address = hdd_set_mac_address,
5437 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005438
5439#endif
5440
5441void hdd_set_station_ops( struct net_device *pWlanDev )
5442{
5443#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005444 pWlanDev->netdev_ops = &wlan_drv_ops;
5445#else
5446 pWlanDev->open = hdd_open;
5447 pWlanDev->stop = hdd_stop;
5448 pWlanDev->uninit = hdd_uninit;
5449 pWlanDev->hard_start_xmit = NULL;
5450 pWlanDev->tx_timeout = hdd_tx_timeout;
5451 pWlanDev->get_stats = hdd_stats;
5452 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005453 pWlanDev->set_mac_address = hdd_set_mac_address;
5454#endif
5455}
5456
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005457static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005458{
5459 struct net_device *pWlanDev = NULL;
5460 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 /*
5462 * cfg80211 initialization and registration....
5463 */
5464 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5465
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 if(pWlanDev != NULL)
5467 {
5468
5469 //Save the pointer to the net_device in the HDD adapter
5470 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5471
Jeff Johnson295189b2012-06-20 16:38:30 -07005472 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5473
5474 pAdapter->dev = pWlanDev;
5475 pAdapter->pHddCtx = pHddCtx;
5476 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
5477
5478 init_completion(&pAdapter->session_open_comp_var);
5479 init_completion(&pAdapter->session_close_comp_var);
5480 init_completion(&pAdapter->disconnect_comp_var);
5481 init_completion(&pAdapter->linkup_event_var);
5482 init_completion(&pAdapter->cancel_rem_on_chan_var);
5483 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305484 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005485#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5486 init_completion(&pAdapter->offchannel_tx_event);
5487#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005489#ifdef FEATURE_WLAN_TDLS
5490 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005491 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005492 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305493 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005494#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005495 init_completion(&pHddCtx->mc_sus_event_var);
5496 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305497 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005498 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005499 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005500
Rajeev79dbe4c2013-10-05 11:03:42 +05305501#ifdef FEATURE_WLAN_BATCH_SCAN
5502 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5503 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5504 pAdapter->pBatchScanRsp = NULL;
5505 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005506 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005507 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305508 mutex_init(&pAdapter->hdd_batch_scan_lock);
5509#endif
5510
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 pAdapter->isLinkUpSvcNeeded = FALSE;
5512 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5513 //Init the net_device structure
5514 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5515
5516 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5517 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5518 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5519 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5520
5521 hdd_set_station_ops( pAdapter->dev );
5522
5523 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5525 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5526 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 /* set pWlanDev's parent to underlying device */
5528 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
5529 }
5530
5531 return pAdapter;
5532}
5533
5534VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5535{
5536 struct net_device *pWlanDev = pAdapter->dev;
5537 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5538 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5539 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5540
5541 if( rtnl_lock_held )
5542 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005543 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005544 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5545 {
5546 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5547 return VOS_STATUS_E_FAILURE;
5548 }
5549 }
5550 if (register_netdevice(pWlanDev))
5551 {
5552 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5553 return VOS_STATUS_E_FAILURE;
5554 }
5555 }
5556 else
5557 {
5558 if(register_netdev(pWlanDev))
5559 {
5560 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5561 return VOS_STATUS_E_FAILURE;
5562 }
5563 }
5564 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5565
5566 return VOS_STATUS_SUCCESS;
5567}
5568
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005569static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005570{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005571 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005572
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005573 if (NULL == pAdapter)
5574 {
5575 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5576 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005577 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005578
5579 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5580 {
5581 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5582 return eHAL_STATUS_NOT_INITIALIZED;
5583 }
5584
5585 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5586
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005587#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005588 /* need to make sure all of our scheduled work has completed.
5589 * This callback is called from MC thread context, so it is safe to
5590 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005591 *
5592 * Even though this is called from MC thread context, if there is a faulty
5593 * work item in the system, that can hang this call forever. So flushing
5594 * this global work queue is not safe; and now we make sure that
5595 * individual work queues are stopped correctly. But the cancel work queue
5596 * is a GPL only API, so the proprietary version of the driver would still
5597 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005598 */
5599 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005600#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005601
5602 /* We can be blocked while waiting for scheduled work to be
5603 * flushed, and the adapter structure can potentially be freed, in
5604 * which case the magic will have been reset. So make sure the
5605 * magic is still good, and hence the adapter structure is still
5606 * valid, before signaling completion */
5607 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5608 {
5609 complete(&pAdapter->session_close_comp_var);
5610 }
5611
Jeff Johnson295189b2012-06-20 16:38:30 -07005612 return eHAL_STATUS_SUCCESS;
5613}
5614
5615VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5616{
5617 struct net_device *pWlanDev = pAdapter->dev;
5618 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5619 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5620 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5621 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305622 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005623
5624 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005625 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005626 //Open a SME session for future operation
5627 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005628 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5630 {
5631 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005632 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 halStatus, halStatus );
5634 status = VOS_STATUS_E_FAILURE;
5635 goto error_sme_open;
5636 }
5637
5638 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305639 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 &pAdapter->session_open_comp_var,
5641 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305642 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005643 {
5644 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305645 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005646 status = VOS_STATUS_E_FAILURE;
5647 goto error_sme_open;
5648 }
5649
5650 // Register wireless extensions
5651 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5652 {
5653 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005654 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005655 halStatus, halStatus );
5656 status = VOS_STATUS_E_FAILURE;
5657 goto error_register_wext;
5658 }
5659 //Safe to register the hard_start_xmit function again
5660#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5661 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
5662#else
5663 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
5664#endif
5665
5666 //Set the Connection State to Not Connected
5667 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5668
5669 //Set the default operation channel
5670 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5671
5672 /* Make the default Auth Type as OPEN*/
5673 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5674
5675 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5676 {
5677 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005678 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005679 status, status );
5680 goto error_init_txrx;
5681 }
5682
5683 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5684
5685 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5686 {
5687 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005688 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005689 status, status );
5690 goto error_wmm_init;
5691 }
5692
5693 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5694
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005695#ifdef FEATURE_WLAN_TDLS
5696 if(0 != wlan_hdd_tdls_init(pAdapter))
5697 {
5698 status = VOS_STATUS_E_FAILURE;
5699 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5700 goto error_tdls_init;
5701 }
5702 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5703#endif
5704
Jeff Johnson295189b2012-06-20 16:38:30 -07005705 return VOS_STATUS_SUCCESS;
5706
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005707#ifdef FEATURE_WLAN_TDLS
5708error_tdls_init:
5709 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5710 hdd_wmm_adapter_close(pAdapter);
5711#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005712error_wmm_init:
5713 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5714 hdd_deinit_tx_rx(pAdapter);
5715error_init_txrx:
5716 hdd_UnregisterWext(pWlanDev);
5717error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005718 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005719 {
5720 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005721 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005723 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305725 unsigned long rc;
5726
Jeff Johnson295189b2012-06-20 16:38:30 -07005727 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305728 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005729 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005730 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305731 if (rc <= 0)
5732 hddLog(VOS_TRACE_LEVEL_ERROR,
5733 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005734 }
5735}
5736error_sme_open:
5737 return status;
5738}
5739
Jeff Johnson295189b2012-06-20 16:38:30 -07005740void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5741{
5742 hdd_cfg80211_state_t *cfgState;
5743
5744 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5745
5746 if( NULL != cfgState->buf )
5747 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305748 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5750 rc = wait_for_completion_interruptible_timeout(
5751 &pAdapter->tx_action_cnf_event,
5752 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305753 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005754 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305756 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5757 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005758 }
5759 }
5760 return;
5761}
Jeff Johnson295189b2012-06-20 16:38:30 -07005762
5763void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5764{
5765 ENTER();
5766 switch ( pAdapter->device_mode )
5767 {
5768 case WLAN_HDD_INFRA_STATION:
5769 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005770 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005771 {
5772 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5773 {
5774 hdd_deinit_tx_rx( pAdapter );
5775 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5776 }
5777
5778 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5779 {
5780 hdd_wmm_adapter_close( pAdapter );
5781 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5782 }
5783
Jeff Johnson295189b2012-06-20 16:38:30 -07005784 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005785#ifdef FEATURE_WLAN_TDLS
5786 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5787 {
5788 wlan_hdd_tdls_exit(pAdapter);
5789 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5790 }
5791#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005792
5793 break;
5794 }
5795
5796 case WLAN_HDD_SOFTAP:
5797 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305799
5800 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5801 {
5802 hdd_wmm_adapter_close( pAdapter );
5803 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5804 }
5805
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005807
5808 hdd_unregister_hostapd(pAdapter);
5809 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005810 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 break;
5812 }
5813
5814 case WLAN_HDD_MONITOR:
5815 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005816 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5818 {
5819 hdd_deinit_tx_rx( pAdapter );
5820 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5821 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005822 if(NULL != pAdapterforTx)
5823 {
5824 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5825 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 break;
5827 }
5828
5829
5830 default:
5831 break;
5832 }
5833
5834 EXIT();
5835}
5836
5837void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5838{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005839 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305840
5841 ENTER();
5842 if (NULL == pAdapter)
5843 {
5844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5845 "%s: HDD adapter is Null", __func__);
5846 return;
5847 }
5848
5849 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005850
Rajeev79dbe4c2013-10-05 11:03:42 +05305851#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305852 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5853 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005854 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305855 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5856 )
5857 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005858 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305859 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005860 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5861 {
5862 hdd_deinit_batch_scan(pAdapter);
5863 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305864 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005865 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305866#endif
5867
Jeff Johnson295189b2012-06-20 16:38:30 -07005868 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5869 if( rtnl_held )
5870 {
5871 unregister_netdevice(pWlanDev);
5872 }
5873 else
5874 {
5875 unregister_netdev(pWlanDev);
5876 }
5877 // note that the pAdapter is no longer valid at this point
5878 // since the memory has been reclaimed
5879 }
5880
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305881 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005882}
5883
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005884void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5885{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305886 VOS_STATUS status;
5887 hdd_adapter_t *pAdapter = NULL;
5888 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005889
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305890 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005891
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305892 /*loop through all adapters.*/
5893 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005894 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305895 pAdapter = pAdapterNode->pAdapter;
5896 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5897 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005898
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305899 { // we skip this registration for modes other than STA and P2P client modes.
5900 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5901 pAdapterNode = pNext;
5902 continue;
5903 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005904
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305905 //Apply Dynamic DTIM For P2P
5906 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5907 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5908 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5909 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5910 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5911 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5912 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5913 (eConnectionState_Associated ==
5914 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5915 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5916 {
5917 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005918
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305919 powerRequest.uIgnoreDTIM = 1;
5920 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5921
5922 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5923 {
5924 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5925 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5926 }
5927 else
5928 {
5929 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5930 }
5931
5932 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5933 * specified during Enter/Exit BMPS when LCD off*/
5934 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5935 NULL, eANI_BOOLEAN_FALSE);
5936 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5937 NULL, eANI_BOOLEAN_FALSE);
5938
5939 /* switch to the DTIM specified in cfg.ini */
5940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5941 "Switch to DTIM %d", powerRequest.uListenInterval);
5942 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5943 break;
5944
5945 }
5946
5947 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5948 pAdapterNode = pNext;
5949 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005950}
5951
5952void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5953{
5954 /*Switch back to DTIM 1*/
5955 tSirSetPowerParamsReq powerRequest = { 0 };
5956
5957 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5958 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005959 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005960
5961 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5962 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5963 NULL, eANI_BOOLEAN_FALSE);
5964 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5965 NULL, eANI_BOOLEAN_FALSE);
5966
5967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5968 "Switch to DTIM%d",powerRequest.uListenInterval);
5969 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5970
5971}
5972
Jeff Johnson295189b2012-06-20 16:38:30 -07005973VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5974{
5975 VOS_STATUS status = VOS_STATUS_SUCCESS;
5976
5977 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5978 {
5979 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5980 }
5981
5982 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5983 {
5984 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5985 }
5986
5987 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5988 {
5989 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5990 }
5991
5992 return status;
5993}
5994
5995VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
5996{
5997 hdd_adapter_t *pAdapter = NULL;
5998 eHalStatus halStatus;
5999 VOS_STATUS status = VOS_STATUS_E_INVAL;
6000 v_BOOL_t disableBmps = FALSE;
6001 v_BOOL_t disableImps = FALSE;
6002
6003 switch(session_type)
6004 {
6005 case WLAN_HDD_INFRA_STATION:
6006 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 case WLAN_HDD_P2P_CLIENT:
6008 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006009 //Exit BMPS -> Is Sta/P2P Client is already connected
6010 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6011 if((NULL != pAdapter)&&
6012 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6013 {
6014 disableBmps = TRUE;
6015 }
6016
6017 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6018 if((NULL != pAdapter)&&
6019 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6020 {
6021 disableBmps = TRUE;
6022 }
6023
6024 //Exit both Bmps and Imps incase of Go/SAP Mode
6025 if((WLAN_HDD_SOFTAP == session_type) ||
6026 (WLAN_HDD_P2P_GO == session_type))
6027 {
6028 disableBmps = TRUE;
6029 disableImps = TRUE;
6030 }
6031
6032 if(TRUE == disableImps)
6033 {
6034 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6035 {
6036 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6037 }
6038 }
6039
6040 if(TRUE == disableBmps)
6041 {
6042 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6043 {
6044 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6045
6046 if(eHAL_STATUS_SUCCESS != halStatus)
6047 {
6048 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006049 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 VOS_ASSERT(0);
6051 return status;
6052 }
6053 }
6054
6055 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6056 {
6057 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6058
6059 if(eHAL_STATUS_SUCCESS != halStatus)
6060 {
6061 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006062 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 VOS_ASSERT(0);
6064 return status;
6065 }
6066 }
6067 }
6068
6069 if((TRUE == disableBmps) ||
6070 (TRUE == disableImps))
6071 {
6072 /* Now, get the chip into Full Power now */
6073 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6074 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6075 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6076
6077 if(halStatus != eHAL_STATUS_SUCCESS)
6078 {
6079 if(halStatus == eHAL_STATUS_PMC_PENDING)
6080 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306081 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006082 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306083 ret = wait_for_completion_interruptible_timeout(
6084 &pHddCtx->full_pwr_comp_var,
6085 msecs_to_jiffies(1000));
6086 if (ret <= 0)
6087 {
6088 hddLog(VOS_TRACE_LEVEL_ERROR,
6089 "%s: wait on full_pwr_comp_var failed %ld",
6090 __func__, ret);
6091 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006092 }
6093 else
6094 {
6095 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006096 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 VOS_ASSERT(0);
6098 return status;
6099 }
6100 }
6101
6102 status = VOS_STATUS_SUCCESS;
6103 }
6104
6105 break;
6106 }
6107 return status;
6108}
6109
6110hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006111 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 tANI_U8 rtnl_held )
6113{
6114 hdd_adapter_t *pAdapter = NULL;
6115 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6116 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6117 VOS_STATUS exitbmpsStatus;
6118
Arif Hussain6d2a3322013-11-17 19:50:10 -08006119 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006120
Nirav Shah436658f2014-02-28 17:05:45 +05306121 if(macAddr == NULL)
6122 {
6123 /* Not received valid macAddr */
6124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6125 "%s:Unable to add virtual intf: Not able to get"
6126 "valid mac address",__func__);
6127 return NULL;
6128 }
6129
Jeff Johnson295189b2012-06-20 16:38:30 -07006130 //Disable BMPS incase of Concurrency
6131 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6132
6133 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6134 {
6135 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306136 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006137 VOS_ASSERT(0);
6138 return NULL;
6139 }
6140
6141 switch(session_type)
6142 {
6143 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006144 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006145 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006146 {
6147 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6148
6149 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306150 {
6151 hddLog(VOS_TRACE_LEVEL_FATAL,
6152 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006153 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306154 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006155
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306156#ifdef FEATURE_WLAN_TDLS
6157 /* A Mutex Lock is introduced while changing/initializing the mode to
6158 * protect the concurrent access for the Adapters by TDLS module.
6159 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306160 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306161#endif
6162
Jeff Johnsone7245742012-09-05 17:12:55 -07006163 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6164 NL80211_IFTYPE_P2P_CLIENT:
6165 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006166
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306168#ifdef FEATURE_WLAN_TDLS
6169 mutex_unlock(&pHddCtx->tdls_lock);
6170#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306171
6172 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006173 if( VOS_STATUS_SUCCESS != status )
6174 goto err_free_netdev;
6175
6176 status = hdd_register_interface( pAdapter, rtnl_held );
6177 if( VOS_STATUS_SUCCESS != status )
6178 {
6179 hdd_deinit_adapter(pHddCtx, pAdapter);
6180 goto err_free_netdev;
6181 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306182
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306183 // Workqueue which gets scheduled in IPv4 notification callback.
6184 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6185
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306186#ifdef WLAN_NS_OFFLOAD
6187 // Workqueue which gets scheduled in IPv6 notification callback.
6188 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6189#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006190 //Stop the Interface TX queue.
6191 netif_tx_disable(pAdapter->dev);
6192 //netif_tx_disable(pWlanDev);
6193 netif_carrier_off(pAdapter->dev);
6194
6195 break;
6196 }
6197
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 case WLAN_HDD_SOFTAP:
6200 {
6201 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6202 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306203 {
6204 hddLog(VOS_TRACE_LEVEL_FATAL,
6205 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006206 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306207 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006208
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6210 NL80211_IFTYPE_AP:
6211 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 pAdapter->device_mode = session_type;
6213
6214 status = hdd_init_ap_mode(pAdapter);
6215 if( VOS_STATUS_SUCCESS != status )
6216 goto err_free_netdev;
6217
6218 status = hdd_register_hostapd( pAdapter, rtnl_held );
6219 if( VOS_STATUS_SUCCESS != status )
6220 {
6221 hdd_deinit_adapter(pHddCtx, pAdapter);
6222 goto err_free_netdev;
6223 }
6224
6225 netif_tx_disable(pAdapter->dev);
6226 netif_carrier_off(pAdapter->dev);
6227
6228 hdd_set_conparam( 1 );
6229 break;
6230 }
6231 case WLAN_HDD_MONITOR:
6232 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006233 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6234 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306235 {
6236 hddLog(VOS_TRACE_LEVEL_FATAL,
6237 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306239 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006240
6241 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6242 pAdapter->device_mode = session_type;
6243 status = hdd_register_interface( pAdapter, rtnl_held );
6244#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6245 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6246#else
6247 pAdapter->dev->open = hdd_mon_open;
6248 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6249#endif
6250 hdd_init_tx_rx( pAdapter );
6251 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6252 //Set adapter to be used for data tx. It will use either GO or softap.
6253 pAdapter->sessionCtx.monitor.pAdapterForTx =
6254 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006255 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6256 {
6257 pAdapter->sessionCtx.monitor.pAdapterForTx =
6258 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6259 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006260 /* This workqueue will be used to transmit management packet over
6261 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006262 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6263 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6264 return NULL;
6265 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006266
Jeff Johnson295189b2012-06-20 16:38:30 -07006267 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6268 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006269 }
6270 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006271 case WLAN_HDD_FTM:
6272 {
6273 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6274
6275 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306276 {
6277 hddLog(VOS_TRACE_LEVEL_FATAL,
6278 FL("failed to allocate adapter for session %d"), session_type);
6279 return NULL;
6280 }
6281
Jeff Johnson295189b2012-06-20 16:38:30 -07006282 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6283 * message while loading driver in FTM mode. */
6284 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6285 pAdapter->device_mode = session_type;
6286 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306287
6288 hdd_init_tx_rx( pAdapter );
6289
6290 //Stop the Interface TX queue.
6291 netif_tx_disable(pAdapter->dev);
6292 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 }
6294 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 default:
6296 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306297 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6298 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006299 VOS_ASSERT(0);
6300 return NULL;
6301 }
6302 }
6303
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 if( VOS_STATUS_SUCCESS == status )
6305 {
6306 //Add it to the hdd's session list.
6307 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6308 if( NULL == pHddAdapterNode )
6309 {
6310 status = VOS_STATUS_E_NOMEM;
6311 }
6312 else
6313 {
6314 pHddAdapterNode->pAdapter = pAdapter;
6315 status = hdd_add_adapter_back ( pHddCtx,
6316 pHddAdapterNode );
6317 }
6318 }
6319
6320 if( VOS_STATUS_SUCCESS != status )
6321 {
6322 if( NULL != pAdapter )
6323 {
6324 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6325 pAdapter = NULL;
6326 }
6327 if( NULL != pHddAdapterNode )
6328 {
6329 vos_mem_free( pHddAdapterNode );
6330 }
6331
6332 goto resume_bmps;
6333 }
6334
6335 if(VOS_STATUS_SUCCESS == status)
6336 {
6337 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6338
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006339 //Initialize the WoWL service
6340 if(!hdd_init_wowl(pAdapter))
6341 {
6342 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6343 goto err_free_netdev;
6344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 return pAdapter;
6347
6348err_free_netdev:
6349 free_netdev(pAdapter->dev);
6350 wlan_hdd_release_intf_addr( pHddCtx,
6351 pAdapter->macAddressCurrent.bytes );
6352
6353resume_bmps:
6354 //If bmps disabled enable it
6355 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6356 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306357 if (pHddCtx->hdd_wlan_suspended)
6358 {
6359 hdd_set_pwrparams(pHddCtx);
6360 }
6361 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 }
6363 return NULL;
6364}
6365
6366VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6367 tANI_U8 rtnl_held )
6368{
6369 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6370 VOS_STATUS status;
6371
6372 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6373 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306374 {
6375 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6376 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306378 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006379
6380 while ( pCurrent->pAdapter != pAdapter )
6381 {
6382 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6383 if( VOS_STATUS_SUCCESS != status )
6384 break;
6385
6386 pCurrent = pNext;
6387 }
6388 pAdapterNode = pCurrent;
6389 if( VOS_STATUS_SUCCESS == status )
6390 {
6391 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6392 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306393
6394#ifdef FEATURE_WLAN_TDLS
6395
6396 /* A Mutex Lock is introduced while changing/initializing the mode to
6397 * protect the concurrent access for the Adapters by TDLS module.
6398 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306399 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306400#endif
6401
Jeff Johnson295189b2012-06-20 16:38:30 -07006402 hdd_remove_adapter( pHddCtx, pAdapterNode );
6403 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006404 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006405
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306406#ifdef FEATURE_WLAN_TDLS
6407 mutex_unlock(&pHddCtx->tdls_lock);
6408#endif
6409
Jeff Johnson295189b2012-06-20 16:38:30 -07006410
6411 /* If there is a single session of STA/P2P client, re-enable BMPS */
6412 if ((!vos_concurrent_sessions_running()) &&
6413 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6414 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6415 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306416 if (pHddCtx->hdd_wlan_suspended)
6417 {
6418 hdd_set_pwrparams(pHddCtx);
6419 }
6420 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 }
6422
6423 return VOS_STATUS_SUCCESS;
6424 }
6425
6426 return VOS_STATUS_E_FAILURE;
6427}
6428
6429VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6430{
6431 hdd_adapter_list_node_t *pHddAdapterNode;
6432 VOS_STATUS status;
6433
6434 ENTER();
6435
6436 do
6437 {
6438 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6439 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6440 {
6441 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6442 vos_mem_free( pHddAdapterNode );
6443 }
6444 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6445
6446 EXIT();
6447
6448 return VOS_STATUS_SUCCESS;
6449}
6450
6451void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6452{
6453 v_U8_t addIE[1] = {0};
6454
6455 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6456 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6457 eANI_BOOLEAN_FALSE) )
6458 {
6459 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006460 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 }
6462
6463 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6464 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6465 eANI_BOOLEAN_FALSE) )
6466 {
6467 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006468 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 }
6470
6471 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6472 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6473 eANI_BOOLEAN_FALSE) )
6474 {
6475 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006476 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 }
6478}
6479
6480VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6481{
6482 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6483 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6484 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306485 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306486 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006487
6488 ENTER();
6489
6490 switch(pAdapter->device_mode)
6491 {
6492 case WLAN_HDD_INFRA_STATION:
6493 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006494 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306495 {
6496 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6497 if( hdd_connIsConnected(pstation) ||
6498 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 {
6500 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6501 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6502 pAdapter->sessionId,
6503 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6504 else
6505 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6506 pAdapter->sessionId,
6507 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6508 //success implies disconnect command got queued up successfully
6509 if(halStatus == eHAL_STATUS_SUCCESS)
6510 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306511 ret = wait_for_completion_interruptible_timeout(
6512 &pAdapter->disconnect_comp_var,
6513 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6514 if (ret <= 0)
6515 {
6516 hddLog(VOS_TRACE_LEVEL_ERROR,
6517 "%s: wait on disconnect_comp_var failed %ld",
6518 __func__, ret);
6519 }
6520 }
6521 else
6522 {
6523 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6524 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006525 }
6526 memset(&wrqu, '\0', sizeof(wrqu));
6527 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6528 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6529 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6530 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306531 else if(pstation->conn_info.connState ==
6532 eConnectionState_Disconnecting)
6533 {
6534 ret = wait_for_completion_interruptible_timeout(
6535 &pAdapter->disconnect_comp_var,
6536 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6537 if (ret <= 0)
6538 {
6539 hddLog(VOS_TRACE_LEVEL_ERROR,
6540 FL("wait on disconnect_comp_var failed %ld"), ret);
6541 }
6542 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006543 else
6544 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306545 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6546 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006547 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306548 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6549 {
6550 while (pAdapter->is_roc_inprogress)
6551 {
6552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6553 "%s: ROC in progress for session %d!!!",
6554 __func__, pAdapter->sessionId);
6555 // waiting for ROC to expire
6556 msleep(500);
6557 /* In GO present case , if retry exceeds 3,
6558 it means something went wrong. */
6559 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6560 {
6561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6562 "%s: ROC completion is not received.!!!", __func__);
6563 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6564 pAdapter->sessionId);
6565 wait_for_completion_interruptible_timeout(
6566 &pAdapter->cancel_rem_on_chan_var,
6567 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6568 break;
6569 }
6570 }
6571 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306572#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306573#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306574 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6575#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306576 if (pAdapter->ipv6_notifier_registered)
6577 {
6578 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6579 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6580 pAdapter->ipv6_notifier_registered = false;
6581 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306582#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306583 if (pAdapter->ipv4_notifier_registered)
6584 {
6585 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6586 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6587 pAdapter->ipv4_notifier_registered = false;
6588 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306589#ifdef WLAN_OPEN_SOURCE
6590 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6591#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6593 {
6594 INIT_COMPLETION(pAdapter->session_close_comp_var);
6595 if (eHAL_STATUS_SUCCESS ==
6596 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6597 hdd_smeCloseSessionCallback, pAdapter))
6598 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306599 unsigned long ret;
6600
Jeff Johnson295189b2012-06-20 16:38:30 -07006601 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306602 ret = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 &pAdapter->session_close_comp_var,
6604 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306605 if ( 0 >= ret)
6606 {
6607 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
6608 __func__, ret);
6609 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 }
6611 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306612 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006613 break;
6614
6615 case WLAN_HDD_SOFTAP:
6616 case WLAN_HDD_P2P_GO:
6617 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306618 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6619 while (pAdapter->is_roc_inprogress) {
6620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6621 "%s: ROC in progress for session %d!!!",
6622 __func__, pAdapter->sessionId);
6623 msleep(500);
6624 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6626 "%s: ROC completion is not received.!!!", __func__);
6627 WLANSAP_CancelRemainOnChannel(
6628 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6629 wait_for_completion_interruptible_timeout(
6630 &pAdapter->cancel_rem_on_chan_var,
6631 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6632 break;
6633 }
6634 }
6635 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006636 mutex_lock(&pHddCtx->sap_lock);
6637 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6638 {
6639 VOS_STATUS status;
6640 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6641
6642 //Stop Bss.
6643 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6644 if (VOS_IS_STATUS_SUCCESS(status))
6645 {
6646 hdd_hostapd_state_t *pHostapdState =
6647 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6648
6649 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6650
6651 if (!VOS_IS_STATUS_SUCCESS(status))
6652 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306653 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6654 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006655 }
6656 }
6657 else
6658 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006659 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006660 }
6661 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6662
6663 if (eHAL_STATUS_FAILURE ==
6664 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6665 0, NULL, eANI_BOOLEAN_FALSE))
6666 {
6667 hddLog(LOGE,
6668 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006669 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006670 }
6671
6672 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6673 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6674 eANI_BOOLEAN_FALSE) )
6675 {
6676 hddLog(LOGE,
6677 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6678 }
6679
6680 // Reset WNI_CFG_PROBE_RSP Flags
6681 wlan_hdd_reset_prob_rspies(pAdapter);
6682 kfree(pAdapter->sessionCtx.ap.beacon);
6683 pAdapter->sessionCtx.ap.beacon = NULL;
6684 }
6685 mutex_unlock(&pHddCtx->sap_lock);
6686 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006687
Jeff Johnson295189b2012-06-20 16:38:30 -07006688 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006689#ifdef WLAN_OPEN_SOURCE
6690 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6691#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006692 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006693
Jeff Johnson295189b2012-06-20 16:38:30 -07006694 default:
6695 break;
6696 }
6697
6698 EXIT();
6699 return VOS_STATUS_SUCCESS;
6700}
6701
6702VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6703{
6704 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6705 VOS_STATUS status;
6706 hdd_adapter_t *pAdapter;
6707
6708 ENTER();
6709
6710 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6711
6712 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6713 {
6714 pAdapter = pAdapterNode->pAdapter;
6715 netif_tx_disable(pAdapter->dev);
6716 netif_carrier_off(pAdapter->dev);
6717
6718 hdd_stop_adapter( pHddCtx, pAdapter );
6719
6720 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6721 pAdapterNode = pNext;
6722 }
6723
6724 EXIT();
6725
6726 return VOS_STATUS_SUCCESS;
6727}
6728
Rajeev Kumarf999e582014-01-09 17:33:29 -08006729
6730#ifdef FEATURE_WLAN_BATCH_SCAN
6731/**---------------------------------------------------------------------------
6732
6733 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6734 structures
6735
6736 \param - pAdapter Pointer to HDD adapter
6737
6738 \return - None
6739
6740 --------------------------------------------------------------------------*/
6741void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6742{
6743 tHddBatchScanRsp *pNode;
6744 tHddBatchScanRsp *pPrev;
6745
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306746 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006747 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306748 hddLog(VOS_TRACE_LEVEL_ERROR,
6749 "%s: Adapter context is Null", __func__);
6750 return;
6751 }
6752
6753 pNode = pAdapter->pBatchScanRsp;
6754 while (pNode)
6755 {
6756 pPrev = pNode;
6757 pNode = pNode->pNext;
6758 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006759 }
6760
6761 pAdapter->pBatchScanRsp = NULL;
6762 pAdapter->numScanList = 0;
6763 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6764 pAdapter->prev_batch_id = 0;
6765
6766 return;
6767}
6768#endif
6769
6770
Jeff Johnson295189b2012-06-20 16:38:30 -07006771VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6772{
6773 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6774 VOS_STATUS status;
6775 hdd_adapter_t *pAdapter;
6776
6777 ENTER();
6778
6779 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6780
6781 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6782 {
6783 pAdapter = pAdapterNode->pAdapter;
6784 netif_tx_disable(pAdapter->dev);
6785 netif_carrier_off(pAdapter->dev);
6786
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006787 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6788
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306790 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6791 {
6792 hdd_wmm_adapter_close( pAdapter );
6793 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6794 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006795
Rajeev Kumarf999e582014-01-09 17:33:29 -08006796#ifdef FEATURE_WLAN_BATCH_SCAN
6797 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6798 {
6799 hdd_deinit_batch_scan(pAdapter);
6800 }
6801#endif
6802
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6804 pAdapterNode = pNext;
6805 }
6806
6807 EXIT();
6808
6809 return VOS_STATUS_SUCCESS;
6810}
6811
6812VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6813{
6814 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6815 VOS_STATUS status;
6816 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306817 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006818
6819 ENTER();
6820
6821 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6822
6823 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6824 {
6825 pAdapter = pAdapterNode->pAdapter;
6826
6827 switch(pAdapter->device_mode)
6828 {
6829 case WLAN_HDD_INFRA_STATION:
6830 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006831 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306832
6833 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6834
Jeff Johnson295189b2012-06-20 16:38:30 -07006835 hdd_init_station_mode(pAdapter);
6836 /* Open the gates for HDD to receive Wext commands */
6837 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006838 pHddCtx->scan_info.mScanPending = FALSE;
6839 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006840
6841 //Trigger the initial scan
6842 hdd_wlan_initial_scan(pAdapter);
6843
6844 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306845 if (eConnectionState_Associated == connState ||
6846 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 {
6848 union iwreq_data wrqu;
6849 memset(&wrqu, '\0', sizeof(wrqu));
6850 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6851 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6852 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006853 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006854
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 /* indicate disconnected event to nl80211 */
6856 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6857 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006858 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306859 else if (eConnectionState_Connecting == connState)
6860 {
6861 /*
6862 * Indicate connect failure to supplicant if we were in the
6863 * process of connecting
6864 */
6865 cfg80211_connect_result(pAdapter->dev, NULL,
6866 NULL, 0, NULL, 0,
6867 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6868 GFP_KERNEL);
6869 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 break;
6871
6872 case WLAN_HDD_SOFTAP:
6873 /* softAP can handle SSR */
6874 break;
6875
6876 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006879 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006880 break;
6881
6882 case WLAN_HDD_MONITOR:
6883 /* monitor interface start */
6884 break;
6885 default:
6886 break;
6887 }
6888
6889 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6890 pAdapterNode = pNext;
6891 }
6892
6893 EXIT();
6894
6895 return VOS_STATUS_SUCCESS;
6896}
6897
6898VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6899{
6900 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6901 hdd_adapter_t *pAdapter;
6902 VOS_STATUS status;
6903 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306904 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006905
6906 ENTER();
6907
6908 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6909
6910 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6911 {
6912 pAdapter = pAdapterNode->pAdapter;
6913
6914 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6915 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6916 {
6917 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6918 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6919
6920 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6921 init_completion(&pAdapter->disconnect_comp_var);
6922 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6923 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6924
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306925 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006926 &pAdapter->disconnect_comp_var,
6927 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306928 if (0 >= ret)
6929 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
6930 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07006931
6932 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6933 pHddCtx->isAmpAllowed = VOS_FALSE;
6934 sme_RoamConnect(pHddCtx->hHal,
6935 pAdapter->sessionId, &(pWextState->roamProfile),
6936 &roamId);
6937 }
6938
6939 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6940 pAdapterNode = pNext;
6941 }
6942
6943 EXIT();
6944
6945 return VOS_STATUS_SUCCESS;
6946}
6947
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006948void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6949{
6950 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6951 VOS_STATUS status;
6952 hdd_adapter_t *pAdapter;
6953 hdd_station_ctx_t *pHddStaCtx;
6954 hdd_ap_ctx_t *pHddApCtx;
6955 hdd_hostapd_state_t * pHostapdState;
6956 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6957 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6958 const char *p2pMode = "DEV";
6959 const char *ccMode = "Standalone";
6960 int n;
6961
6962 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6963 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6964 {
6965 pAdapter = pAdapterNode->pAdapter;
6966 switch (pAdapter->device_mode) {
6967 case WLAN_HDD_INFRA_STATION:
6968 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6969 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6970 staChannel = pHddStaCtx->conn_info.operationChannel;
6971 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6972 }
6973 break;
6974 case WLAN_HDD_P2P_CLIENT:
6975 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6976 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6977 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6978 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6979 p2pMode = "CLI";
6980 }
6981 break;
6982 case WLAN_HDD_P2P_GO:
6983 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6984 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6985 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6986 p2pChannel = pHddApCtx->operatingChannel;
6987 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6988 }
6989 p2pMode = "GO";
6990 break;
6991 case WLAN_HDD_SOFTAP:
6992 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6993 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6994 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6995 apChannel = pHddApCtx->operatingChannel;
6996 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
6997 }
6998 break;
6999 default:
7000 break;
7001 }
7002 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7003 pAdapterNode = pNext;
7004 }
7005 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7006 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7007 }
7008 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7009 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7010 if (p2pChannel > 0) {
7011 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7012 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7013 }
7014 if (apChannel > 0) {
7015 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7016 apChannel, MAC_ADDR_ARRAY(apBssid));
7017 }
7018
7019 if (p2pChannel > 0 && apChannel > 0) {
7020 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7021 }
7022}
7023
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007024bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007025{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007026 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007027}
7028
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007029/* Once SSR is disabled then it cannot be set. */
7030void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007031{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007032 if (HDD_SSR_DISABLED == isSsrRequired)
7033 return;
7034
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 isSsrRequired = value;
7036}
7037
7038VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7039 hdd_adapter_list_node_t** ppAdapterNode)
7040{
7041 VOS_STATUS status;
7042 spin_lock(&pHddCtx->hddAdapters.lock);
7043 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7044 (hdd_list_node_t**) ppAdapterNode );
7045 spin_unlock(&pHddCtx->hddAdapters.lock);
7046 return status;
7047}
7048
7049VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7050 hdd_adapter_list_node_t* pAdapterNode,
7051 hdd_adapter_list_node_t** pNextAdapterNode)
7052{
7053 VOS_STATUS status;
7054 spin_lock(&pHddCtx->hddAdapters.lock);
7055 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7056 (hdd_list_node_t*) pAdapterNode,
7057 (hdd_list_node_t**)pNextAdapterNode );
7058
7059 spin_unlock(&pHddCtx->hddAdapters.lock);
7060 return status;
7061}
7062
7063VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7064 hdd_adapter_list_node_t* pAdapterNode)
7065{
7066 VOS_STATUS status;
7067 spin_lock(&pHddCtx->hddAdapters.lock);
7068 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7069 &pAdapterNode->node );
7070 spin_unlock(&pHddCtx->hddAdapters.lock);
7071 return status;
7072}
7073
7074VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7075 hdd_adapter_list_node_t** ppAdapterNode)
7076{
7077 VOS_STATUS status;
7078 spin_lock(&pHddCtx->hddAdapters.lock);
7079 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7080 (hdd_list_node_t**) ppAdapterNode );
7081 spin_unlock(&pHddCtx->hddAdapters.lock);
7082 return status;
7083}
7084
7085VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7086 hdd_adapter_list_node_t* pAdapterNode)
7087{
7088 VOS_STATUS status;
7089 spin_lock(&pHddCtx->hddAdapters.lock);
7090 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7091 (hdd_list_node_t*) pAdapterNode );
7092 spin_unlock(&pHddCtx->hddAdapters.lock);
7093 return status;
7094}
7095
7096VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7097 hdd_adapter_list_node_t* pAdapterNode)
7098{
7099 VOS_STATUS status;
7100 spin_lock(&pHddCtx->hddAdapters.lock);
7101 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7102 (hdd_list_node_t*) pAdapterNode );
7103 spin_unlock(&pHddCtx->hddAdapters.lock);
7104 return status;
7105}
7106
7107hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7108 tSirMacAddr macAddr )
7109{
7110 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7111 hdd_adapter_t *pAdapter;
7112 VOS_STATUS status;
7113
7114 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7115
7116 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7117 {
7118 pAdapter = pAdapterNode->pAdapter;
7119
7120 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7121 macAddr, sizeof(tSirMacAddr) ) )
7122 {
7123 return pAdapter;
7124 }
7125 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7126 pAdapterNode = pNext;
7127 }
7128
7129 return NULL;
7130
7131}
7132
7133hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7134{
7135 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7136 hdd_adapter_t *pAdapter;
7137 VOS_STATUS status;
7138
7139 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7140
7141 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7142 {
7143 pAdapter = pAdapterNode->pAdapter;
7144
7145 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7146 IFNAMSIZ ) )
7147 {
7148 return pAdapter;
7149 }
7150 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7151 pAdapterNode = pNext;
7152 }
7153
7154 return NULL;
7155
7156}
7157
7158hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7159{
7160 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7161 hdd_adapter_t *pAdapter;
7162 VOS_STATUS status;
7163
7164 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7165
7166 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7167 {
7168 pAdapter = pAdapterNode->pAdapter;
7169
7170 if( pAdapter && (mode == pAdapter->device_mode) )
7171 {
7172 return pAdapter;
7173 }
7174 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7175 pAdapterNode = pNext;
7176 }
7177
7178 return NULL;
7179
7180}
7181
7182//Remove this function later
7183hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7184{
7185 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7186 hdd_adapter_t *pAdapter;
7187 VOS_STATUS status;
7188
7189 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7190
7191 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7192 {
7193 pAdapter = pAdapterNode->pAdapter;
7194
7195 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7196 {
7197 return pAdapter;
7198 }
7199
7200 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7201 pAdapterNode = pNext;
7202 }
7203
7204 return NULL;
7205
7206}
7207
Jeff Johnson295189b2012-06-20 16:38:30 -07007208/**---------------------------------------------------------------------------
7209
7210 \brief hdd_set_monitor_tx_adapter() -
7211
7212 This API initializes the adapter to be used while transmitting on monitor
7213 adapter.
7214
7215 \param - pHddCtx - Pointer to the HDD context.
7216 pAdapter - Adapter that will used for TX. This can be NULL.
7217 \return - None.
7218 --------------------------------------------------------------------------*/
7219void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7220{
7221 hdd_adapter_t *pMonAdapter;
7222
7223 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7224
7225 if( NULL != pMonAdapter )
7226 {
7227 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7228 }
7229}
Jeff Johnson295189b2012-06-20 16:38:30 -07007230/**---------------------------------------------------------------------------
7231
7232 \brief hdd_select_queue() -
7233
7234 This API returns the operating channel of the requested device mode
7235
7236 \param - pHddCtx - Pointer to the HDD context.
7237 - mode - Device mode for which operating channel is required
7238 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7239 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7240 \return - channel number. "0" id the requested device is not found OR it is not connected.
7241 --------------------------------------------------------------------------*/
7242v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7243{
7244 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7245 VOS_STATUS status;
7246 hdd_adapter_t *pAdapter;
7247 v_U8_t operatingChannel = 0;
7248
7249 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7250
7251 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7252 {
7253 pAdapter = pAdapterNode->pAdapter;
7254
7255 if( mode == pAdapter->device_mode )
7256 {
7257 switch(pAdapter->device_mode)
7258 {
7259 case WLAN_HDD_INFRA_STATION:
7260 case WLAN_HDD_P2P_CLIENT:
7261 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7262 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7263 break;
7264 case WLAN_HDD_SOFTAP:
7265 case WLAN_HDD_P2P_GO:
7266 /*softap connection info */
7267 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7268 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7269 break;
7270 default:
7271 break;
7272 }
7273
7274 break; //Found the device of interest. break the loop
7275 }
7276
7277 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7278 pAdapterNode = pNext;
7279 }
7280 return operatingChannel;
7281}
7282
7283#ifdef WLAN_FEATURE_PACKET_FILTERING
7284/**---------------------------------------------------------------------------
7285
7286 \brief hdd_set_multicast_list() -
7287
7288 This used to set the multicast address list.
7289
7290 \param - dev - Pointer to the WLAN device.
7291 - skb - Pointer to OS packet (sk_buff).
7292 \return - success/fail
7293
7294 --------------------------------------------------------------------------*/
7295static void hdd_set_multicast_list(struct net_device *dev)
7296{
7297 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007298 int mc_count;
7299 int i = 0;
7300 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307301
7302 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 {
7304 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307305 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007306 return;
7307 }
7308
7309 if (dev->flags & IFF_ALLMULTI)
7310 {
7311 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007312 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307313 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007314 }
7315 else
7316 {
7317 mc_count = netdev_mc_count(dev);
7318 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007319 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007320 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7321 {
7322 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007323 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307324 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007325 return;
7326 }
7327
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307328 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007329
7330 netdev_for_each_mc_addr(ha, dev) {
7331 if (i == mc_count)
7332 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307333 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7334 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307337 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007338 i++;
7339 }
7340 }
7341 return;
7342}
7343#endif
7344
7345/**---------------------------------------------------------------------------
7346
7347 \brief hdd_select_queue() -
7348
7349 This function is registered with the Linux OS for network
7350 core to decide which queue to use first.
7351
7352 \param - dev - Pointer to the WLAN device.
7353 - skb - Pointer to OS packet (sk_buff).
7354 \return - ac, Queue Index/access category corresponding to UP in IP header
7355
7356 --------------------------------------------------------------------------*/
7357v_U16_t hdd_select_queue(struct net_device *dev,
7358 struct sk_buff *skb)
7359{
7360 return hdd_wmm_select_queue(dev, skb);
7361}
7362
7363
7364/**---------------------------------------------------------------------------
7365
7366 \brief hdd_wlan_initial_scan() -
7367
7368 This function triggers the initial scan
7369
7370 \param - pAdapter - Pointer to the HDD adapter.
7371
7372 --------------------------------------------------------------------------*/
7373void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7374{
7375 tCsrScanRequest scanReq;
7376 tCsrChannelInfo channelInfo;
7377 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007378 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007379 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7380
7381 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7382 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7383 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7384
7385 if(sme_Is11dSupported(pHddCtx->hHal))
7386 {
7387 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7388 if ( HAL_STATUS_SUCCESS( halStatus ) )
7389 {
7390 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7391 if( !scanReq.ChannelInfo.ChannelList )
7392 {
7393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7394 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007395 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007396 return;
7397 }
7398 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7399 channelInfo.numOfChannels);
7400 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7401 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007402 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007403 }
7404
7405 scanReq.scanType = eSIR_PASSIVE_SCAN;
7406 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7407 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7408 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7409 }
7410 else
7411 {
7412 scanReq.scanType = eSIR_ACTIVE_SCAN;
7413 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7414 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7415 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7416 }
7417
7418 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7419 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7420 {
7421 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7422 __func__, halStatus );
7423 }
7424
7425 if(sme_Is11dSupported(pHddCtx->hHal))
7426 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7427}
7428
Jeff Johnson295189b2012-06-20 16:38:30 -07007429/**---------------------------------------------------------------------------
7430
7431 \brief hdd_full_power_callback() - HDD full power callback function
7432
7433 This is the function invoked by SME to inform the result of a full power
7434 request issued by HDD
7435
7436 \param - callbackcontext - Pointer to cookie
7437 \param - status - result of request
7438
7439 \return - None
7440
7441 --------------------------------------------------------------------------*/
7442static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7443{
Jeff Johnson72a40512013-12-19 10:14:15 -08007444 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007445
7446 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307447 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007448
7449 if (NULL == callbackContext)
7450 {
7451 hddLog(VOS_TRACE_LEVEL_ERROR,
7452 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007453 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007454 return;
7455 }
7456
Jeff Johnson72a40512013-12-19 10:14:15 -08007457 /* there is a race condition that exists between this callback
7458 function and the caller since the caller could time out either
7459 before or while this code is executing. we use a spinlock to
7460 serialize these actions */
7461 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007462
7463 if (POWER_CONTEXT_MAGIC != pContext->magic)
7464 {
7465 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007466 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007467 hddLog(VOS_TRACE_LEVEL_WARN,
7468 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007469 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007470 return;
7471 }
7472
Jeff Johnson72a40512013-12-19 10:14:15 -08007473 /* context is valid so caller is still waiting */
7474
7475 /* paranoia: invalidate the magic */
7476 pContext->magic = 0;
7477
7478 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007480
7481 /* serialization is complete */
7482 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007483}
7484
7485/**---------------------------------------------------------------------------
7486
7487 \brief hdd_wlan_exit() - HDD WLAN exit function
7488
7489 This is the driver exit point (invoked during rmmod)
7490
7491 \param - pHddCtx - Pointer to the HDD Context
7492
7493 \return - None
7494
7495 --------------------------------------------------------------------------*/
7496void hdd_wlan_exit(hdd_context_t *pHddCtx)
7497{
7498 eHalStatus halStatus;
7499 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7500 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307501 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007502 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007503 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007504 long lrc;
7505
7506 ENTER();
7507
Jeff Johnson88ba7742013-02-27 14:36:02 -08007508 if (VOS_FTM_MODE != hdd_get_conparam())
7509 {
7510 // Unloading, restart logic is no more required.
7511 wlan_hdd_restart_deinit(pHddCtx);
7512 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007513
Jeff Johnson295189b2012-06-20 16:38:30 -07007514 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007515 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007516 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007517 {
7518 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7519 WLAN_HDD_INFRA_STATION);
7520 if (pAdapter == NULL)
7521 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7522
7523 if (pAdapter != NULL)
7524 {
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05307525 wlan_hdd_cfg80211_deregister_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 hdd_UnregisterWext(pAdapter->dev);
7527 }
7528 }
7529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007530
Jeff Johnson295189b2012-06-20 16:38:30 -07007531 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007532 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307533 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007534 wlan_hdd_ftm_close(pHddCtx);
7535 goto free_hdd_ctx;
7536 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 //Stop the Interface TX queue.
7538 //netif_tx_disable(pWlanDev);
7539 //netif_carrier_off(pWlanDev);
7540
Jeff Johnson295189b2012-06-20 16:38:30 -07007541 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7542 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307543 hddLog(VOS_TRACE_LEVEL_INFO,"%s: SAP MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007544 pAdapter = hdd_get_adapter(pHddCtx,
7545 WLAN_HDD_SOFTAP);
7546 }
7547 else
7548 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007549 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007550 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307551 hddLog(VOS_TRACE_LEVEL_INFO,"%s: STA MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007552 pAdapter = hdd_get_adapter(pHddCtx,
7553 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007554 if (pAdapter == NULL)
7555 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007556 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307558
7559 if(NULL == pAdapter)
7560 {
7561 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: pAdapter is NULL",__func__);
7562 goto free_hdd_ctx;
7563 }
7564
Jeff Johnson295189b2012-06-20 16:38:30 -07007565 /* DeRegister with platform driver as client for Suspend/Resume */
7566 vosStatus = hddDeregisterPmOps(pHddCtx);
7567 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7568 {
7569 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7570 VOS_ASSERT(0);
7571 }
7572
7573 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7574 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7575 {
7576 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007578
7579 // Cancel any outstanding scan requests. We are about to close all
7580 // of our adapters, but an adapter structure is what SME passes back
7581 // to our callback function. Hence if there are any outstanding scan
7582 // requests then there is a race condition between when the adapter
7583 // is closed and when the callback is invoked. We try to resolve that
7584 // race condition here by canceling any outstanding scans before we
7585 // close the adapters.
7586 // Note that the scans may be cancelled in an asynchronous manner, so
7587 // ideally there needs to be some kind of synchronization. Rather than
7588 // introduce a new synchronization here, we will utilize the fact that
7589 // we are about to Request Full Power, and since that is synchronized,
7590 // the expectation is that by the time Request Full Power has completed,
7591 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007592 if (NULL != pAdapter)
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307593 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, eCSR_SCAN_ABORT_DEFAULT);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007594 else
7595 hddLog(VOS_TRACE_LEVEL_ERROR,
7596 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007597
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007598 //Stop the traffic monitor timer
7599 if ( VOS_TIMER_STATE_RUNNING ==
7600 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7601 {
7602 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7603 }
7604
7605 // Destroy the traffic monitor timer
7606 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7607 &pHddCtx->tx_rx_trafficTmr)))
7608 {
7609 hddLog(VOS_TRACE_LEVEL_ERROR,
7610 "%s: Cannot deallocate Traffic monitor timer", __func__);
7611 }
7612
Jeff Johnson295189b2012-06-20 16:38:30 -07007613 //Disable IMPS/BMPS as we do not want the device to enter any power
7614 //save mode during shutdown
7615 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7616 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7617 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7618
7619 //Ensure that device is in full power as we will touch H/W during vos_Stop
7620 init_completion(&powerContext.completion);
7621 powerContext.magic = POWER_CONTEXT_MAGIC;
7622
7623 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7624 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7625
7626 if (eHAL_STATUS_SUCCESS != halStatus)
7627 {
7628 if (eHAL_STATUS_PMC_PENDING == halStatus)
7629 {
7630 /* request was sent -- wait for the response */
7631 lrc = wait_for_completion_interruptible_timeout(
7632 &powerContext.completion,
7633 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007634 if (lrc <= 0)
7635 {
7636 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007637 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007638 }
7639 }
7640 else
7641 {
7642 hddLog(VOS_TRACE_LEVEL_ERROR,
7643 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007644 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007645 /* continue -- need to clean up as much as possible */
7646 }
7647 }
7648
Jeff Johnson72a40512013-12-19 10:14:15 -08007649 /* either we never sent a request, we sent a request and received a
7650 response or we sent a request and timed out. if we never sent a
7651 request or if we sent a request and got a response, we want to
7652 clear the magic out of paranoia. if we timed out there is a
7653 race condition such that the callback function could be
7654 executing at the same time we are. of primary concern is if the
7655 callback function had already verified the "magic" but had not
7656 yet set the completion variable when a timeout occurred. we
7657 serialize these activities by invalidating the magic while
7658 holding a shared spinlock which will cause us to block if the
7659 callback is currently executing */
7660 spin_lock(&hdd_context_lock);
7661 powerContext.magic = 0;
7662 spin_unlock(&hdd_context_lock);
7663
Yue Ma0d4891e2013-08-06 17:01:45 -07007664 hdd_debugfs_exit(pHddCtx);
7665
Jeff Johnson295189b2012-06-20 16:38:30 -07007666 // Unregister the Net Device Notifier
7667 unregister_netdevice_notifier(&hdd_netdev_notifier);
7668
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 hdd_stop_all_adapters( pHddCtx );
7670
Jeff Johnson295189b2012-06-20 16:38:30 -07007671#ifdef WLAN_BTAMP_FEATURE
7672 vosStatus = WLANBAP_Stop(pVosContext);
7673 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7674 {
7675 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7676 "%s: Failed to stop BAP",__func__);
7677 }
7678#endif //WLAN_BTAMP_FEATURE
7679
7680 //Stop all the modules
7681 vosStatus = vos_stop( pVosContext );
7682 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7683 {
7684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7685 "%s: Failed to stop VOSS",__func__);
7686 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7687 }
7688
Jeff Johnson295189b2012-06-20 16:38:30 -07007689 //Assert Deep sleep signal now to put Libra HW in lowest power state
7690 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7691 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7692
7693 //Vote off any PMIC voltage supplies
7694 vos_chipPowerDown(NULL, NULL, NULL);
7695
7696 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7697
Leo Chang59cdc7e2013-07-10 10:08:21 -07007698
Jeff Johnson295189b2012-06-20 16:38:30 -07007699 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007701
7702 //Close the scheduler before calling vos_close to make sure no thread is
7703 // scheduled after the each module close is called i.e after all the data
7704 // structures are freed.
7705 vosStatus = vos_sched_close( pVosContext );
7706 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7707 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7708 "%s: Failed to close VOSS Scheduler",__func__);
7709 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7710 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007711#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007712#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7713 /* Destroy the wake lock */
7714 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7715#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007716 /* Destroy the wake lock */
7717 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007718#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007719
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307720#ifdef CONFIG_ENABLE_LINUX_REG
7721 vosStatus = vos_nv_close();
7722 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7723 {
7724 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7725 "%s: Failed to close NV", __func__);
7726 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7727 }
7728#endif
7729
Jeff Johnson295189b2012-06-20 16:38:30 -07007730 //Close VOSS
7731 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7732 vos_close(pVosContext);
7733
Jeff Johnson295189b2012-06-20 16:38:30 -07007734 //Close Watchdog
7735 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7736 vos_watchdog_close(pVosContext);
7737
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307738 //Clean up HDD Nlink Service
7739 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007740#ifdef WLAN_KD_READY_NOTIFIER
7741 nl_srv_exit(pHddCtx->ptt_pid);
7742#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307743 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007744#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307745
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307746#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307747 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307748 {
7749 wlan_logging_sock_deactivate_svc();
7750 }
7751#endif
7752
Jeff Johnson295189b2012-06-20 16:38:30 -07007753 /* Cancel the vote for XO Core ON.
7754 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7755 * exited at this point
7756 */
7757 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007758 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7760 {
7761 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7762 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007763 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007764 }
7765
7766 hdd_close_all_adapters( pHddCtx );
7767
Jeff Johnson295189b2012-06-20 16:38:30 -07007768 /* free the power on lock from platform driver */
7769 if (free_riva_power_on_lock("wlan"))
7770 {
7771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7772 __func__);
7773 }
7774
Jeff Johnson88ba7742013-02-27 14:36:02 -08007775free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05307776
7777 //Free up dynamically allocated members inside HDD Adapter
7778 if (pHddCtx->cfg_ini)
7779 {
7780 kfree(pHddCtx->cfg_ini);
7781 pHddCtx->cfg_ini= NULL;
7782 }
7783
Leo Changf04ddad2013-09-18 13:46:38 -07007784 /* FTM mode, WIPHY did not registered
7785 If un-register here, system crash will happen */
7786 if (VOS_FTM_MODE != hdd_get_conparam())
7787 {
7788 wiphy_unregister(wiphy) ;
7789 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007790 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 if (hdd_is_ssr_required())
7792 {
7793 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007794 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 msleep(5000);
7796 }
7797 hdd_set_ssr_required (VOS_FALSE);
7798}
7799
7800
7801/**---------------------------------------------------------------------------
7802
7803 \brief hdd_update_config_from_nv() - Function to update the contents of
7804 the running configuration with parameters taken from NV storage
7805
7806 \param - pHddCtx - Pointer to the HDD global context
7807
7808 \return - VOS_STATUS_SUCCESS if successful
7809
7810 --------------------------------------------------------------------------*/
7811static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7812{
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 v_BOOL_t itemIsValid = VOS_FALSE;
7814 VOS_STATUS status;
7815 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7816 v_U8_t macLoop;
7817
7818 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7819 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7820 if(status != VOS_STATUS_SUCCESS)
7821 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007822 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007823 return VOS_STATUS_E_FAILURE;
7824 }
7825
7826 if (itemIsValid == VOS_TRUE)
7827 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007828 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007829 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7830 VOS_MAX_CONCURRENCY_PERSONA);
7831 if(status != VOS_STATUS_SUCCESS)
7832 {
7833 /* Get MAC from NV fail, not update CFG info
7834 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007835 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007836 return VOS_STATUS_E_FAILURE;
7837 }
7838
7839 /* If first MAC is not valid, treat all others are not valid
7840 * Then all MACs will be got from ini file */
7841 if(vos_is_macaddr_zero(&macFromNV[0]))
7842 {
7843 /* MAC address in NV file is not configured yet */
7844 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7845 return VOS_STATUS_E_INVAL;
7846 }
7847
7848 /* Get MAC address from NV, update CFG info */
7849 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7850 {
7851 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7852 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307853 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 /* This MAC is not valid, skip it
7855 * This MAC will be got from ini file */
7856 }
7857 else
7858 {
7859 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7860 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7861 VOS_MAC_ADDR_SIZE);
7862 }
7863 }
7864 }
7865 else
7866 {
7867 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7868 return VOS_STATUS_E_FAILURE;
7869 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007870
Jeff Johnson295189b2012-06-20 16:38:30 -07007871
7872 return VOS_STATUS_SUCCESS;
7873}
7874
7875/**---------------------------------------------------------------------------
7876
7877 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7878
7879 \param - pAdapter - Pointer to the HDD
7880
7881 \return - None
7882
7883 --------------------------------------------------------------------------*/
7884VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7885{
7886 eHalStatus halStatus;
7887 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307888 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007889
Jeff Johnson295189b2012-06-20 16:38:30 -07007890
7891 // Send ready indication to the HDD. This will kick off the MAC
7892 // into a 'running' state and should kick off an initial scan.
7893 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7894 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7895 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307896 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007897 "code %08d [x%08x]",__func__, halStatus, halStatus );
7898 return VOS_STATUS_E_FAILURE;
7899 }
7900
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307901 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007902 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7903 // And RIVA will crash
7904 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7905 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307906 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7907 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7908
7909
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 return VOS_STATUS_SUCCESS;
7911}
7912
Jeff Johnson295189b2012-06-20 16:38:30 -07007913/* wake lock APIs for HDD */
7914void hdd_prevent_suspend(void)
7915{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007916#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007918#else
7919 wcnss_prevent_suspend();
7920#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007921}
7922
7923void hdd_allow_suspend(void)
7924{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007925#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007927#else
7928 wcnss_allow_suspend();
7929#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007930}
7931
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05307932void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007933{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007934#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007935 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007936#else
7937 /* Do nothing as there is no API in wcnss for timeout*/
7938#endif
7939}
7940
Jeff Johnson295189b2012-06-20 16:38:30 -07007941/**---------------------------------------------------------------------------
7942
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007943 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7944 information between Host and Riva
7945
7946 This function gets reported version of FW
7947 It also finds the version of Riva headers used to compile the host
7948 It compares the above two and prints a warning if they are different
7949 It gets the SW and HW version string
7950 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7951 indicating the features they support through a bitmap
7952
7953 \param - pHddCtx - Pointer to HDD context
7954
7955 \return - void
7956
7957 --------------------------------------------------------------------------*/
7958
7959void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7960{
7961
7962 tSirVersionType versionCompiled;
7963 tSirVersionType versionReported;
7964 tSirVersionString versionString;
7965 tANI_U8 fwFeatCapsMsgSupported = 0;
7966 VOS_STATUS vstatus;
7967
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007968 memset(&versionCompiled, 0, sizeof(versionCompiled));
7969 memset(&versionReported, 0, sizeof(versionReported));
7970
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007971 /* retrieve and display WCNSS version information */
7972 do {
7973
7974 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7975 &versionCompiled);
7976 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7977 {
7978 hddLog(VOS_TRACE_LEVEL_FATAL,
7979 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007980 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007981 break;
7982 }
7983
7984 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7985 &versionReported);
7986 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7987 {
7988 hddLog(VOS_TRACE_LEVEL_FATAL,
7989 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007990 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007991 break;
7992 }
7993
7994 if ((versionCompiled.major != versionReported.major) ||
7995 (versionCompiled.minor != versionReported.minor) ||
7996 (versionCompiled.version != versionReported.version) ||
7997 (versionCompiled.revision != versionReported.revision))
7998 {
7999 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8000 "Host expected %u.%u.%u.%u\n",
8001 WLAN_MODULE_NAME,
8002 (int)versionReported.major,
8003 (int)versionReported.minor,
8004 (int)versionReported.version,
8005 (int)versionReported.revision,
8006 (int)versionCompiled.major,
8007 (int)versionCompiled.minor,
8008 (int)versionCompiled.version,
8009 (int)versionCompiled.revision);
8010 }
8011 else
8012 {
8013 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8014 WLAN_MODULE_NAME,
8015 (int)versionReported.major,
8016 (int)versionReported.minor,
8017 (int)versionReported.version,
8018 (int)versionReported.revision);
8019 }
8020
8021 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8022 versionString,
8023 sizeof(versionString));
8024 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8025 {
8026 hddLog(VOS_TRACE_LEVEL_FATAL,
8027 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008028 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008029 break;
8030 }
8031
8032 pr_info("%s: WCNSS software version %s\n",
8033 WLAN_MODULE_NAME, versionString);
8034
8035 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8036 versionString,
8037 sizeof(versionString));
8038 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8039 {
8040 hddLog(VOS_TRACE_LEVEL_FATAL,
8041 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008042 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008043 break;
8044 }
8045
8046 pr_info("%s: WCNSS hardware version %s\n",
8047 WLAN_MODULE_NAME, versionString);
8048
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008049 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8050 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008051 send the message only if it the riva is 1.1
8052 minor numbers for different riva branches:
8053 0 -> (1.0)Mainline Build
8054 1 -> (1.1)Mainline Build
8055 2->(1.04) Stability Build
8056 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008057 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008058 ((versionReported.minor>=1) && (versionReported.version>=1)))
8059 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8060 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008061
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008062 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008063 {
8064#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8065 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8066 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8067#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008068 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8069 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8070 {
8071 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8072 }
8073
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008074 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008075 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008076
8077 } while (0);
8078
8079}
8080
8081/**---------------------------------------------------------------------------
8082
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308083 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8084
8085 \param - pHddCtx - Pointer to the hdd context
8086
8087 \return - true if hardware supports 5GHz
8088
8089 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308090boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308091{
8092 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8093 * then hardware support 5Ghz.
8094 */
8095 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8096 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308098 return true;
8099 }
8100 else
8101 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308102 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308103 __func__);
8104 return false;
8105 }
8106}
8107
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308108/**---------------------------------------------------------------------------
8109
8110 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8111 generate function
8112
8113 This is generate the random mac address for WLAN interface
8114
8115 \param - pHddCtx - Pointer to HDD context
8116 idx - Start interface index to get auto
8117 generated mac addr.
8118 mac_addr - Mac address
8119
8120 \return - 0 for success, < 0 for failure
8121
8122 --------------------------------------------------------------------------*/
8123
8124static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8125 int idx, v_MACADDR_t mac_addr)
8126{
8127 int i;
8128 unsigned int serialno;
8129 serialno = wcnss_get_serial_number();
8130
8131 if (0 != serialno)
8132 {
8133 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8134 bytes of the serial number that can be used to generate
8135 the other 3 bytes of the MAC address. Mask off all but
8136 the lower 3 bytes (this will also make sure we don't
8137 overflow in the next step) */
8138 serialno &= 0x00FFFFFF;
8139
8140 /* we need a unique address for each session */
8141 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8142
8143 /* autogen other Mac addresses */
8144 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8145 {
8146 /* start with the entire default address */
8147 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8148 /* then replace the lower 3 bytes */
8149 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8150 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8151 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8152
8153 serialno++;
8154 hddLog(VOS_TRACE_LEVEL_ERROR,
8155 "%s: Derived Mac Addr: "
8156 MAC_ADDRESS_STR, __func__,
8157 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8158 }
8159
8160 }
8161 else
8162 {
8163 hddLog(LOGE, FL("Failed to Get Serial NO"));
8164 return -1;
8165 }
8166 return 0;
8167}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308168
8169/**---------------------------------------------------------------------------
8170
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308171 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8172 completed to flush out the scan results
8173
8174 11d scan is done during driver load and is a passive scan on all
8175 channels supported by the device, 11d scans may find some APs on
8176 frequencies which are forbidden to be used in the regulatory domain
8177 the device is operating in. If these APs are notified to the supplicant
8178 it may try to connect to these APs, thus flush out all the scan results
8179 which are present in SME after 11d scan is done.
8180
8181 \return - eHalStatus
8182
8183 --------------------------------------------------------------------------*/
8184static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8185 tANI_U32 scanId, eCsrScanStatus status)
8186{
8187 ENTER();
8188
8189 sme_ScanFlushResult(halHandle, 0);
8190
8191 EXIT();
8192
8193 return eHAL_STATUS_SUCCESS;
8194}
8195
8196/**---------------------------------------------------------------------------
8197
Jeff Johnson295189b2012-06-20 16:38:30 -07008198 \brief hdd_wlan_startup() - HDD init function
8199
8200 This is the driver startup code executed once a WLAN device has been detected
8201
8202 \param - dev - Pointer to the underlying device
8203
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008204 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008205
8206 --------------------------------------------------------------------------*/
8207
8208int hdd_wlan_startup(struct device *dev )
8209{
8210 VOS_STATUS status;
8211 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008212 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 hdd_context_t *pHddCtx = NULL;
8214 v_CONTEXT_t pVosContext= NULL;
8215#ifdef WLAN_BTAMP_FEATURE
8216 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8217 WLANBAP_ConfigType btAmpConfig;
8218 hdd_config_t *pConfig;
8219#endif
8220 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008221 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308222 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008223
8224 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 /*
8226 * cfg80211: wiphy allocation
8227 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308228 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008229
8230 if(wiphy == NULL)
8231 {
8232 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008233 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 }
8235
8236 pHddCtx = wiphy_priv(wiphy);
8237
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 //Initialize the adapter context to zeros.
8239 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8240
Jeff Johnson295189b2012-06-20 16:38:30 -07008241 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008242 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308243 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008244
8245 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8246
8247 /*Get vos context here bcoz vos_open requires it*/
8248 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8249
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008250 if(pVosContext == NULL)
8251 {
8252 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8253 goto err_free_hdd_context;
8254 }
8255
Jeff Johnson295189b2012-06-20 16:38:30 -07008256 //Save the Global VOSS context in adapter context for future.
8257 pHddCtx->pvosContext = pVosContext;
8258
8259 //Save the adapter context in global context for future.
8260 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8261
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 pHddCtx->parent_dev = dev;
8263
8264 init_completion(&pHddCtx->full_pwr_comp_var);
8265 init_completion(&pHddCtx->standby_comp_var);
8266 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008267 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008268 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308269 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308270 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008271
8272#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008273 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008274#else
8275 init_completion(&pHddCtx->driver_crda_req);
8276#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008277
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308278 spin_lock_init(&pHddCtx->schedScan_lock);
8279
Jeff Johnson295189b2012-06-20 16:38:30 -07008280 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8281
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308282#ifdef FEATURE_WLAN_TDLS
8283 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8284 * invoked by other instances also) to protect the concurrent
8285 * access for the Adapters by TDLS module.
8286 */
8287 mutex_init(&pHddCtx->tdls_lock);
8288#endif
8289
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308290 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008291 // Load all config first as TL config is needed during vos_open
8292 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8293 if(pHddCtx->cfg_ini == NULL)
8294 {
8295 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8296 goto err_free_hdd_context;
8297 }
8298
8299 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8300
8301 // Read and parse the qcom_cfg.ini file
8302 status = hdd_parse_config_ini( pHddCtx );
8303 if ( VOS_STATUS_SUCCESS != status )
8304 {
8305 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8306 __func__, WLAN_INI_FILE);
8307 goto err_config;
8308 }
Arif Hussaind5218912013-12-05 01:10:55 -08008309#ifdef MEMORY_DEBUG
8310 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8311 vos_mem_init();
8312
8313 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8314 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8315#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008316
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308317 /* INI has been read, initialise the configuredMcastBcastFilter with
8318 * INI value as this will serve as the default value
8319 */
8320 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8321 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8322 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308323
8324 if (false == hdd_is_5g_supported(pHddCtx))
8325 {
8326 //5Ghz is not supported.
8327 if (1 != pHddCtx->cfg_ini->nBandCapability)
8328 {
8329 hddLog(VOS_TRACE_LEVEL_INFO,
8330 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8331 pHddCtx->cfg_ini->nBandCapability = 1;
8332 }
8333 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308334
8335 /* If SNR Monitoring is enabled, FW has to parse all beacons
8336 * for calcaluting and storing the average SNR, so set Nth beacon
8337 * filter to 1 to enable FW to parse all the beaocons
8338 */
8339 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8340 {
8341 /* The log level is deliberately set to WARN as overriding
8342 * nthBeaconFilter to 1 will increase power cosumption and this
8343 * might just prove helpful to detect the power issue.
8344 */
8345 hddLog(VOS_TRACE_LEVEL_WARN,
8346 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8347 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8348 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008349 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308350 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008352 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008354 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8355 {
8356 hddLog(VOS_TRACE_LEVEL_FATAL,
8357 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8358 goto err_config;
8359 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008361
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008362 // Update VOS trace levels based upon the cfg.ini
8363 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8364 pHddCtx->cfg_ini->vosTraceEnableBAP);
8365 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8366 pHddCtx->cfg_ini->vosTraceEnableTL);
8367 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8368 pHddCtx->cfg_ini->vosTraceEnableWDI);
8369 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8370 pHddCtx->cfg_ini->vosTraceEnableHDD);
8371 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8372 pHddCtx->cfg_ini->vosTraceEnableSME);
8373 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8374 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308375 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8376 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008377 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8378 pHddCtx->cfg_ini->vosTraceEnableWDA);
8379 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8380 pHddCtx->cfg_ini->vosTraceEnableSYS);
8381 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8382 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008383 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8384 pHddCtx->cfg_ini->vosTraceEnableSAP);
8385 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8386 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008387
Jeff Johnson295189b2012-06-20 16:38:30 -07008388 // Update WDI trace levels based upon the cfg.ini
8389 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8390 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8391 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8392 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8393 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8394 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8395 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8396 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008397
Jeff Johnson88ba7742013-02-27 14:36:02 -08008398 if (VOS_FTM_MODE == hdd_get_conparam())
8399 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008400 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8401 {
8402 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8403 goto err_free_hdd_context;
8404 }
8405 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308406
8407 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008409 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008410
Jeff Johnson88ba7742013-02-27 14:36:02 -08008411 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008412 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8413 {
8414 status = vos_watchdog_open(pVosContext,
8415 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8416
8417 if(!VOS_IS_STATUS_SUCCESS( status ))
8418 {
8419 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308420 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008421 }
8422 }
8423
8424 pHddCtx->isLogpInProgress = FALSE;
8425 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8426
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8428 if(!VOS_IS_STATUS_SUCCESS(status))
8429 {
8430 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 }
8433
Amar Singhala49cbc52013-10-08 18:37:44 -07008434#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008435 /* initialize the NV module. This is required so that
8436 we can initialize the channel information in wiphy
8437 from the NV.bin data. The channel information in
8438 wiphy needs to be initialized before wiphy registration */
8439
8440 status = vos_nv_open();
8441 if (!VOS_IS_STATUS_SUCCESS(status))
8442 {
8443 /* NV module cannot be initialized */
8444 hddLog( VOS_TRACE_LEVEL_FATAL,
8445 "%s: vos_nv_open failed", __func__);
8446 goto err_clkvote;
8447 }
8448
8449 status = vos_init_wiphy_from_nv_bin();
8450 if (!VOS_IS_STATUS_SUCCESS(status))
8451 {
8452 /* NV module cannot be initialized */
8453 hddLog( VOS_TRACE_LEVEL_FATAL,
8454 "%s: vos_init_wiphy failed", __func__);
8455 goto err_vos_nv_close;
8456 }
8457
Amar Singhala49cbc52013-10-08 18:37:44 -07008458#endif
8459
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308460 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 if ( !VOS_IS_STATUS_SUCCESS( status ))
8462 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008463 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308464 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 }
8466
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8468
8469 if ( NULL == pHddCtx->hHal )
8470 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008471 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008472 goto err_vosclose;
8473 }
8474
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008475 status = vos_preStart( pHddCtx->pvosContext );
8476 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8477 {
8478 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308479 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008480 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008481
Arif Hussaineaf68602013-12-30 23:10:44 -08008482 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8483 {
8484 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8485 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8486 __func__, enable_dfs_chan_scan);
8487 }
8488 if (0 == enable_11d || 1 == enable_11d)
8489 {
8490 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8491 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8492 __func__, enable_11d);
8493 }
8494
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008495 /* Note that the vos_preStart() sequence triggers the cfg download.
8496 The cfg download must occur before we update the SME config
8497 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008498 status = hdd_set_sme_config( pHddCtx );
8499
8500 if ( VOS_STATUS_SUCCESS != status )
8501 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008502 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308503 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008504 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008505
8506 //Initialize the WMM module
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07008507 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra);
8508 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p);
Jeff Johnson295189b2012-06-20 16:38:30 -07008509 if (!VOS_IS_STATUS_SUCCESS(status))
8510 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008511 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308512 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008513 }
8514
Jeff Johnson295189b2012-06-20 16:38:30 -07008515 /* In the integrated architecture we update the configuration from
8516 the INI file and from NV before vOSS has been started so that
8517 the final contents are available to send down to the cCPU */
8518
8519 // Apply the cfg.ini to cfg.dat
8520 if (FALSE == hdd_update_config_dat(pHddCtx))
8521 {
8522 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308523 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008524 }
8525
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308526 // Get mac addr from platform driver
8527 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8528
8529 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008530 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308531 /* Store the mac addr for first interface */
8532 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8533
8534 hddLog(VOS_TRACE_LEVEL_ERROR,
8535 "%s: WLAN Mac Addr: "
8536 MAC_ADDRESS_STR, __func__,
8537 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8538
8539 /* Here, passing Arg2 as 1 because we do not want to change the
8540 last 3 bytes (means non OUI bytes) of first interface mac
8541 addr.
8542 */
8543 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8544 {
8545 hddLog(VOS_TRACE_LEVEL_ERROR,
8546 "%s: Failed to generate wlan interface mac addr "
8547 "using MAC from ini file ", __func__);
8548 }
8549 }
8550 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8551 {
8552 // Apply the NV to cfg.dat
8553 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008554#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8555 /* There was not a valid set of MAC Addresses in NV. See if the
8556 default addresses were modified by the cfg.ini settings. If so,
8557 we'll use them, but if not, we'll autogenerate a set of MAC
8558 addresses based upon the device serial number */
8559
8560 static const v_MACADDR_t default_address =
8561 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008562
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308563 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8564 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 {
8566 /* cfg.ini has the default address, invoke autogen logic */
8567
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308568 /* Here, passing Arg2 as 0 because we want to change the
8569 last 3 bytes (means non OUI bytes) of all the interfaces
8570 mac addr.
8571 */
8572 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8573 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308575 hddLog(VOS_TRACE_LEVEL_ERROR,
8576 "%s: Failed to generate wlan interface mac addr "
8577 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8578 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 }
8581 else
8582#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8583 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008584 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008585 "%s: Invalid MAC address in NV, using MAC from ini file "
8586 MAC_ADDRESS_STR, __func__,
8587 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8588 }
8589 }
8590 {
8591 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308592
8593 /* Set the MAC Address Currently this is used by HAL to
8594 * add self sta. Remove this once self sta is added as
8595 * part of session open.
8596 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8598 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8599 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308600
Jeff Johnson295189b2012-06-20 16:38:30 -07008601 if (!HAL_STATUS_SUCCESS( halStatus ))
8602 {
8603 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8604 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308605 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008606 }
8607 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008608
8609 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8610 Note: Firmware image will be read and downloaded inside vos_start API */
8611 status = vos_start( pHddCtx->pvosContext );
8612 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8613 {
8614 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308615 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008616 }
8617
Leo Chang6cec3e22014-01-21 15:33:49 -08008618#ifdef FEATURE_WLAN_CH_AVOID
8619 /* Plug in avoid channel notification callback
8620 * This should happen before ADD_SELF_STA
8621 * FW will send first IND with ADD_SELF_STA REQ from host */
8622 sme_AddChAvoidCallback(pHddCtx->hHal,
8623 hdd_hostapd_ch_avoid_cb);
8624#endif /* FEATURE_WLAN_CH_AVOID */
8625
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008626 /* Exchange capability info between Host and FW and also get versioning info from FW */
8627 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008628
8629 status = hdd_post_voss_start_config( pHddCtx );
8630 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8631 {
8632 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8633 __func__);
8634 goto err_vosstop;
8635 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008636
8637#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308638 wlan_hdd_cfg80211_update_reg_info( wiphy );
8639
8640 /* registration of wiphy dev with cfg80211 */
8641 if (0 > wlan_hdd_cfg80211_register(wiphy))
8642 {
8643 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8644 goto err_vosstop;
8645 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008646#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008647
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308648#ifdef CONFIG_ENABLE_LINUX_REG
8649 status = wlan_hdd_init_channels(pHddCtx);
8650 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8651 {
8652 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8653 __func__);
8654 goto err_vosstop;
8655 }
8656
8657 /* registration of wiphy dev with cfg80211 */
8658 if (0 > wlan_hdd_cfg80211_register(wiphy))
8659 {
8660 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8661 goto err_vosstop;
8662 }
8663
8664 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8665 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8666 {
8667 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8668 __func__);
8669 goto err_unregister_wiphy;
8670 }
8671#endif
8672
Jeff Johnson295189b2012-06-20 16:38:30 -07008673 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8674 {
8675 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8676 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8677 }
8678 else
8679 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8681 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8682 if (pAdapter != NULL)
8683 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308684 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008685 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308686 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8687 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8688 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008689
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308690 /* Generate the P2P Device Address. This consists of the device's
8691 * primary MAC address with the locally administered bit set.
8692 */
8693 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008694 }
8695 else
8696 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308697 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8698 if (p2p_dev_addr != NULL)
8699 {
8700 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8701 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8702 }
8703 else
8704 {
8705 hddLog(VOS_TRACE_LEVEL_FATAL,
8706 "%s: Failed to allocate mac_address for p2p_device",
8707 __func__);
8708 goto err_close_adapter;
8709 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008710 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008711
8712 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8713 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8714 if ( NULL == pP2pAdapter )
8715 {
8716 hddLog(VOS_TRACE_LEVEL_FATAL,
8717 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008718 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008719 goto err_close_adapter;
8720 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008721 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008722 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008723
8724 if( pAdapter == NULL )
8725 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8727 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008729
Arif Hussain66559122013-11-21 10:11:40 -08008730 if (country_code)
8731 {
8732 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008733 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008734 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8735#ifndef CONFIG_ENABLE_LINUX_REG
8736 hdd_checkandupdate_phymode(pAdapter, country_code);
8737#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008738 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8739 (void *)(tSmeChangeCountryCallback)
8740 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008741 country_code,
8742 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308743 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008744 if (eHAL_STATUS_SUCCESS == ret)
8745 {
Arif Hussaincb607082013-12-20 11:57:42 -08008746 ret = wait_for_completion_interruptible_timeout(
8747 &pAdapter->change_country_code,
8748 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8749
8750 if (0 >= ret)
8751 {
8752 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8753 "%s: SME while setting country code timed out", __func__);
8754 }
Arif Hussain66559122013-11-21 10:11:40 -08008755 }
8756 else
8757 {
Arif Hussaincb607082013-12-20 11:57:42 -08008758 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8759 "%s: SME Change Country code from module param fail ret=%d",
8760 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008761 }
8762 }
8763
Jeff Johnson295189b2012-06-20 16:38:30 -07008764#ifdef WLAN_BTAMP_FEATURE
8765 vStatus = WLANBAP_Open(pVosContext);
8766 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8767 {
8768 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8769 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008770 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008771 }
8772
8773 vStatus = BSL_Init(pVosContext);
8774 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8775 {
8776 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8777 "%s: Failed to Init BSL",__func__);
8778 goto err_bap_close;
8779 }
8780 vStatus = WLANBAP_Start(pVosContext);
8781 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8782 {
8783 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8784 "%s: Failed to start TL",__func__);
8785 goto err_bap_close;
8786 }
8787
8788 pConfig = pHddCtx->cfg_ini;
8789 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8790 status = WLANBAP_SetConfig(&btAmpConfig);
8791
8792#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008793
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008794#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8795 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8796 {
8797 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8798 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8799 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8800 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8801 }
8802#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008803#ifdef FEATURE_WLAN_SCAN_PNO
8804 /*SME must send channel update configuration to RIVA*/
8805 sme_UpdateChannelConfig(pHddCtx->hHal);
8806#endif
8807
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308808 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8809
Jeff Johnson295189b2012-06-20 16:38:30 -07008810 /* Register with platform driver as client for Suspend/Resume */
8811 status = hddRegisterPmOps(pHddCtx);
8812 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8813 {
8814 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8815#ifdef WLAN_BTAMP_FEATURE
8816 goto err_bap_stop;
8817#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008818 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008819#endif //WLAN_BTAMP_FEATURE
8820 }
8821
Yue Ma0d4891e2013-08-06 17:01:45 -07008822 /* Open debugfs interface */
8823 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8824 {
8825 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8826 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008827 }
8828
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 /* Register TM level change handler function to the platform */
8830 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8831 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8832 {
8833 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8834 goto err_unregister_pmops;
8835 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008836
8837 /* register for riva power on lock to platform driver */
8838 if (req_riva_power_on_lock("wlan"))
8839 {
8840 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8841 __func__);
8842 goto err_unregister_pmops;
8843 }
8844
Jeff Johnson295189b2012-06-20 16:38:30 -07008845 // register net device notifier for device change notification
8846 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8847
8848 if(ret < 0)
8849 {
8850 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8851 goto err_free_power_on_lock;
8852 }
8853
8854 //Initialize the nlink service
8855 if(nl_srv_init() != 0)
8856 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308857 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008858 goto err_reg_netdev;
8859 }
8860
Leo Chang4ce1cc52013-10-21 18:27:15 -07008861#ifdef WLAN_KD_READY_NOTIFIER
8862 pHddCtx->kd_nl_init = 1;
8863#endif /* WLAN_KD_READY_NOTIFIER */
8864
Jeff Johnson295189b2012-06-20 16:38:30 -07008865 //Initialize the BTC service
8866 if(btc_activate_service(pHddCtx) != 0)
8867 {
8868 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8869 goto err_nl_srv;
8870 }
8871
8872#ifdef PTT_SOCK_SVC_ENABLE
8873 //Initialize the PTT service
8874 if(ptt_sock_activate_svc(pHddCtx) != 0)
8875 {
8876 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8877 goto err_nl_srv;
8878 }
8879#endif
8880
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308881#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
8882 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
8883 {
8884 if(wlan_logging_sock_activate_svc(
8885 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
8886 pHddCtx->cfg_ini->wlanLoggingNumBuf))
8887 {
8888 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
8889 " failed", __func__);
8890 goto err_nl_srv;
8891 }
8892 }
8893#endif
8894
Jeff Johnson295189b2012-06-20 16:38:30 -07008895 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008897 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008898 /* Action frame registered in one adapter which will
8899 * applicable to all interfaces
8900 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308901 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008902 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008903
8904 mutex_init(&pHddCtx->sap_lock);
8905
Mihir Shete18156292014-03-11 15:38:30 +05308906 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008907
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008908#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008909#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8910 /* Initialize the wake lcok */
8911 wake_lock_init(&pHddCtx->rx_wake_lock,
8912 WAKE_LOCK_SUSPEND,
8913 "qcom_rx_wakelock");
8914#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008915 /* Initialize the wake lcok */
8916 wake_lock_init(&pHddCtx->sap_wake_lock,
8917 WAKE_LOCK_SUSPEND,
8918 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008919#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008920
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008921 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8922 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008923
8924 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8925 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308926#ifndef CONFIG_ENABLE_LINUX_REG
8927 /*updating wiphy so that regulatory user hints can be processed*/
8928 if (wiphy)
8929 {
8930 regulatory_hint(wiphy, "00");
8931 }
8932#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008933 // Initialize the restart logic
8934 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308935
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008936 //Register the traffic monitor timer now
8937 if ( pHddCtx->cfg_ini->dynSplitscan)
8938 {
8939 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8940 VOS_TIMER_TYPE_SW,
8941 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8942 (void *)pHddCtx);
8943 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008944 goto success;
8945
8946err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008947#ifdef WLAN_KD_READY_NOTIFIER
8948 nl_srv_exit(pHddCtx->ptt_pid);
8949#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008951#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008952err_reg_netdev:
8953 unregister_netdevice_notifier(&hdd_netdev_notifier);
8954
8955err_free_power_on_lock:
8956 free_riva_power_on_lock("wlan");
8957
8958err_unregister_pmops:
8959 hddDevTmUnregisterNotifyCallback(pHddCtx);
8960 hddDeregisterPmOps(pHddCtx);
8961
Yue Ma0d4891e2013-08-06 17:01:45 -07008962 hdd_debugfs_exit(pHddCtx);
8963
Jeff Johnson295189b2012-06-20 16:38:30 -07008964#ifdef WLAN_BTAMP_FEATURE
8965err_bap_stop:
8966 WLANBAP_Stop(pVosContext);
8967#endif
8968
8969#ifdef WLAN_BTAMP_FEATURE
8970err_bap_close:
8971 WLANBAP_Close(pVosContext);
8972#endif
8973
Jeff Johnson295189b2012-06-20 16:38:30 -07008974err_close_adapter:
8975 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308976err_unregister_wiphy:
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308977 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008978err_vosstop:
8979 vos_stop(pVosContext);
8980
Amar Singhala49cbc52013-10-08 18:37:44 -07008981err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 status = vos_sched_close( pVosContext );
8983 if (!VOS_IS_STATUS_SUCCESS(status)) {
8984 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8985 "%s: Failed to close VOSS Scheduler", __func__);
8986 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8987 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008988 vos_close(pVosContext );
8989
Amar Singhal0a402232013-10-11 20:57:16 -07008990err_vos_nv_close:
8991
c_hpothue6a36282014-03-19 12:27:38 +05308992#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008993 vos_nv_close();
8994
Jeff Johnson295189b2012-06-20 16:38:30 -07008995err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05308996#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008997 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008998
8999err_wdclose:
9000 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9001 vos_watchdog_close(pVosContext);
9002
Jeff Johnson295189b2012-06-20 16:38:30 -07009003err_config:
9004 kfree(pHddCtx->cfg_ini);
9005 pHddCtx->cfg_ini= NULL;
9006
9007err_free_hdd_context:
9008 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009009 wiphy_free(wiphy) ;
9010 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009011 VOS_BUG(1);
9012
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009013 if (hdd_is_ssr_required())
9014 {
9015 /* WDI timeout had happened during load, so SSR is needed here */
9016 subsystem_restart("wcnss");
9017 msleep(5000);
9018 }
9019 hdd_set_ssr_required (VOS_FALSE);
9020
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009021 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009022
9023success:
9024 EXIT();
9025 return 0;
9026}
9027
9028/**---------------------------------------------------------------------------
9029
Jeff Johnson32d95a32012-09-10 13:15:23 -07009030 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009031
Jeff Johnson32d95a32012-09-10 13:15:23 -07009032 This is the driver entry point - called in different timeline depending
9033 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009034
9035 \param - None
9036
9037 \return - 0 for success, non zero for failure
9038
9039 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009040static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009041{
9042 VOS_STATUS status;
9043 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009044 struct device *dev = NULL;
9045 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009046#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9047 int max_retries = 0;
9048#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009049
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309050#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9051 wlan_logging_sock_init_svc();
9052#endif
9053
Jeff Johnson295189b2012-06-20 16:38:30 -07009054 ENTER();
9055
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009056#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009057 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009058#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009059
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309060 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9062 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9063
9064 //Power Up Libra WLAN card first if not already powered up
9065 status = vos_chipPowerUp(NULL,NULL,NULL);
9066 if (!VOS_IS_STATUS_SUCCESS(status))
9067 {
9068 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9069 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309070#ifdef WLAN_OPEN_SOURCE
9071 wake_lock_destroy(&wlan_wake_lock);
9072#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309073
9074#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9075 wlan_logging_sock_deinit_svc();
9076#endif
9077
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009078 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009079 }
9080
Jeff Johnson295189b2012-06-20 16:38:30 -07009081#ifdef ANI_BUS_TYPE_PCI
9082
9083 dev = wcnss_wlan_get_device();
9084
9085#endif // ANI_BUS_TYPE_PCI
9086
9087#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009088
9089#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9090 /* wait until WCNSS driver downloads NV */
9091 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9092 msleep(1000);
9093 }
9094 if (max_retries >= 5) {
9095 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309096#ifdef WLAN_OPEN_SOURCE
9097 wake_lock_destroy(&wlan_wake_lock);
9098#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309099
9100#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9101 wlan_logging_sock_deinit_svc();
9102#endif
9103
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009104 return -ENODEV;
9105 }
9106#endif
9107
Jeff Johnson295189b2012-06-20 16:38:30 -07009108 dev = wcnss_wlan_get_device();
9109#endif // ANI_BUS_TYPE_PLATFORM
9110
9111
9112 do {
9113 if (NULL == dev) {
9114 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9115 ret_status = -1;
9116 break;
9117 }
9118
Jeff Johnson295189b2012-06-20 16:38:30 -07009119#ifdef TIMER_MANAGER
9120 vos_timer_manager_init();
9121#endif
9122
9123 /* Preopen VOSS so that it is ready to start at least SAL */
9124 status = vos_preOpen(&pVosContext);
9125
9126 if (!VOS_IS_STATUS_SUCCESS(status))
9127 {
9128 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9129 ret_status = -1;
9130 break;
9131 }
9132
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009133#ifndef MODULE
9134 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9135 */
9136 hdd_set_conparam((v_UINT_t)con_mode);
9137#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009138
9139 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009140 if (hdd_wlan_startup(dev))
9141 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009143 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 vos_preClose( &pVosContext );
9145 ret_status = -1;
9146 break;
9147 }
9148
9149 /* Cancel the vote for XO Core ON
9150 * This is done here for safety purposes in case we re-initialize without turning
9151 * it OFF in any error scenario.
9152 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009153 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009155 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9157 {
9158 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009159 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 }
9161 } while (0);
9162
9163 if (0 != ret_status)
9164 {
9165 //Assert Deep sleep signal now to put Libra HW in lowest power state
9166 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9167 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9168
9169 //Vote off any PMIC voltage supplies
9170 vos_chipPowerDown(NULL, NULL, NULL);
9171#ifdef TIMER_MANAGER
9172 vos_timer_exit();
9173#endif
9174#ifdef MEMORY_DEBUG
9175 vos_mem_exit();
9176#endif
9177
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009178#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009179 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009180#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309181
9182#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9183 wlan_logging_sock_deinit_svc();
9184#endif
9185
Jeff Johnson295189b2012-06-20 16:38:30 -07009186 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9187 }
9188 else
9189 {
9190 //Send WLAN UP indication to Nlink Service
9191 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9192
9193 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 }
9195
9196 EXIT();
9197
9198 return ret_status;
9199}
9200
Jeff Johnson32d95a32012-09-10 13:15:23 -07009201/**---------------------------------------------------------------------------
9202
9203 \brief hdd_module_init() - Init Function
9204
9205 This is the driver entry point (invoked when module is loaded using insmod)
9206
9207 \param - None
9208
9209 \return - 0 for success, non zero for failure
9210
9211 --------------------------------------------------------------------------*/
9212#ifdef MODULE
9213static int __init hdd_module_init ( void)
9214{
9215 return hdd_driver_init();
9216}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009217#else /* #ifdef MODULE */
9218static int __init hdd_module_init ( void)
9219{
9220 /* Driver initialization is delayed to fwpath_changed_handler */
9221 return 0;
9222}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009223#endif /* #ifdef MODULE */
9224
Jeff Johnson295189b2012-06-20 16:38:30 -07009225
9226/**---------------------------------------------------------------------------
9227
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009228 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009229
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009230 This is the driver exit point (invoked when module is unloaded using rmmod
9231 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009232
9233 \param - None
9234
9235 \return - None
9236
9237 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009238static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009239{
9240 hdd_context_t *pHddCtx = NULL;
9241 v_CONTEXT_t pVosContext = NULL;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309242 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009243
9244 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9245
9246 //Get the global vos context
9247 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9248
9249 if(!pVosContext)
9250 {
9251 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9252 goto done;
9253 }
9254
9255 //Get the HDD context.
9256 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9257
9258 if(!pHddCtx)
9259 {
9260 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9261 }
9262 else
9263 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309264 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9265
9266 if (pHddCtx->isLogpInProgress)
9267 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309269 "%s:SSR in Progress; block rmmod !!!", __func__);
9270 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9271 msecs_to_jiffies(30000));
9272 if(!rc)
9273 {
9274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9275 "%s:SSR timedout, fatal error", __func__);
9276 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009277 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309278 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009279
Mihir Shete18156292014-03-11 15:38:30 +05309280 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9282
9283 //Do all the cleanup before deregistering the driver
9284 hdd_wlan_exit(pHddCtx);
9285 }
9286
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 vos_preClose( &pVosContext );
9288
9289#ifdef TIMER_MANAGER
9290 vos_timer_exit();
9291#endif
9292#ifdef MEMORY_DEBUG
9293 vos_mem_exit();
9294#endif
9295
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309296#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9297 wlan_logging_sock_deinit_svc();
9298#endif
9299
Jeff Johnson295189b2012-06-20 16:38:30 -07009300done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009301#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009303#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309304
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9306}
9307
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009308/**---------------------------------------------------------------------------
9309
9310 \brief hdd_module_exit() - Exit function
9311
9312 This is the driver exit point (invoked when module is unloaded using rmmod)
9313
9314 \param - None
9315
9316 \return - None
9317
9318 --------------------------------------------------------------------------*/
9319static void __exit hdd_module_exit(void)
9320{
9321 hdd_driver_exit();
9322}
9323
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009324#ifdef MODULE
9325static int fwpath_changed_handler(const char *kmessage,
9326 struct kernel_param *kp)
9327{
Jeff Johnson76052702013-04-16 13:55:05 -07009328 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009329}
9330
9331static int con_mode_handler(const char *kmessage,
9332 struct kernel_param *kp)
9333{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009334 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009335}
9336#else /* #ifdef MODULE */
9337/**---------------------------------------------------------------------------
9338
Jeff Johnson76052702013-04-16 13:55:05 -07009339 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009340
Jeff Johnson76052702013-04-16 13:55:05 -07009341 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009342 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009343 - invoked when module parameter fwpath is modified from userspace to signal
9344 initializing the WLAN driver or when con_mode is modified from userspace
9345 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009346
9347 \return - 0 for success, non zero for failure
9348
9349 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009350static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009351{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009352 int ret_status;
9353
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009354 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009355 ret_status = hdd_driver_init();
9356 wlan_hdd_inited = ret_status ? 0 : 1;
9357 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009358 }
9359
9360 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009361
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009362 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009363
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009364 ret_status = hdd_driver_init();
9365 wlan_hdd_inited = ret_status ? 0 : 1;
9366 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009367}
9368
Jeff Johnson295189b2012-06-20 16:38:30 -07009369/**---------------------------------------------------------------------------
9370
Jeff Johnson76052702013-04-16 13:55:05 -07009371 \brief fwpath_changed_handler() - Handler Function
9372
9373 Handle changes to the fwpath parameter
9374
9375 \return - 0 for success, non zero for failure
9376
9377 --------------------------------------------------------------------------*/
9378static int fwpath_changed_handler(const char *kmessage,
9379 struct kernel_param *kp)
9380{
9381 int ret;
9382
9383 ret = param_set_copystring(kmessage, kp);
9384 if (0 == ret)
9385 ret = kickstart_driver();
9386 return ret;
9387}
9388
9389/**---------------------------------------------------------------------------
9390
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009391 \brief con_mode_handler() -
9392
9393 Handler function for module param con_mode when it is changed by userspace
9394 Dynamically linked - do nothing
9395 Statically linked - exit and init driver, as in rmmod and insmod
9396
Jeff Johnson76052702013-04-16 13:55:05 -07009397 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009398
Jeff Johnson76052702013-04-16 13:55:05 -07009399 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009400
9401 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009402static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009403{
Jeff Johnson76052702013-04-16 13:55:05 -07009404 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009405
Jeff Johnson76052702013-04-16 13:55:05 -07009406 ret = param_set_int(kmessage, kp);
9407 if (0 == ret)
9408 ret = kickstart_driver();
9409 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009410}
9411#endif /* #ifdef MODULE */
9412
9413/**---------------------------------------------------------------------------
9414
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 \brief hdd_get_conparam() -
9416
9417 This is the driver exit point (invoked when module is unloaded using rmmod)
9418
9419 \param - None
9420
9421 \return - tVOS_CON_MODE
9422
9423 --------------------------------------------------------------------------*/
9424tVOS_CON_MODE hdd_get_conparam ( void )
9425{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009426#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009428#else
9429 return (tVOS_CON_MODE)curr_con_mode;
9430#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009431}
9432void hdd_set_conparam ( v_UINT_t newParam )
9433{
9434 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009435#ifndef MODULE
9436 curr_con_mode = con_mode;
9437#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009438}
9439/**---------------------------------------------------------------------------
9440
9441 \brief hdd_softap_sta_deauth() - function
9442
9443 This to take counter measure to handle deauth req from HDD
9444
9445 \param - pAdapter - Pointer to the HDD
9446
9447 \param - enable - boolean value
9448
9449 \return - None
9450
9451 --------------------------------------------------------------------------*/
9452
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009453VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009454{
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009456 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009457
9458 ENTER();
9459
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009460 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9461 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009462
9463 //Ignore request to deauth bcmc station
9464 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009465 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009466
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009467 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009468
9469 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009470 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009471}
9472
9473/**---------------------------------------------------------------------------
9474
9475 \brief hdd_softap_sta_disassoc() - function
9476
9477 This to take counter measure to handle deauth req from HDD
9478
9479 \param - pAdapter - Pointer to the HDD
9480
9481 \param - enable - boolean value
9482
9483 \return - None
9484
9485 --------------------------------------------------------------------------*/
9486
9487void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9488{
9489 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9490
9491 ENTER();
9492
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309493 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009494
9495 //Ignore request to disassoc bcmc station
9496 if( pDestMacAddress[0] & 0x1 )
9497 return;
9498
9499 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9500}
9501
9502void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9503{
9504 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9505
9506 ENTER();
9507
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309508 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009509
9510 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9511}
9512
Jeff Johnson295189b2012-06-20 16:38:30 -07009513/**---------------------------------------------------------------------------
9514 *
9515 * \brief hdd_get__concurrency_mode() -
9516 *
9517 *
9518 * \param - None
9519 *
9520 * \return - CONCURRENCY MODE
9521 *
9522 * --------------------------------------------------------------------------*/
9523tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9524{
9525 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9526 hdd_context_t *pHddCtx;
9527
9528 if (NULL != pVosContext)
9529 {
9530 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9531 if (NULL != pHddCtx)
9532 {
9533 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9534 }
9535 }
9536
9537 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009538 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009539 return VOS_STA;
9540}
9541
9542/* Decide whether to allow/not the apps power collapse.
9543 * Allow apps power collapse if we are in connected state.
9544 * if not, allow only if we are in IMPS */
9545v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9546{
9547 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009548 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009549 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009550 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9551 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9552 hdd_adapter_t *pAdapter = NULL;
9553 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009554 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009555
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9557 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009558
Yathish9f22e662012-12-10 14:21:35 -08009559 concurrent_state = hdd_get_concurrency_mode();
9560
9561#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9562 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9563 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9564 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9565 return TRUE;
9566#endif
9567
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 /*loop through all adapters. TBD fix for Concurrency */
9569 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9570 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9571 {
9572 pAdapter = pAdapterNode->pAdapter;
9573 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9574 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9575 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009576 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +05309577 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -08009578 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009579 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9580 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009582 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009583 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9584 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 return FALSE;
9586 }
9587 }
9588 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9589 pAdapterNode = pNext;
9590 }
9591 return TRUE;
9592}
9593
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009594/* Decides whether to send suspend notification to Riva
9595 * if any adapter is in BMPS; then it is required */
9596v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9597{
9598 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9599 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9600
9601 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9602 {
9603 return TRUE;
9604 }
9605 return FALSE;
9606}
9607
Jeff Johnson295189b2012-06-20 16:38:30 -07009608void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9609{
9610 switch(mode)
9611 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009612 case VOS_STA_MODE:
9613 case VOS_P2P_CLIENT_MODE:
9614 case VOS_P2P_GO_MODE:
9615 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009616 pHddCtx->concurrency_mode |= (1 << mode);
9617 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 break;
9619 default:
9620 break;
9621
9622 }
9623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9624 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9625}
9626
9627
9628void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9629{
9630 switch(mode)
9631 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009632 case VOS_STA_MODE:
9633 case VOS_P2P_CLIENT_MODE:
9634 case VOS_P2P_GO_MODE:
9635 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009636 pHddCtx->no_of_sessions[mode]--;
9637 if (!(pHddCtx->no_of_sessions[mode]))
9638 pHddCtx->concurrency_mode &= (~(1 << mode));
9639 break;
9640 default:
9641 break;
9642 }
9643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9644 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9645}
9646
Jeff Johnsone7245742012-09-05 17:12:55 -07009647/**---------------------------------------------------------------------------
9648 *
9649 * \brief wlan_hdd_restart_init
9650 *
9651 * This function initalizes restart timer/flag. An internal function.
9652 *
9653 * \param - pHddCtx
9654 *
9655 * \return - None
9656 *
9657 * --------------------------------------------------------------------------*/
9658
9659static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9660{
9661 /* Initialize */
9662 pHddCtx->hdd_restart_retries = 0;
9663 atomic_set(&pHddCtx->isRestartInProgress, 0);
9664 vos_timer_init(&pHddCtx->hdd_restart_timer,
9665 VOS_TIMER_TYPE_SW,
9666 wlan_hdd_restart_timer_cb,
9667 pHddCtx);
9668}
9669/**---------------------------------------------------------------------------
9670 *
9671 * \brief wlan_hdd_restart_deinit
9672 *
9673 * This function cleans up the resources used. An internal function.
9674 *
9675 * \param - pHddCtx
9676 *
9677 * \return - None
9678 *
9679 * --------------------------------------------------------------------------*/
9680
9681static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9682{
9683
9684 VOS_STATUS vos_status;
9685 /* Block any further calls */
9686 atomic_set(&pHddCtx->isRestartInProgress, 1);
9687 /* Cleanup */
9688 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9689 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309690 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009691 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9692 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309693 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009694
9695}
9696
9697/**---------------------------------------------------------------------------
9698 *
9699 * \brief wlan_hdd_framework_restart
9700 *
9701 * This function uses a cfg80211 API to start a framework initiated WLAN
9702 * driver module unload/load.
9703 *
9704 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9705 *
9706 *
9707 * \param - pHddCtx
9708 *
9709 * \return - VOS_STATUS_SUCCESS: Success
9710 * VOS_STATUS_E_EMPTY: Adapter is Empty
9711 * VOS_STATUS_E_NOMEM: No memory
9712
9713 * --------------------------------------------------------------------------*/
9714
9715static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9716{
9717 VOS_STATUS status = VOS_STATUS_SUCCESS;
9718 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009719 int len = (sizeof (struct ieee80211_mgmt));
9720 struct ieee80211_mgmt *mgmt = NULL;
9721
9722 /* Prepare the DEAUTH managment frame with reason code */
9723 mgmt = kzalloc(len, GFP_KERNEL);
9724 if(mgmt == NULL)
9725 {
9726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9727 "%s: memory allocation failed (%d bytes)", __func__, len);
9728 return VOS_STATUS_E_NOMEM;
9729 }
9730 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009731
9732 /* Iterate over all adapters/devices */
9733 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9734 do
9735 {
9736 if( (status == VOS_STATUS_SUCCESS) &&
9737 pAdapterNode &&
9738 pAdapterNode->pAdapter)
9739 {
9740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9741 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9742 pAdapterNode->pAdapter->dev->name,
9743 pAdapterNode->pAdapter->device_mode,
9744 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009745 /*
9746 * CFG80211 event to restart the driver
9747 *
9748 * 'cfg80211_send_unprot_deauth' sends a
9749 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9750 * of SME(Linux Kernel) state machine.
9751 *
9752 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9753 * the driver.
9754 *
9755 */
9756
9757 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009758 }
9759 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9760 pAdapterNode = pNext;
9761 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9762
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009763
9764 /* Free the allocated management frame */
9765 kfree(mgmt);
9766
Jeff Johnsone7245742012-09-05 17:12:55 -07009767 /* Retry until we unload or reach max count */
9768 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9769 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9770
9771 return status;
9772
9773}
9774/**---------------------------------------------------------------------------
9775 *
9776 * \brief wlan_hdd_restart_timer_cb
9777 *
9778 * Restart timer callback. An internal function.
9779 *
9780 * \param - User data:
9781 *
9782 * \return - None
9783 *
9784 * --------------------------------------------------------------------------*/
9785
9786void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9787{
9788 hdd_context_t *pHddCtx = usrDataForCallback;
9789 wlan_hdd_framework_restart(pHddCtx);
9790 return;
9791
9792}
9793
9794
9795/**---------------------------------------------------------------------------
9796 *
9797 * \brief wlan_hdd_restart_driver
9798 *
9799 * This function sends an event to supplicant to restart the WLAN driver.
9800 *
9801 * This function is called from vos_wlanRestart.
9802 *
9803 * \param - pHddCtx
9804 *
9805 * \return - VOS_STATUS_SUCCESS: Success
9806 * VOS_STATUS_E_EMPTY: Adapter is Empty
9807 * VOS_STATUS_E_ALREADY: Request already in progress
9808
9809 * --------------------------------------------------------------------------*/
9810VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9811{
9812 VOS_STATUS status = VOS_STATUS_SUCCESS;
9813
9814 /* A tight check to make sure reentrancy */
9815 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9816 {
9817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9818 "%s: WLAN restart is already in progress", __func__);
9819
9820 return VOS_STATUS_E_ALREADY;
9821 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009822 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009823#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009824 wcnss_reset_intr();
9825#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009826
Jeff Johnsone7245742012-09-05 17:12:55 -07009827 return status;
9828}
9829
Mihir Shetee1093ba2014-01-21 20:13:32 +05309830/**---------------------------------------------------------------------------
9831 *
9832 * \brief wlan_hdd_init_channels
9833 *
9834 * This function is used to initialize the channel list in CSR
9835 *
9836 * This function is called from hdd_wlan_startup
9837 *
9838 * \param - pHddCtx: HDD context
9839 *
9840 * \return - VOS_STATUS_SUCCESS: Success
9841 * VOS_STATUS_E_FAULT: Failure reported by SME
9842
9843 * --------------------------------------------------------------------------*/
9844static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
9845{
9846 eHalStatus status;
9847
9848 status = sme_InitChannels(pHddCtx->hHal);
9849 if (HAL_STATUS_SUCCESS(status))
9850 {
9851 return VOS_STATUS_SUCCESS;
9852 }
9853 else
9854 {
9855 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
9856 __func__, status);
9857 return VOS_STATUS_E_FAULT;
9858 }
9859}
9860
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309861static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
9862{
9863 eHalStatus status;
9864
9865 status = sme_InitChannelsForCC(pHddCtx->hHal);
9866 if (HAL_STATUS_SUCCESS(status))
9867 {
9868 return VOS_STATUS_SUCCESS;
9869 }
9870 else
9871 {
9872 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
9873 __func__, status);
9874 return VOS_STATUS_E_FAULT;
9875 }
9876}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009877/*
9878 * API to find if there is any STA or P2P-Client is connected
9879 */
9880VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9881{
9882 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9883}
Jeff Johnsone7245742012-09-05 17:12:55 -07009884
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309885int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
9886{
9887 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9888 hdd_scaninfo_t *pScanInfo = NULL;
9889 int status;
9890
9891 pScanInfo = &pHddCtx->scan_info;
9892 if (pScanInfo->mScanPending)
9893 {
9894 INIT_COMPLETION(pScanInfo->abortscan_event_var);
9895 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
9896 eCSR_SCAN_ABORT_DEFAULT);
9897
9898 status = wait_for_completion_interruptible_timeout(
9899 &pScanInfo->abortscan_event_var,
9900 msecs_to_jiffies(5000));
9901 if ((!status) || (status == -ERESTARTSYS))
9902 {
9903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9904 "%s: Timeout occurred while waiting for abort scan",
9905 __func__);
9906 return -ETIMEDOUT;
9907 }
9908 }
9909 return status;
9910}
9911
Jeff Johnson295189b2012-06-20 16:38:30 -07009912//Register the module init/exit functions
9913module_init(hdd_module_init);
9914module_exit(hdd_module_exit);
9915
9916MODULE_LICENSE("Dual BSD/GPL");
9917MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9918MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9919
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009920module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9921 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009922
Jeff Johnson76052702013-04-16 13:55:05 -07009923module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009924 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009925
9926module_param(enable_dfs_chan_scan, int,
9927 S_IRUSR | S_IRGRP | S_IROTH);
9928
9929module_param(enable_11d, int,
9930 S_IRUSR | S_IRGRP | S_IROTH);
9931
9932module_param(country_code, charp,
9933 S_IRUSR | S_IRGRP | S_IROTH);