blob: 8e1c9215a06630850a15f1a0fb2ba3e73a166de7 [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
Abhishek Singhf4669da2014-05-26 15:07:49 +05305667 hddLog(VOS_TRACE_LEVEL_INFO,
5668 "%s: Set HDD connState to eConnectionState_NotConnected",
5669 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005670 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5671
5672 //Set the default operation channel
5673 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
5674
5675 /* Make the default Auth Type as OPEN*/
5676 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5677
5678 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
5679 {
5680 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005681 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005682 status, status );
5683 goto error_init_txrx;
5684 }
5685
5686 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5687
5688 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
5689 {
5690 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005691 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 status, status );
5693 goto error_wmm_init;
5694 }
5695
5696 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5697
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005698#ifdef FEATURE_WLAN_TDLS
5699 if(0 != wlan_hdd_tdls_init(pAdapter))
5700 {
5701 status = VOS_STATUS_E_FAILURE;
5702 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_tdls_init failed",__func__);
5703 goto error_tdls_init;
5704 }
5705 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5706#endif
5707
Jeff Johnson295189b2012-06-20 16:38:30 -07005708 return VOS_STATUS_SUCCESS;
5709
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005710#ifdef FEATURE_WLAN_TDLS
5711error_tdls_init:
5712 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5713 hdd_wmm_adapter_close(pAdapter);
5714#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005715error_wmm_init:
5716 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5717 hdd_deinit_tx_rx(pAdapter);
5718error_init_txrx:
5719 hdd_UnregisterWext(pWlanDev);
5720error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005721 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 {
5723 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005724 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07005725 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005726 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07005727 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305728 unsigned long rc;
5729
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305731 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005733 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305734 if (rc <= 0)
5735 hddLog(VOS_TRACE_LEVEL_ERROR,
5736 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005737 }
5738}
5739error_sme_open:
5740 return status;
5741}
5742
Jeff Johnson295189b2012-06-20 16:38:30 -07005743void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5744{
5745 hdd_cfg80211_state_t *cfgState;
5746
5747 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
5748
5749 if( NULL != cfgState->buf )
5750 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305751 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
5753 rc = wait_for_completion_interruptible_timeout(
5754 &pAdapter->tx_action_cnf_event,
5755 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305756 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005757 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08005758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305759 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
5760 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07005761 }
5762 }
5763 return;
5764}
Jeff Johnson295189b2012-06-20 16:38:30 -07005765
5766void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
5767{
5768 ENTER();
5769 switch ( pAdapter->device_mode )
5770 {
5771 case WLAN_HDD_INFRA_STATION:
5772 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07005773 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07005774 {
5775 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5776 {
5777 hdd_deinit_tx_rx( pAdapter );
5778 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5779 }
5780
5781 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5782 {
5783 hdd_wmm_adapter_close( pAdapter );
5784 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5785 }
5786
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005788#ifdef FEATURE_WLAN_TDLS
5789 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
5790 {
5791 wlan_hdd_tdls_exit(pAdapter);
5792 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
5793 }
5794#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005795
5796 break;
5797 }
5798
5799 case WLAN_HDD_SOFTAP:
5800 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05305802
5803 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
5804 {
5805 hdd_wmm_adapter_close( pAdapter );
5806 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5807 }
5808
Jeff Johnson295189b2012-06-20 16:38:30 -07005809 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005810
5811 hdd_unregister_hostapd(pAdapter);
5812 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 break;
5815 }
5816
5817 case WLAN_HDD_MONITOR:
5818 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
5821 {
5822 hdd_deinit_tx_rx( pAdapter );
5823 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
5824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005825 if(NULL != pAdapterforTx)
5826 {
5827 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
5828 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 break;
5830 }
5831
5832
5833 default:
5834 break;
5835 }
5836
5837 EXIT();
5838}
5839
5840void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
5841{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08005842 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305843
5844 ENTER();
5845 if (NULL == pAdapter)
5846 {
5847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5848 "%s: HDD adapter is Null", __func__);
5849 return;
5850 }
5851
5852 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005853
Rajeev79dbe4c2013-10-05 11:03:42 +05305854#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305855 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
5856 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08005857 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305858 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
5859 )
5860 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005861 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05305862 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08005863 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
5864 {
5865 hdd_deinit_batch_scan(pAdapter);
5866 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305867 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08005868 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305869#endif
5870
Jeff Johnson295189b2012-06-20 16:38:30 -07005871 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
5872 if( rtnl_held )
5873 {
5874 unregister_netdevice(pWlanDev);
5875 }
5876 else
5877 {
5878 unregister_netdev(pWlanDev);
5879 }
5880 // note that the pAdapter is no longer valid at this point
5881 // since the memory has been reclaimed
5882 }
5883
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05305884 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005885}
5886
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005887void hdd_set_pwrparams(hdd_context_t *pHddCtx)
5888{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305889 VOS_STATUS status;
5890 hdd_adapter_t *pAdapter = NULL;
5891 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005892
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305893 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005894
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305895 /*loop through all adapters.*/
5896 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005897 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305898 pAdapter = pAdapterNode->pAdapter;
5899 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
5900 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005901
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305902 { // we skip this registration for modes other than STA and P2P client modes.
5903 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5904 pAdapterNode = pNext;
5905 continue;
5906 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005907
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305908 //Apply Dynamic DTIM For P2P
5909 //Only if ignoreDynamicDtimInP2pMode is not set in ini
5910 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
5911 pHddCtx->cfg_ini->enableModulatedDTIM) &&
5912 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5913 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
5914 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
5915 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
5916 (eConnectionState_Associated ==
5917 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
5918 (pHddCtx->cfg_ini->fIsBmpsEnabled))
5919 {
5920 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005921
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05305922 powerRequest.uIgnoreDTIM = 1;
5923 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
5924
5925 if (pHddCtx->cfg_ini->enableModulatedDTIM)
5926 {
5927 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
5928 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
5929 }
5930 else
5931 {
5932 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
5933 }
5934
5935 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
5936 * specified during Enter/Exit BMPS when LCD off*/
5937 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5938 NULL, eANI_BOOLEAN_FALSE);
5939 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5940 NULL, eANI_BOOLEAN_FALSE);
5941
5942 /* switch to the DTIM specified in cfg.ini */
5943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5944 "Switch to DTIM %d", powerRequest.uListenInterval);
5945 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5946 break;
5947
5948 }
5949
5950 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5951 pAdapterNode = pNext;
5952 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005953}
5954
5955void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
5956{
5957 /*Switch back to DTIM 1*/
5958 tSirSetPowerParamsReq powerRequest = { 0 };
5959
5960 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
5961 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07005962 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08005963
5964 /* Update ignoreDTIM and ListedInterval in CFG with default values */
5965 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
5966 NULL, eANI_BOOLEAN_FALSE);
5967 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
5968 NULL, eANI_BOOLEAN_FALSE);
5969
5970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5971 "Switch to DTIM%d",powerRequest.uListenInterval);
5972 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
5973
5974}
5975
Jeff Johnson295189b2012-06-20 16:38:30 -07005976VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
5977{
5978 VOS_STATUS status = VOS_STATUS_SUCCESS;
5979
5980 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
5981 {
5982 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
5983 }
5984
5985 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
5986 {
5987 sme_StartAutoBmpsTimer(pHddCtx->hHal);
5988 }
5989
5990 if (pHddCtx->cfg_ini->fIsImpsEnabled)
5991 {
5992 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
5993 }
5994
5995 return status;
5996}
5997
5998VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
5999{
6000 hdd_adapter_t *pAdapter = NULL;
6001 eHalStatus halStatus;
6002 VOS_STATUS status = VOS_STATUS_E_INVAL;
6003 v_BOOL_t disableBmps = FALSE;
6004 v_BOOL_t disableImps = FALSE;
6005
6006 switch(session_type)
6007 {
6008 case WLAN_HDD_INFRA_STATION:
6009 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 case WLAN_HDD_P2P_CLIENT:
6011 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 //Exit BMPS -> Is Sta/P2P Client is already connected
6013 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6014 if((NULL != pAdapter)&&
6015 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6016 {
6017 disableBmps = TRUE;
6018 }
6019
6020 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6021 if((NULL != pAdapter)&&
6022 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6023 {
6024 disableBmps = TRUE;
6025 }
6026
6027 //Exit both Bmps and Imps incase of Go/SAP Mode
6028 if((WLAN_HDD_SOFTAP == session_type) ||
6029 (WLAN_HDD_P2P_GO == session_type))
6030 {
6031 disableBmps = TRUE;
6032 disableImps = TRUE;
6033 }
6034
6035 if(TRUE == disableImps)
6036 {
6037 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6038 {
6039 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6040 }
6041 }
6042
6043 if(TRUE == disableBmps)
6044 {
6045 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6046 {
6047 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6048
6049 if(eHAL_STATUS_SUCCESS != halStatus)
6050 {
6051 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006052 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006053 VOS_ASSERT(0);
6054 return status;
6055 }
6056 }
6057
6058 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6059 {
6060 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6061
6062 if(eHAL_STATUS_SUCCESS != halStatus)
6063 {
6064 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006065 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006066 VOS_ASSERT(0);
6067 return status;
6068 }
6069 }
6070 }
6071
6072 if((TRUE == disableBmps) ||
6073 (TRUE == disableImps))
6074 {
6075 /* Now, get the chip into Full Power now */
6076 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6077 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6078 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6079
6080 if(halStatus != eHAL_STATUS_SUCCESS)
6081 {
6082 if(halStatus == eHAL_STATUS_PMC_PENDING)
6083 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306084 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006085 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306086 ret = wait_for_completion_interruptible_timeout(
6087 &pHddCtx->full_pwr_comp_var,
6088 msecs_to_jiffies(1000));
6089 if (ret <= 0)
6090 {
6091 hddLog(VOS_TRACE_LEVEL_ERROR,
6092 "%s: wait on full_pwr_comp_var failed %ld",
6093 __func__, ret);
6094 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006095 }
6096 else
6097 {
6098 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006099 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006100 VOS_ASSERT(0);
6101 return status;
6102 }
6103 }
6104
6105 status = VOS_STATUS_SUCCESS;
6106 }
6107
6108 break;
6109 }
6110 return status;
6111}
6112
6113hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006114 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 tANI_U8 rtnl_held )
6116{
6117 hdd_adapter_t *pAdapter = NULL;
6118 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6119 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6120 VOS_STATUS exitbmpsStatus;
6121
Arif Hussain6d2a3322013-11-17 19:50:10 -08006122 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006123
Nirav Shah436658f2014-02-28 17:05:45 +05306124 if(macAddr == NULL)
6125 {
6126 /* Not received valid macAddr */
6127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6128 "%s:Unable to add virtual intf: Not able to get"
6129 "valid mac address",__func__);
6130 return NULL;
6131 }
6132
Jeff Johnson295189b2012-06-20 16:38:30 -07006133 //Disable BMPS incase of Concurrency
6134 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6135
6136 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6137 {
6138 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306139 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006140 VOS_ASSERT(0);
6141 return NULL;
6142 }
6143
6144 switch(session_type)
6145 {
6146 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006147 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006148 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006149 {
6150 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6151
6152 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306153 {
6154 hddLog(VOS_TRACE_LEVEL_FATAL,
6155 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006156 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306157 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006158
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306159#ifdef FEATURE_WLAN_TDLS
6160 /* A Mutex Lock is introduced while changing/initializing the mode to
6161 * protect the concurrent access for the Adapters by TDLS module.
6162 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306163 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306164#endif
6165
Jeff Johnsone7245742012-09-05 17:12:55 -07006166 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6167 NL80211_IFTYPE_P2P_CLIENT:
6168 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006169
Jeff Johnson295189b2012-06-20 16:38:30 -07006170 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306171#ifdef FEATURE_WLAN_TDLS
6172 mutex_unlock(&pHddCtx->tdls_lock);
6173#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306174
6175 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006176 if( VOS_STATUS_SUCCESS != status )
6177 goto err_free_netdev;
6178
6179 status = hdd_register_interface( pAdapter, rtnl_held );
6180 if( VOS_STATUS_SUCCESS != status )
6181 {
6182 hdd_deinit_adapter(pHddCtx, pAdapter);
6183 goto err_free_netdev;
6184 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306185
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306186 // Workqueue which gets scheduled in IPv4 notification callback.
6187 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6188
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306189#ifdef WLAN_NS_OFFLOAD
6190 // Workqueue which gets scheduled in IPv6 notification callback.
6191 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 //Stop the Interface TX queue.
6194 netif_tx_disable(pAdapter->dev);
6195 //netif_tx_disable(pWlanDev);
6196 netif_carrier_off(pAdapter->dev);
6197
6198 break;
6199 }
6200
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006202 case WLAN_HDD_SOFTAP:
6203 {
6204 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6205 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306206 {
6207 hddLog(VOS_TRACE_LEVEL_FATAL,
6208 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006209 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306210 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006211
Jeff Johnson295189b2012-06-20 16:38:30 -07006212 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6213 NL80211_IFTYPE_AP:
6214 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006215 pAdapter->device_mode = session_type;
6216
6217 status = hdd_init_ap_mode(pAdapter);
6218 if( VOS_STATUS_SUCCESS != status )
6219 goto err_free_netdev;
6220
6221 status = hdd_register_hostapd( pAdapter, rtnl_held );
6222 if( VOS_STATUS_SUCCESS != status )
6223 {
6224 hdd_deinit_adapter(pHddCtx, pAdapter);
6225 goto err_free_netdev;
6226 }
6227
6228 netif_tx_disable(pAdapter->dev);
6229 netif_carrier_off(pAdapter->dev);
6230
6231 hdd_set_conparam( 1 );
6232 break;
6233 }
6234 case WLAN_HDD_MONITOR:
6235 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6237 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306238 {
6239 hddLog(VOS_TRACE_LEVEL_FATAL,
6240 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006241 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306242 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006243
6244 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6245 pAdapter->device_mode = session_type;
6246 status = hdd_register_interface( pAdapter, rtnl_held );
6247#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6248 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6249#else
6250 pAdapter->dev->open = hdd_mon_open;
6251 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6252#endif
6253 hdd_init_tx_rx( pAdapter );
6254 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6255 //Set adapter to be used for data tx. It will use either GO or softap.
6256 pAdapter->sessionCtx.monitor.pAdapterForTx =
6257 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6259 {
6260 pAdapter->sessionCtx.monitor.pAdapterForTx =
6261 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6262 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006263 /* This workqueue will be used to transmit management packet over
6264 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006265 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6266 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6267 return NULL;
6268 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006269
Jeff Johnson295189b2012-06-20 16:38:30 -07006270 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6271 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006272 }
6273 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006274 case WLAN_HDD_FTM:
6275 {
6276 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6277
6278 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306279 {
6280 hddLog(VOS_TRACE_LEVEL_FATAL,
6281 FL("failed to allocate adapter for session %d"), session_type);
6282 return NULL;
6283 }
6284
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6286 * message while loading driver in FTM mode. */
6287 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6288 pAdapter->device_mode = session_type;
6289 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306290
6291 hdd_init_tx_rx( pAdapter );
6292
6293 //Stop the Interface TX queue.
6294 netif_tx_disable(pAdapter->dev);
6295 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 }
6297 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 default:
6299 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306300 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6301 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 VOS_ASSERT(0);
6303 return NULL;
6304 }
6305 }
6306
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 if( VOS_STATUS_SUCCESS == status )
6308 {
6309 //Add it to the hdd's session list.
6310 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6311 if( NULL == pHddAdapterNode )
6312 {
6313 status = VOS_STATUS_E_NOMEM;
6314 }
6315 else
6316 {
6317 pHddAdapterNode->pAdapter = pAdapter;
6318 status = hdd_add_adapter_back ( pHddCtx,
6319 pHddAdapterNode );
6320 }
6321 }
6322
6323 if( VOS_STATUS_SUCCESS != status )
6324 {
6325 if( NULL != pAdapter )
6326 {
6327 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6328 pAdapter = NULL;
6329 }
6330 if( NULL != pHddAdapterNode )
6331 {
6332 vos_mem_free( pHddAdapterNode );
6333 }
6334
6335 goto resume_bmps;
6336 }
6337
6338 if(VOS_STATUS_SUCCESS == status)
6339 {
6340 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6341
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006342 //Initialize the WoWL service
6343 if(!hdd_init_wowl(pAdapter))
6344 {
6345 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6346 goto err_free_netdev;
6347 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 return pAdapter;
6350
6351err_free_netdev:
6352 free_netdev(pAdapter->dev);
6353 wlan_hdd_release_intf_addr( pHddCtx,
6354 pAdapter->macAddressCurrent.bytes );
6355
6356resume_bmps:
6357 //If bmps disabled enable it
6358 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6359 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306360 if (pHddCtx->hdd_wlan_suspended)
6361 {
6362 hdd_set_pwrparams(pHddCtx);
6363 }
6364 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 }
6366 return NULL;
6367}
6368
6369VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6370 tANI_U8 rtnl_held )
6371{
6372 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6373 VOS_STATUS status;
6374
6375 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6376 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306377 {
6378 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6379 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006380 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306381 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006382
6383 while ( pCurrent->pAdapter != pAdapter )
6384 {
6385 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6386 if( VOS_STATUS_SUCCESS != status )
6387 break;
6388
6389 pCurrent = pNext;
6390 }
6391 pAdapterNode = pCurrent;
6392 if( VOS_STATUS_SUCCESS == status )
6393 {
6394 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6395 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306396
6397#ifdef FEATURE_WLAN_TDLS
6398
6399 /* A Mutex Lock is introduced while changing/initializing the mode to
6400 * protect the concurrent access for the Adapters by TDLS module.
6401 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306402 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306403#endif
6404
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 hdd_remove_adapter( pHddCtx, pAdapterNode );
6406 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006407 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006408
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306409#ifdef FEATURE_WLAN_TDLS
6410 mutex_unlock(&pHddCtx->tdls_lock);
6411#endif
6412
Jeff Johnson295189b2012-06-20 16:38:30 -07006413
6414 /* If there is a single session of STA/P2P client, re-enable BMPS */
6415 if ((!vos_concurrent_sessions_running()) &&
6416 ((pHddCtx->no_of_sessions[VOS_STA_MODE] >= 1) ||
6417 (pHddCtx->no_of_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
6418 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306419 if (pHddCtx->hdd_wlan_suspended)
6420 {
6421 hdd_set_pwrparams(pHddCtx);
6422 }
6423 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 }
6425
6426 return VOS_STATUS_SUCCESS;
6427 }
6428
6429 return VOS_STATUS_E_FAILURE;
6430}
6431
6432VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6433{
6434 hdd_adapter_list_node_t *pHddAdapterNode;
6435 VOS_STATUS status;
6436
6437 ENTER();
6438
6439 do
6440 {
6441 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6442 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6443 {
6444 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6445 vos_mem_free( pHddAdapterNode );
6446 }
6447 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6448
6449 EXIT();
6450
6451 return VOS_STATUS_SUCCESS;
6452}
6453
6454void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6455{
6456 v_U8_t addIE[1] = {0};
6457
6458 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6459 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6460 eANI_BOOLEAN_FALSE) )
6461 {
6462 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006463 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 }
6465
6466 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6467 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6468 eANI_BOOLEAN_FALSE) )
6469 {
6470 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006471 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006472 }
6473
6474 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6475 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6476 eANI_BOOLEAN_FALSE) )
6477 {
6478 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006479 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 }
6481}
6482
6483VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6484{
6485 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6486 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6487 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306488 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306489 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006490
6491 ENTER();
6492
6493 switch(pAdapter->device_mode)
6494 {
6495 case WLAN_HDD_INFRA_STATION:
6496 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006497 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306498 {
6499 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6500 if( hdd_connIsConnected(pstation) ||
6501 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 {
6503 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6504 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6505 pAdapter->sessionId,
6506 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6507 else
6508 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6509 pAdapter->sessionId,
6510 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6511 //success implies disconnect command got queued up successfully
6512 if(halStatus == eHAL_STATUS_SUCCESS)
6513 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306514 ret = wait_for_completion_interruptible_timeout(
6515 &pAdapter->disconnect_comp_var,
6516 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6517 if (ret <= 0)
6518 {
6519 hddLog(VOS_TRACE_LEVEL_ERROR,
6520 "%s: wait on disconnect_comp_var failed %ld",
6521 __func__, ret);
6522 }
6523 }
6524 else
6525 {
6526 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6527 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006528 }
6529 memset(&wrqu, '\0', sizeof(wrqu));
6530 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6531 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6532 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6533 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306534 else if(pstation->conn_info.connState ==
6535 eConnectionState_Disconnecting)
6536 {
6537 ret = wait_for_completion_interruptible_timeout(
6538 &pAdapter->disconnect_comp_var,
6539 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6540 if (ret <= 0)
6541 {
6542 hddLog(VOS_TRACE_LEVEL_ERROR,
6543 FL("wait on disconnect_comp_var failed %ld"), ret);
6544 }
6545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 else
6547 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306548 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6549 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306551 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6552 {
6553 while (pAdapter->is_roc_inprogress)
6554 {
6555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6556 "%s: ROC in progress for session %d!!!",
6557 __func__, pAdapter->sessionId);
6558 // waiting for ROC to expire
6559 msleep(500);
6560 /* In GO present case , if retry exceeds 3,
6561 it means something went wrong. */
6562 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6563 {
6564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6565 "%s: ROC completion is not received.!!!", __func__);
6566 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6567 pAdapter->sessionId);
6568 wait_for_completion_interruptible_timeout(
6569 &pAdapter->cancel_rem_on_chan_var,
6570 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6571 break;
6572 }
6573 }
6574 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306575#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306576#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306577 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6578#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306579 if (pAdapter->ipv6_notifier_registered)
6580 {
6581 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6582 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6583 pAdapter->ipv6_notifier_registered = false;
6584 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306585#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306586 if (pAdapter->ipv4_notifier_registered)
6587 {
6588 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6589 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6590 pAdapter->ipv4_notifier_registered = false;
6591 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306592#ifdef WLAN_OPEN_SOURCE
6593 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6594#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006595 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
6596 {
6597 INIT_COMPLETION(pAdapter->session_close_comp_var);
6598 if (eHAL_STATUS_SUCCESS ==
6599 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6600 hdd_smeCloseSessionCallback, pAdapter))
6601 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306602 unsigned long ret;
6603
Jeff Johnson295189b2012-06-20 16:38:30 -07006604 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306605 ret = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006606 &pAdapter->session_close_comp_var,
6607 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306608 if ( 0 >= ret)
6609 {
6610 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
6611 __func__, ret);
6612 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006613 }
6614 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306615 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006616 break;
6617
6618 case WLAN_HDD_SOFTAP:
6619 case WLAN_HDD_P2P_GO:
6620 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306621 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6622 while (pAdapter->is_roc_inprogress) {
6623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6624 "%s: ROC in progress for session %d!!!",
6625 __func__, pAdapter->sessionId);
6626 msleep(500);
6627 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6629 "%s: ROC completion is not received.!!!", __func__);
6630 WLANSAP_CancelRemainOnChannel(
6631 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6632 wait_for_completion_interruptible_timeout(
6633 &pAdapter->cancel_rem_on_chan_var,
6634 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6635 break;
6636 }
6637 }
6638 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006639 mutex_lock(&pHddCtx->sap_lock);
6640 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6641 {
6642 VOS_STATUS status;
6643 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6644
6645 //Stop Bss.
6646 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6647 if (VOS_IS_STATUS_SUCCESS(status))
6648 {
6649 hdd_hostapd_state_t *pHostapdState =
6650 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6651
6652 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6653
6654 if (!VOS_IS_STATUS_SUCCESS(status))
6655 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306656 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
6657 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006658 }
6659 }
6660 else
6661 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006662 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006663 }
6664 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
6665
6666 if (eHAL_STATUS_FAILURE ==
6667 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
6668 0, NULL, eANI_BOOLEAN_FALSE))
6669 {
6670 hddLog(LOGE,
6671 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006672 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006673 }
6674
6675 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
6676 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6677 eANI_BOOLEAN_FALSE) )
6678 {
6679 hddLog(LOGE,
6680 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
6681 }
6682
6683 // Reset WNI_CFG_PROBE_RSP Flags
6684 wlan_hdd_reset_prob_rspies(pAdapter);
6685 kfree(pAdapter->sessionCtx.ap.beacon);
6686 pAdapter->sessionCtx.ap.beacon = NULL;
6687 }
6688 mutex_unlock(&pHddCtx->sap_lock);
6689 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006690
Jeff Johnson295189b2012-06-20 16:38:30 -07006691 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006692#ifdef WLAN_OPEN_SOURCE
6693 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
6694#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006696
Jeff Johnson295189b2012-06-20 16:38:30 -07006697 default:
6698 break;
6699 }
6700
6701 EXIT();
6702 return VOS_STATUS_SUCCESS;
6703}
6704
6705VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
6706{
6707 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6708 VOS_STATUS status;
6709 hdd_adapter_t *pAdapter;
6710
6711 ENTER();
6712
6713 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6714
6715 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6716 {
6717 pAdapter = pAdapterNode->pAdapter;
6718 netif_tx_disable(pAdapter->dev);
6719 netif_carrier_off(pAdapter->dev);
6720
6721 hdd_stop_adapter( pHddCtx, pAdapter );
6722
6723 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6724 pAdapterNode = pNext;
6725 }
6726
6727 EXIT();
6728
6729 return VOS_STATUS_SUCCESS;
6730}
6731
Rajeev Kumarf999e582014-01-09 17:33:29 -08006732
6733#ifdef FEATURE_WLAN_BATCH_SCAN
6734/**---------------------------------------------------------------------------
6735
6736 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
6737 structures
6738
6739 \param - pAdapter Pointer to HDD adapter
6740
6741 \return - None
6742
6743 --------------------------------------------------------------------------*/
6744void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
6745{
6746 tHddBatchScanRsp *pNode;
6747 tHddBatchScanRsp *pPrev;
6748
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306749 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006750 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05306751 hddLog(VOS_TRACE_LEVEL_ERROR,
6752 "%s: Adapter context is Null", __func__);
6753 return;
6754 }
6755
6756 pNode = pAdapter->pBatchScanRsp;
6757 while (pNode)
6758 {
6759 pPrev = pNode;
6760 pNode = pNode->pNext;
6761 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08006762 }
6763
6764 pAdapter->pBatchScanRsp = NULL;
6765 pAdapter->numScanList = 0;
6766 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
6767 pAdapter->prev_batch_id = 0;
6768
6769 return;
6770}
6771#endif
6772
6773
Jeff Johnson295189b2012-06-20 16:38:30 -07006774VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
6775{
6776 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6777 VOS_STATUS status;
6778 hdd_adapter_t *pAdapter;
6779
6780 ENTER();
6781
6782 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6783
6784 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6785 {
6786 pAdapter = pAdapterNode->pAdapter;
6787 netif_tx_disable(pAdapter->dev);
6788 netif_carrier_off(pAdapter->dev);
6789
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006790 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
6791
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 hdd_deinit_tx_rx(pAdapter);
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306793 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6794 {
6795 hdd_wmm_adapter_close( pAdapter );
6796 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6797 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006798
Rajeev Kumarf999e582014-01-09 17:33:29 -08006799#ifdef FEATURE_WLAN_BATCH_SCAN
6800 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6801 {
6802 hdd_deinit_batch_scan(pAdapter);
6803 }
6804#endif
6805
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6807 pAdapterNode = pNext;
6808 }
6809
6810 EXIT();
6811
6812 return VOS_STATUS_SUCCESS;
6813}
6814
6815VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
6816{
6817 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6818 VOS_STATUS status;
6819 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306820 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07006821
6822 ENTER();
6823
6824 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6825
6826 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6827 {
6828 pAdapter = pAdapterNode->pAdapter;
6829
6830 switch(pAdapter->device_mode)
6831 {
6832 case WLAN_HDD_INFRA_STATION:
6833 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006834 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306835
6836 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
6837
Jeff Johnson295189b2012-06-20 16:38:30 -07006838 hdd_init_station_mode(pAdapter);
6839 /* Open the gates for HDD to receive Wext commands */
6840 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006841 pHddCtx->scan_info.mScanPending = FALSE;
6842 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006843
6844 //Trigger the initial scan
6845 hdd_wlan_initial_scan(pAdapter);
6846
6847 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306848 if (eConnectionState_Associated == connState ||
6849 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 {
6851 union iwreq_data wrqu;
6852 memset(&wrqu, '\0', sizeof(wrqu));
6853 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6854 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6855 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07006856 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006857
Jeff Johnson295189b2012-06-20 16:38:30 -07006858 /* indicate disconnected event to nl80211 */
6859 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
6860 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006861 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05306862 else if (eConnectionState_Connecting == connState)
6863 {
6864 /*
6865 * Indicate connect failure to supplicant if we were in the
6866 * process of connecting
6867 */
6868 cfg80211_connect_result(pAdapter->dev, NULL,
6869 NULL, 0, NULL, 0,
6870 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
6871 GFP_KERNEL);
6872 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 break;
6874
6875 case WLAN_HDD_SOFTAP:
6876 /* softAP can handle SSR */
6877 break;
6878
6879 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006880 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07006882 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 break;
6884
6885 case WLAN_HDD_MONITOR:
6886 /* monitor interface start */
6887 break;
6888 default:
6889 break;
6890 }
6891
6892 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6893 pAdapterNode = pNext;
6894 }
6895
6896 EXIT();
6897
6898 return VOS_STATUS_SUCCESS;
6899}
6900
6901VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
6902{
6903 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6904 hdd_adapter_t *pAdapter;
6905 VOS_STATUS status;
6906 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306907 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006908
6909 ENTER();
6910
6911 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6912
6913 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6914 {
6915 pAdapter = pAdapterNode->pAdapter;
6916
6917 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6918 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6919 {
6920 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6921 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6922
Abhishek Singhf4669da2014-05-26 15:07:49 +05306923 hddLog(VOS_TRACE_LEVEL_INFO,
6924 "%s: Set HDD connState to eConnectionState_NotConnected",
6925 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006926 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6927 init_completion(&pAdapter->disconnect_comp_var);
6928 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
6929 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6930
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306931 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 &pAdapter->disconnect_comp_var,
6933 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306934 if (0 >= ret)
6935 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
6936 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07006937
6938 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
6939 pHddCtx->isAmpAllowed = VOS_FALSE;
6940 sme_RoamConnect(pHddCtx->hHal,
6941 pAdapter->sessionId, &(pWextState->roamProfile),
6942 &roamId);
6943 }
6944
6945 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6946 pAdapterNode = pNext;
6947 }
6948
6949 EXIT();
6950
6951 return VOS_STATUS_SUCCESS;
6952}
6953
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07006954void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
6955{
6956 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6957 VOS_STATUS status;
6958 hdd_adapter_t *pAdapter;
6959 hdd_station_ctx_t *pHddStaCtx;
6960 hdd_ap_ctx_t *pHddApCtx;
6961 hdd_hostapd_state_t * pHostapdState;
6962 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
6963 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
6964 const char *p2pMode = "DEV";
6965 const char *ccMode = "Standalone";
6966 int n;
6967
6968 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6969 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
6970 {
6971 pAdapter = pAdapterNode->pAdapter;
6972 switch (pAdapter->device_mode) {
6973 case WLAN_HDD_INFRA_STATION:
6974 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6975 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6976 staChannel = pHddStaCtx->conn_info.operationChannel;
6977 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
6978 }
6979 break;
6980 case WLAN_HDD_P2P_CLIENT:
6981 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6982 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
6983 p2pChannel = pHddStaCtx->conn_info.operationChannel;
6984 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
6985 p2pMode = "CLI";
6986 }
6987 break;
6988 case WLAN_HDD_P2P_GO:
6989 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6990 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6991 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
6992 p2pChannel = pHddApCtx->operatingChannel;
6993 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
6994 }
6995 p2pMode = "GO";
6996 break;
6997 case WLAN_HDD_SOFTAP:
6998 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
6999 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7000 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7001 apChannel = pHddApCtx->operatingChannel;
7002 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7003 }
7004 break;
7005 default:
7006 break;
7007 }
7008 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7009 pAdapterNode = pNext;
7010 }
7011 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7012 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7013 }
7014 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7015 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7016 if (p2pChannel > 0) {
7017 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7018 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7019 }
7020 if (apChannel > 0) {
7021 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7022 apChannel, MAC_ADDR_ARRAY(apBssid));
7023 }
7024
7025 if (p2pChannel > 0 && apChannel > 0) {
7026 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7027 }
7028}
7029
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007030bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007031{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007032 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007033}
7034
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007035/* Once SSR is disabled then it cannot be set. */
7036void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007037{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007038 if (HDD_SSR_DISABLED == isSsrRequired)
7039 return;
7040
Jeff Johnson295189b2012-06-20 16:38:30 -07007041 isSsrRequired = value;
7042}
7043
7044VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7045 hdd_adapter_list_node_t** ppAdapterNode)
7046{
7047 VOS_STATUS status;
7048 spin_lock(&pHddCtx->hddAdapters.lock);
7049 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7050 (hdd_list_node_t**) ppAdapterNode );
7051 spin_unlock(&pHddCtx->hddAdapters.lock);
7052 return status;
7053}
7054
7055VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7056 hdd_adapter_list_node_t* pAdapterNode,
7057 hdd_adapter_list_node_t** pNextAdapterNode)
7058{
7059 VOS_STATUS status;
7060 spin_lock(&pHddCtx->hddAdapters.lock);
7061 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7062 (hdd_list_node_t*) pAdapterNode,
7063 (hdd_list_node_t**)pNextAdapterNode );
7064
7065 spin_unlock(&pHddCtx->hddAdapters.lock);
7066 return status;
7067}
7068
7069VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7070 hdd_adapter_list_node_t* pAdapterNode)
7071{
7072 VOS_STATUS status;
7073 spin_lock(&pHddCtx->hddAdapters.lock);
7074 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7075 &pAdapterNode->node );
7076 spin_unlock(&pHddCtx->hddAdapters.lock);
7077 return status;
7078}
7079
7080VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7081 hdd_adapter_list_node_t** ppAdapterNode)
7082{
7083 VOS_STATUS status;
7084 spin_lock(&pHddCtx->hddAdapters.lock);
7085 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7086 (hdd_list_node_t**) ppAdapterNode );
7087 spin_unlock(&pHddCtx->hddAdapters.lock);
7088 return status;
7089}
7090
7091VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7092 hdd_adapter_list_node_t* pAdapterNode)
7093{
7094 VOS_STATUS status;
7095 spin_lock(&pHddCtx->hddAdapters.lock);
7096 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7097 (hdd_list_node_t*) pAdapterNode );
7098 spin_unlock(&pHddCtx->hddAdapters.lock);
7099 return status;
7100}
7101
7102VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7103 hdd_adapter_list_node_t* pAdapterNode)
7104{
7105 VOS_STATUS status;
7106 spin_lock(&pHddCtx->hddAdapters.lock);
7107 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7108 (hdd_list_node_t*) pAdapterNode );
7109 spin_unlock(&pHddCtx->hddAdapters.lock);
7110 return status;
7111}
7112
7113hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7114 tSirMacAddr macAddr )
7115{
7116 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7117 hdd_adapter_t *pAdapter;
7118 VOS_STATUS status;
7119
7120 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7121
7122 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7123 {
7124 pAdapter = pAdapterNode->pAdapter;
7125
7126 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7127 macAddr, sizeof(tSirMacAddr) ) )
7128 {
7129 return pAdapter;
7130 }
7131 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7132 pAdapterNode = pNext;
7133 }
7134
7135 return NULL;
7136
7137}
7138
7139hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7140{
7141 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7142 hdd_adapter_t *pAdapter;
7143 VOS_STATUS status;
7144
7145 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7146
7147 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7148 {
7149 pAdapter = pAdapterNode->pAdapter;
7150
7151 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7152 IFNAMSIZ ) )
7153 {
7154 return pAdapter;
7155 }
7156 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7157 pAdapterNode = pNext;
7158 }
7159
7160 return NULL;
7161
7162}
7163
7164hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7165{
7166 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7167 hdd_adapter_t *pAdapter;
7168 VOS_STATUS status;
7169
7170 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7171
7172 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7173 {
7174 pAdapter = pAdapterNode->pAdapter;
7175
7176 if( pAdapter && (mode == pAdapter->device_mode) )
7177 {
7178 return pAdapter;
7179 }
7180 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7181 pAdapterNode = pNext;
7182 }
7183
7184 return NULL;
7185
7186}
7187
7188//Remove this function later
7189hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7190{
7191 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7192 hdd_adapter_t *pAdapter;
7193 VOS_STATUS status;
7194
7195 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7196
7197 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7198 {
7199 pAdapter = pAdapterNode->pAdapter;
7200
7201 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7202 {
7203 return pAdapter;
7204 }
7205
7206 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7207 pAdapterNode = pNext;
7208 }
7209
7210 return NULL;
7211
7212}
7213
Jeff Johnson295189b2012-06-20 16:38:30 -07007214/**---------------------------------------------------------------------------
7215
7216 \brief hdd_set_monitor_tx_adapter() -
7217
7218 This API initializes the adapter to be used while transmitting on monitor
7219 adapter.
7220
7221 \param - pHddCtx - Pointer to the HDD context.
7222 pAdapter - Adapter that will used for TX. This can be NULL.
7223 \return - None.
7224 --------------------------------------------------------------------------*/
7225void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7226{
7227 hdd_adapter_t *pMonAdapter;
7228
7229 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7230
7231 if( NULL != pMonAdapter )
7232 {
7233 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7234 }
7235}
Jeff Johnson295189b2012-06-20 16:38:30 -07007236/**---------------------------------------------------------------------------
7237
7238 \brief hdd_select_queue() -
7239
7240 This API returns the operating channel of the requested device mode
7241
7242 \param - pHddCtx - Pointer to the HDD context.
7243 - mode - Device mode for which operating channel is required
7244 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7245 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7246 \return - channel number. "0" id the requested device is not found OR it is not connected.
7247 --------------------------------------------------------------------------*/
7248v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7249{
7250 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7251 VOS_STATUS status;
7252 hdd_adapter_t *pAdapter;
7253 v_U8_t operatingChannel = 0;
7254
7255 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7256
7257 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7258 {
7259 pAdapter = pAdapterNode->pAdapter;
7260
7261 if( mode == pAdapter->device_mode )
7262 {
7263 switch(pAdapter->device_mode)
7264 {
7265 case WLAN_HDD_INFRA_STATION:
7266 case WLAN_HDD_P2P_CLIENT:
7267 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7268 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7269 break;
7270 case WLAN_HDD_SOFTAP:
7271 case WLAN_HDD_P2P_GO:
7272 /*softap connection info */
7273 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7274 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7275 break;
7276 default:
7277 break;
7278 }
7279
7280 break; //Found the device of interest. break the loop
7281 }
7282
7283 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7284 pAdapterNode = pNext;
7285 }
7286 return operatingChannel;
7287}
7288
7289#ifdef WLAN_FEATURE_PACKET_FILTERING
7290/**---------------------------------------------------------------------------
7291
7292 \brief hdd_set_multicast_list() -
7293
7294 This used to set the multicast address list.
7295
7296 \param - dev - Pointer to the WLAN device.
7297 - skb - Pointer to OS packet (sk_buff).
7298 \return - success/fail
7299
7300 --------------------------------------------------------------------------*/
7301static void hdd_set_multicast_list(struct net_device *dev)
7302{
7303 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007304 int mc_count;
7305 int i = 0;
7306 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307307
7308 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007309 {
7310 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307311 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007312 return;
7313 }
7314
7315 if (dev->flags & IFF_ALLMULTI)
7316 {
7317 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007318 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307319 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007320 }
7321 else
7322 {
7323 mc_count = netdev_mc_count(dev);
7324 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007325 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7327 {
7328 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007329 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307330 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 return;
7332 }
7333
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307334 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007335
7336 netdev_for_each_mc_addr(ha, dev) {
7337 if (i == mc_count)
7338 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307339 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7340 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007341 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007342 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307343 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 i++;
7345 }
7346 }
7347 return;
7348}
7349#endif
7350
7351/**---------------------------------------------------------------------------
7352
7353 \brief hdd_select_queue() -
7354
7355 This function is registered with the Linux OS for network
7356 core to decide which queue to use first.
7357
7358 \param - dev - Pointer to the WLAN device.
7359 - skb - Pointer to OS packet (sk_buff).
7360 \return - ac, Queue Index/access category corresponding to UP in IP header
7361
7362 --------------------------------------------------------------------------*/
7363v_U16_t hdd_select_queue(struct net_device *dev,
7364 struct sk_buff *skb)
7365{
7366 return hdd_wmm_select_queue(dev, skb);
7367}
7368
7369
7370/**---------------------------------------------------------------------------
7371
7372 \brief hdd_wlan_initial_scan() -
7373
7374 This function triggers the initial scan
7375
7376 \param - pAdapter - Pointer to the HDD adapter.
7377
7378 --------------------------------------------------------------------------*/
7379void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7380{
7381 tCsrScanRequest scanReq;
7382 tCsrChannelInfo channelInfo;
7383 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007384 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7386
7387 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7388 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7389 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7390
7391 if(sme_Is11dSupported(pHddCtx->hHal))
7392 {
7393 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7394 if ( HAL_STATUS_SUCCESS( halStatus ) )
7395 {
7396 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7397 if( !scanReq.ChannelInfo.ChannelList )
7398 {
7399 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7400 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007401 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007402 return;
7403 }
7404 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7405 channelInfo.numOfChannels);
7406 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7407 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007408 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007409 }
7410
7411 scanReq.scanType = eSIR_PASSIVE_SCAN;
7412 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7413 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7414 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7415 }
7416 else
7417 {
7418 scanReq.scanType = eSIR_ACTIVE_SCAN;
7419 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7420 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7421 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7422 }
7423
7424 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7425 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7426 {
7427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7428 __func__, halStatus );
7429 }
7430
7431 if(sme_Is11dSupported(pHddCtx->hHal))
7432 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7433}
7434
Jeff Johnson295189b2012-06-20 16:38:30 -07007435/**---------------------------------------------------------------------------
7436
7437 \brief hdd_full_power_callback() - HDD full power callback function
7438
7439 This is the function invoked by SME to inform the result of a full power
7440 request issued by HDD
7441
7442 \param - callbackcontext - Pointer to cookie
7443 \param - status - result of request
7444
7445 \return - None
7446
7447 --------------------------------------------------------------------------*/
7448static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7449{
Jeff Johnson72a40512013-12-19 10:14:15 -08007450 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007451
7452 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307453 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007454
7455 if (NULL == callbackContext)
7456 {
7457 hddLog(VOS_TRACE_LEVEL_ERROR,
7458 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007459 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007460 return;
7461 }
7462
Jeff Johnson72a40512013-12-19 10:14:15 -08007463 /* there is a race condition that exists between this callback
7464 function and the caller since the caller could time out either
7465 before or while this code is executing. we use a spinlock to
7466 serialize these actions */
7467 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007468
7469 if (POWER_CONTEXT_MAGIC != pContext->magic)
7470 {
7471 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007472 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007473 hddLog(VOS_TRACE_LEVEL_WARN,
7474 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007475 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007476 return;
7477 }
7478
Jeff Johnson72a40512013-12-19 10:14:15 -08007479 /* context is valid so caller is still waiting */
7480
7481 /* paranoia: invalidate the magic */
7482 pContext->magic = 0;
7483
7484 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007486
7487 /* serialization is complete */
7488 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007489}
7490
7491/**---------------------------------------------------------------------------
7492
7493 \brief hdd_wlan_exit() - HDD WLAN exit function
7494
7495 This is the driver exit point (invoked during rmmod)
7496
7497 \param - pHddCtx - Pointer to the HDD Context
7498
7499 \return - None
7500
7501 --------------------------------------------------------------------------*/
7502void hdd_wlan_exit(hdd_context_t *pHddCtx)
7503{
7504 eHalStatus halStatus;
7505 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7506 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307507 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007508 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007509 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007510 long lrc;
7511
7512 ENTER();
7513
Jeff Johnson88ba7742013-02-27 14:36:02 -08007514 if (VOS_FTM_MODE != hdd_get_conparam())
7515 {
7516 // Unloading, restart logic is no more required.
7517 wlan_hdd_restart_deinit(pHddCtx);
7518 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007519
Jeff Johnson295189b2012-06-20 16:38:30 -07007520 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007521 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007522 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007523 {
7524 hdd_adapter_t* pAdapter = hdd_get_adapter(pHddCtx,
7525 WLAN_HDD_INFRA_STATION);
7526 if (pAdapter == NULL)
7527 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
7528
7529 if (pAdapter != NULL)
7530 {
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05307531 wlan_hdd_cfg80211_deregister_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007532 hdd_UnregisterWext(pAdapter->dev);
7533 }
7534 }
7535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007536
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 if (VOS_FTM_MODE == hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -08007538 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307539 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007540 wlan_hdd_ftm_close(pHddCtx);
7541 goto free_hdd_ctx;
7542 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007543 //Stop the Interface TX queue.
7544 //netif_tx_disable(pWlanDev);
7545 //netif_carrier_off(pWlanDev);
7546
Jeff Johnson295189b2012-06-20 16:38:30 -07007547 if (VOS_STA_SAP_MODE == hdd_get_conparam())
7548 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307549 hddLog(VOS_TRACE_LEVEL_INFO,"%s: SAP MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007550 pAdapter = hdd_get_adapter(pHddCtx,
7551 WLAN_HDD_SOFTAP);
7552 }
7553 else
7554 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007555 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07007556 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307557 hddLog(VOS_TRACE_LEVEL_INFO,"%s: STA MODE",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007558 pAdapter = hdd_get_adapter(pHddCtx,
7559 WLAN_HDD_INFRA_STATION);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007560 if (pAdapter == NULL)
7561 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_IBSS);
Jeff Johnson295189b2012-06-20 16:38:30 -07007562 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307564
7565 if(NULL == pAdapter)
7566 {
7567 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: pAdapter is NULL",__func__);
7568 goto free_hdd_ctx;
7569 }
7570
Jeff Johnson295189b2012-06-20 16:38:30 -07007571 /* DeRegister with platform driver as client for Suspend/Resume */
7572 vosStatus = hddDeregisterPmOps(pHddCtx);
7573 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7574 {
7575 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7576 VOS_ASSERT(0);
7577 }
7578
7579 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7580 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7581 {
7582 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7583 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007584
7585 // Cancel any outstanding scan requests. We are about to close all
7586 // of our adapters, but an adapter structure is what SME passes back
7587 // to our callback function. Hence if there are any outstanding scan
7588 // requests then there is a race condition between when the adapter
7589 // is closed and when the callback is invoked. We try to resolve that
7590 // race condition here by canceling any outstanding scans before we
7591 // close the adapters.
7592 // Note that the scans may be cancelled in an asynchronous manner, so
7593 // ideally there needs to be some kind of synchronization. Rather than
7594 // introduce a new synchronization here, we will utilize the fact that
7595 // we are about to Request Full Power, and since that is synchronized,
7596 // the expectation is that by the time Request Full Power has completed,
7597 // all scans will be cancelled.
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007598 if (NULL != pAdapter)
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307599 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, eCSR_SCAN_ABORT_DEFAULT);
Praveen Kumar Sirisilla47ce6ea2013-09-24 15:08:08 -07007600 else
7601 hddLog(VOS_TRACE_LEVEL_ERROR,
7602 "%s: pAdapter is NULL, cannot Abort scan", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007603
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007604 //Stop the traffic monitor timer
7605 if ( VOS_TIMER_STATE_RUNNING ==
7606 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7607 {
7608 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7609 }
7610
7611 // Destroy the traffic monitor timer
7612 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7613 &pHddCtx->tx_rx_trafficTmr)))
7614 {
7615 hddLog(VOS_TRACE_LEVEL_ERROR,
7616 "%s: Cannot deallocate Traffic monitor timer", __func__);
7617 }
7618
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 //Disable IMPS/BMPS as we do not want the device to enter any power
7620 //save mode during shutdown
7621 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7622 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7623 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7624
7625 //Ensure that device is in full power as we will touch H/W during vos_Stop
7626 init_completion(&powerContext.completion);
7627 powerContext.magic = POWER_CONTEXT_MAGIC;
7628
7629 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7630 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7631
7632 if (eHAL_STATUS_SUCCESS != halStatus)
7633 {
7634 if (eHAL_STATUS_PMC_PENDING == halStatus)
7635 {
7636 /* request was sent -- wait for the response */
7637 lrc = wait_for_completion_interruptible_timeout(
7638 &powerContext.completion,
7639 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 if (lrc <= 0)
7641 {
7642 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007643 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007644 }
7645 }
7646 else
7647 {
7648 hddLog(VOS_TRACE_LEVEL_ERROR,
7649 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007650 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 /* continue -- need to clean up as much as possible */
7652 }
7653 }
7654
Jeff Johnson72a40512013-12-19 10:14:15 -08007655 /* either we never sent a request, we sent a request and received a
7656 response or we sent a request and timed out. if we never sent a
7657 request or if we sent a request and got a response, we want to
7658 clear the magic out of paranoia. if we timed out there is a
7659 race condition such that the callback function could be
7660 executing at the same time we are. of primary concern is if the
7661 callback function had already verified the "magic" but had not
7662 yet set the completion variable when a timeout occurred. we
7663 serialize these activities by invalidating the magic while
7664 holding a shared spinlock which will cause us to block if the
7665 callback is currently executing */
7666 spin_lock(&hdd_context_lock);
7667 powerContext.magic = 0;
7668 spin_unlock(&hdd_context_lock);
7669
Yue Ma0d4891e2013-08-06 17:01:45 -07007670 hdd_debugfs_exit(pHddCtx);
7671
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 // Unregister the Net Device Notifier
7673 unregister_netdevice_notifier(&hdd_netdev_notifier);
7674
Jeff Johnson295189b2012-06-20 16:38:30 -07007675 hdd_stop_all_adapters( pHddCtx );
7676
Jeff Johnson295189b2012-06-20 16:38:30 -07007677#ifdef WLAN_BTAMP_FEATURE
7678 vosStatus = WLANBAP_Stop(pVosContext);
7679 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7680 {
7681 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7682 "%s: Failed to stop BAP",__func__);
7683 }
7684#endif //WLAN_BTAMP_FEATURE
7685
7686 //Stop all the modules
7687 vosStatus = vos_stop( pVosContext );
7688 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7689 {
7690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7691 "%s: Failed to stop VOSS",__func__);
7692 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7693 }
7694
Jeff Johnson295189b2012-06-20 16:38:30 -07007695 //Assert Deep sleep signal now to put Libra HW in lowest power state
7696 vosStatus = vos_chipAssertDeepSleep( NULL, NULL, NULL );
7697 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7698
7699 //Vote off any PMIC voltage supplies
7700 vos_chipPowerDown(NULL, NULL, NULL);
7701
7702 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
7703
Leo Chang59cdc7e2013-07-10 10:08:21 -07007704
Jeff Johnson295189b2012-06-20 16:38:30 -07007705 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07007706 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007707
7708 //Close the scheduler before calling vos_close to make sure no thread is
7709 // scheduled after the each module close is called i.e after all the data
7710 // structures are freed.
7711 vosStatus = vos_sched_close( pVosContext );
7712 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
7713 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
7714 "%s: Failed to close VOSS Scheduler",__func__);
7715 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7716 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007717#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07007718#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
7719 /* Destroy the wake lock */
7720 wake_lock_destroy(&pHddCtx->rx_wake_lock);
7721#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08007722 /* Destroy the wake lock */
7723 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007724#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007725
Mihir Shete7a24b5f2013-12-21 12:18:31 +05307726#ifdef CONFIG_ENABLE_LINUX_REG
7727 vosStatus = vos_nv_close();
7728 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
7729 {
7730 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
7731 "%s: Failed to close NV", __func__);
7732 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
7733 }
7734#endif
7735
Jeff Johnson295189b2012-06-20 16:38:30 -07007736 //Close VOSS
7737 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
7738 vos_close(pVosContext);
7739
Jeff Johnson295189b2012-06-20 16:38:30 -07007740 //Close Watchdog
7741 if(pHddCtx->cfg_ini->fIsLogpEnabled)
7742 vos_watchdog_close(pVosContext);
7743
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307744 //Clean up HDD Nlink Service
7745 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Leo Chang59cdc7e2013-07-10 10:08:21 -07007746#ifdef WLAN_KD_READY_NOTIFIER
7747 nl_srv_exit(pHddCtx->ptt_pid);
7748#else
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307749 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07007750#endif /* WLAN_KD_READY_NOTIFIER */
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05307751
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307752#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05307753 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05307754 {
7755 wlan_logging_sock_deactivate_svc();
7756 }
7757#endif
7758
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 /* Cancel the vote for XO Core ON.
7760 * This is done here to ensure there is no race condition since MC, TX and WD threads have
7761 * exited at this point
7762 */
7763 hddLog(VOS_TRACE_LEVEL_WARN, "In module exit: Cancel the vote for XO Core ON"
Arif Hussain6d2a3322013-11-17 19:50:10 -08007764 " when WLAN is turned OFF");
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
7766 {
7767 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel the vote for XO Core ON."
7768 " Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08007769 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 }
7771
7772 hdd_close_all_adapters( pHddCtx );
7773
Jeff Johnson295189b2012-06-20 16:38:30 -07007774 /* free the power on lock from platform driver */
7775 if (free_riva_power_on_lock("wlan"))
7776 {
7777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
7778 __func__);
7779 }
7780
Jeff Johnson88ba7742013-02-27 14:36:02 -08007781free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05307782
7783 //Free up dynamically allocated members inside HDD Adapter
7784 if (pHddCtx->cfg_ini)
7785 {
7786 kfree(pHddCtx->cfg_ini);
7787 pHddCtx->cfg_ini= NULL;
7788 }
7789
Leo Changf04ddad2013-09-18 13:46:38 -07007790 /* FTM mode, WIPHY did not registered
7791 If un-register here, system crash will happen */
7792 if (VOS_FTM_MODE != hdd_get_conparam())
7793 {
7794 wiphy_unregister(wiphy) ;
7795 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07007797 if (hdd_is_ssr_required())
7798 {
7799 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07007800 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 msleep(5000);
7802 }
7803 hdd_set_ssr_required (VOS_FALSE);
7804}
7805
7806
7807/**---------------------------------------------------------------------------
7808
7809 \brief hdd_update_config_from_nv() - Function to update the contents of
7810 the running configuration with parameters taken from NV storage
7811
7812 \param - pHddCtx - Pointer to the HDD global context
7813
7814 \return - VOS_STATUS_SUCCESS if successful
7815
7816 --------------------------------------------------------------------------*/
7817static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
7818{
Jeff Johnson295189b2012-06-20 16:38:30 -07007819 v_BOOL_t itemIsValid = VOS_FALSE;
7820 VOS_STATUS status;
7821 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
7822 v_U8_t macLoop;
7823
7824 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
7825 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
7826 if(status != VOS_STATUS_SUCCESS)
7827 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007828 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007829 return VOS_STATUS_E_FAILURE;
7830 }
7831
7832 if (itemIsValid == VOS_TRUE)
7833 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007834 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
7836 VOS_MAX_CONCURRENCY_PERSONA);
7837 if(status != VOS_STATUS_SUCCESS)
7838 {
7839 /* Get MAC from NV fail, not update CFG info
7840 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08007841 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 return VOS_STATUS_E_FAILURE;
7843 }
7844
7845 /* If first MAC is not valid, treat all others are not valid
7846 * Then all MACs will be got from ini file */
7847 if(vos_is_macaddr_zero(&macFromNV[0]))
7848 {
7849 /* MAC address in NV file is not configured yet */
7850 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
7851 return VOS_STATUS_E_INVAL;
7852 }
7853
7854 /* Get MAC address from NV, update CFG info */
7855 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
7856 {
7857 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
7858 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307859 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07007860 /* This MAC is not valid, skip it
7861 * This MAC will be got from ini file */
7862 }
7863 else
7864 {
7865 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
7866 (v_U8_t *)&macFromNV[macLoop].bytes[0],
7867 VOS_MAC_ADDR_SIZE);
7868 }
7869 }
7870 }
7871 else
7872 {
7873 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
7874 return VOS_STATUS_E_FAILURE;
7875 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007876
Jeff Johnson295189b2012-06-20 16:38:30 -07007877
7878 return VOS_STATUS_SUCCESS;
7879}
7880
7881/**---------------------------------------------------------------------------
7882
7883 \brief hdd_post_voss_start_config() - HDD post voss start config helper
7884
7885 \param - pAdapter - Pointer to the HDD
7886
7887 \return - None
7888
7889 --------------------------------------------------------------------------*/
7890VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
7891{
7892 eHalStatus halStatus;
7893 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307894 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07007895
Jeff Johnson295189b2012-06-20 16:38:30 -07007896
7897 // Send ready indication to the HDD. This will kick off the MAC
7898 // into a 'running' state and should kick off an initial scan.
7899 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
7900 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7901 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307902 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07007903 "code %08d [x%08x]",__func__, halStatus, halStatus );
7904 return VOS_STATUS_E_FAILURE;
7905 }
7906
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307907 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07007908 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
7909 // And RIVA will crash
7910 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
7911 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307912 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
7913 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
7914
7915
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 return VOS_STATUS_SUCCESS;
7917}
7918
Jeff Johnson295189b2012-06-20 16:38:30 -07007919/* wake lock APIs for HDD */
7920void hdd_prevent_suspend(void)
7921{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007922#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007924#else
7925 wcnss_prevent_suspend();
7926#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007927}
7928
7929void hdd_allow_suspend(void)
7930{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007931#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07007932 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07007933#else
7934 wcnss_allow_suspend();
7935#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007936}
7937
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05307938void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007939{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08007940#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07007941 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07007942#else
7943 /* Do nothing as there is no API in wcnss for timeout*/
7944#endif
7945}
7946
Jeff Johnson295189b2012-06-20 16:38:30 -07007947/**---------------------------------------------------------------------------
7948
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007949 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
7950 information between Host and Riva
7951
7952 This function gets reported version of FW
7953 It also finds the version of Riva headers used to compile the host
7954 It compares the above two and prints a warning if they are different
7955 It gets the SW and HW version string
7956 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
7957 indicating the features they support through a bitmap
7958
7959 \param - pHddCtx - Pointer to HDD context
7960
7961 \return - void
7962
7963 --------------------------------------------------------------------------*/
7964
7965void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
7966{
7967
7968 tSirVersionType versionCompiled;
7969 tSirVersionType versionReported;
7970 tSirVersionString versionString;
7971 tANI_U8 fwFeatCapsMsgSupported = 0;
7972 VOS_STATUS vstatus;
7973
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007974 memset(&versionCompiled, 0, sizeof(versionCompiled));
7975 memset(&versionReported, 0, sizeof(versionReported));
7976
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007977 /* retrieve and display WCNSS version information */
7978 do {
7979
7980 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
7981 &versionCompiled);
7982 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7983 {
7984 hddLog(VOS_TRACE_LEVEL_FATAL,
7985 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007986 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007987 break;
7988 }
7989
7990 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
7991 &versionReported);
7992 if (!VOS_IS_STATUS_SUCCESS(vstatus))
7993 {
7994 hddLog(VOS_TRACE_LEVEL_FATAL,
7995 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007996 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07007997 break;
7998 }
7999
8000 if ((versionCompiled.major != versionReported.major) ||
8001 (versionCompiled.minor != versionReported.minor) ||
8002 (versionCompiled.version != versionReported.version) ||
8003 (versionCompiled.revision != versionReported.revision))
8004 {
8005 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8006 "Host expected %u.%u.%u.%u\n",
8007 WLAN_MODULE_NAME,
8008 (int)versionReported.major,
8009 (int)versionReported.minor,
8010 (int)versionReported.version,
8011 (int)versionReported.revision,
8012 (int)versionCompiled.major,
8013 (int)versionCompiled.minor,
8014 (int)versionCompiled.version,
8015 (int)versionCompiled.revision);
8016 }
8017 else
8018 {
8019 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8020 WLAN_MODULE_NAME,
8021 (int)versionReported.major,
8022 (int)versionReported.minor,
8023 (int)versionReported.version,
8024 (int)versionReported.revision);
8025 }
8026
8027 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8028 versionString,
8029 sizeof(versionString));
8030 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8031 {
8032 hddLog(VOS_TRACE_LEVEL_FATAL,
8033 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008034 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008035 break;
8036 }
8037
8038 pr_info("%s: WCNSS software version %s\n",
8039 WLAN_MODULE_NAME, versionString);
8040
8041 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8042 versionString,
8043 sizeof(versionString));
8044 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8045 {
8046 hddLog(VOS_TRACE_LEVEL_FATAL,
8047 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008048 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008049 break;
8050 }
8051
8052 pr_info("%s: WCNSS hardware version %s\n",
8053 WLAN_MODULE_NAME, versionString);
8054
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008055 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8056 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008057 send the message only if it the riva is 1.1
8058 minor numbers for different riva branches:
8059 0 -> (1.0)Mainline Build
8060 1 -> (1.1)Mainline Build
8061 2->(1.04) Stability Build
8062 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008063 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008064 ((versionReported.minor>=1) && (versionReported.version>=1)))
8065 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8066 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008067
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008068 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008069 {
8070#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8071 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8072 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8073#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008074 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8075 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8076 {
8077 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8078 }
8079
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008080 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008081 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008082
8083 } while (0);
8084
8085}
8086
8087/**---------------------------------------------------------------------------
8088
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308089 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8090
8091 \param - pHddCtx - Pointer to the hdd context
8092
8093 \return - true if hardware supports 5GHz
8094
8095 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308096boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308097{
8098 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8099 * then hardware support 5Ghz.
8100 */
8101 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8102 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308104 return true;
8105 }
8106 else
8107 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308109 __func__);
8110 return false;
8111 }
8112}
8113
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308114/**---------------------------------------------------------------------------
8115
8116 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8117 generate function
8118
8119 This is generate the random mac address for WLAN interface
8120
8121 \param - pHddCtx - Pointer to HDD context
8122 idx - Start interface index to get auto
8123 generated mac addr.
8124 mac_addr - Mac address
8125
8126 \return - 0 for success, < 0 for failure
8127
8128 --------------------------------------------------------------------------*/
8129
8130static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8131 int idx, v_MACADDR_t mac_addr)
8132{
8133 int i;
8134 unsigned int serialno;
8135 serialno = wcnss_get_serial_number();
8136
8137 if (0 != serialno)
8138 {
8139 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8140 bytes of the serial number that can be used to generate
8141 the other 3 bytes of the MAC address. Mask off all but
8142 the lower 3 bytes (this will also make sure we don't
8143 overflow in the next step) */
8144 serialno &= 0x00FFFFFF;
8145
8146 /* we need a unique address for each session */
8147 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8148
8149 /* autogen other Mac addresses */
8150 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8151 {
8152 /* start with the entire default address */
8153 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8154 /* then replace the lower 3 bytes */
8155 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8156 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8157 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8158
8159 serialno++;
8160 hddLog(VOS_TRACE_LEVEL_ERROR,
8161 "%s: Derived Mac Addr: "
8162 MAC_ADDRESS_STR, __func__,
8163 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8164 }
8165
8166 }
8167 else
8168 {
8169 hddLog(LOGE, FL("Failed to Get Serial NO"));
8170 return -1;
8171 }
8172 return 0;
8173}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308174
8175/**---------------------------------------------------------------------------
8176
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308177 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8178 completed to flush out the scan results
8179
8180 11d scan is done during driver load and is a passive scan on all
8181 channels supported by the device, 11d scans may find some APs on
8182 frequencies which are forbidden to be used in the regulatory domain
8183 the device is operating in. If these APs are notified to the supplicant
8184 it may try to connect to these APs, thus flush out all the scan results
8185 which are present in SME after 11d scan is done.
8186
8187 \return - eHalStatus
8188
8189 --------------------------------------------------------------------------*/
8190static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8191 tANI_U32 scanId, eCsrScanStatus status)
8192{
8193 ENTER();
8194
8195 sme_ScanFlushResult(halHandle, 0);
8196
8197 EXIT();
8198
8199 return eHAL_STATUS_SUCCESS;
8200}
8201
8202/**---------------------------------------------------------------------------
8203
Jeff Johnson295189b2012-06-20 16:38:30 -07008204 \brief hdd_wlan_startup() - HDD init function
8205
8206 This is the driver startup code executed once a WLAN device has been detected
8207
8208 \param - dev - Pointer to the underlying device
8209
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008210 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008211
8212 --------------------------------------------------------------------------*/
8213
8214int hdd_wlan_startup(struct device *dev )
8215{
8216 VOS_STATUS status;
8217 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008218 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 hdd_context_t *pHddCtx = NULL;
8220 v_CONTEXT_t pVosContext= NULL;
8221#ifdef WLAN_BTAMP_FEATURE
8222 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8223 WLANBAP_ConfigType btAmpConfig;
8224 hdd_config_t *pConfig;
8225#endif
8226 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008227 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308228 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008229
8230 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 /*
8232 * cfg80211: wiphy allocation
8233 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308234 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008235
8236 if(wiphy == NULL)
8237 {
8238 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008239 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008240 }
8241
8242 pHddCtx = wiphy_priv(wiphy);
8243
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 //Initialize the adapter context to zeros.
8245 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8246
Jeff Johnson295189b2012-06-20 16:38:30 -07008247 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008248 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308249 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008250
8251 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8252
8253 /*Get vos context here bcoz vos_open requires it*/
8254 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8255
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008256 if(pVosContext == NULL)
8257 {
8258 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8259 goto err_free_hdd_context;
8260 }
8261
Jeff Johnson295189b2012-06-20 16:38:30 -07008262 //Save the Global VOSS context in adapter context for future.
8263 pHddCtx->pvosContext = pVosContext;
8264
8265 //Save the adapter context in global context for future.
8266 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8267
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 pHddCtx->parent_dev = dev;
8269
8270 init_completion(&pHddCtx->full_pwr_comp_var);
8271 init_completion(&pHddCtx->standby_comp_var);
8272 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008273 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008274 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308275 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308276 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008277
8278#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008279 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008280#else
8281 init_completion(&pHddCtx->driver_crda_req);
8282#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008283
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308284 spin_lock_init(&pHddCtx->schedScan_lock);
8285
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8287
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308288#ifdef FEATURE_WLAN_TDLS
8289 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8290 * invoked by other instances also) to protect the concurrent
8291 * access for the Adapters by TDLS module.
8292 */
8293 mutex_init(&pHddCtx->tdls_lock);
8294#endif
8295
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308296 pHddCtx->nEnableStrictRegulatoryForFCC = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008297 // Load all config first as TL config is needed during vos_open
8298 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8299 if(pHddCtx->cfg_ini == NULL)
8300 {
8301 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8302 goto err_free_hdd_context;
8303 }
8304
8305 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8306
8307 // Read and parse the qcom_cfg.ini file
8308 status = hdd_parse_config_ini( pHddCtx );
8309 if ( VOS_STATUS_SUCCESS != status )
8310 {
8311 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8312 __func__, WLAN_INI_FILE);
8313 goto err_config;
8314 }
Arif Hussaind5218912013-12-05 01:10:55 -08008315#ifdef MEMORY_DEBUG
8316 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8317 vos_mem_init();
8318
8319 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8320 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8321#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008322
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308323 /* INI has been read, initialise the configuredMcastBcastFilter with
8324 * INI value as this will serve as the default value
8325 */
8326 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8327 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8328 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308329
8330 if (false == hdd_is_5g_supported(pHddCtx))
8331 {
8332 //5Ghz is not supported.
8333 if (1 != pHddCtx->cfg_ini->nBandCapability)
8334 {
8335 hddLog(VOS_TRACE_LEVEL_INFO,
8336 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8337 pHddCtx->cfg_ini->nBandCapability = 1;
8338 }
8339 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308340
8341 /* If SNR Monitoring is enabled, FW has to parse all beacons
8342 * for calcaluting and storing the average SNR, so set Nth beacon
8343 * filter to 1 to enable FW to parse all the beaocons
8344 */
8345 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8346 {
8347 /* The log level is deliberately set to WARN as overriding
8348 * nthBeaconFilter to 1 will increase power cosumption and this
8349 * might just prove helpful to detect the power issue.
8350 */
8351 hddLog(VOS_TRACE_LEVEL_WARN,
8352 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8353 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8354 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308356 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008357 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008358 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008360 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8361 {
8362 hddLog(VOS_TRACE_LEVEL_FATAL,
8363 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8364 goto err_config;
8365 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008366 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008367
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008368 // Update VOS trace levels based upon the cfg.ini
8369 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8370 pHddCtx->cfg_ini->vosTraceEnableBAP);
8371 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8372 pHddCtx->cfg_ini->vosTraceEnableTL);
8373 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8374 pHddCtx->cfg_ini->vosTraceEnableWDI);
8375 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8376 pHddCtx->cfg_ini->vosTraceEnableHDD);
8377 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8378 pHddCtx->cfg_ini->vosTraceEnableSME);
8379 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8380 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308381 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8382 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008383 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8384 pHddCtx->cfg_ini->vosTraceEnableWDA);
8385 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8386 pHddCtx->cfg_ini->vosTraceEnableSYS);
8387 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8388 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008389 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8390 pHddCtx->cfg_ini->vosTraceEnableSAP);
8391 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8392 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008393
Jeff Johnson295189b2012-06-20 16:38:30 -07008394 // Update WDI trace levels based upon the cfg.ini
8395 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8396 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8397 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8398 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8399 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8400 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8401 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8402 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008403
Jeff Johnson88ba7742013-02-27 14:36:02 -08008404 if (VOS_FTM_MODE == hdd_get_conparam())
8405 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8407 {
8408 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8409 goto err_free_hdd_context;
8410 }
8411 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308412
8413 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008414 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008415 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008416
Jeff Johnson88ba7742013-02-27 14:36:02 -08008417 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008418 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8419 {
8420 status = vos_watchdog_open(pVosContext,
8421 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8422
8423 if(!VOS_IS_STATUS_SUCCESS( status ))
8424 {
8425 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308426 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 }
8428 }
8429
8430 pHddCtx->isLogpInProgress = FALSE;
8431 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8432
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 status = vos_chipVoteOnXOBuffer(NULL, NULL, NULL);
8434 if(!VOS_IS_STATUS_SUCCESS(status))
8435 {
8436 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed to configure 19.2 MHz Clock", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008437 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 }
8439
Amar Singhala49cbc52013-10-08 18:37:44 -07008440#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008441 /* initialize the NV module. This is required so that
8442 we can initialize the channel information in wiphy
8443 from the NV.bin data. The channel information in
8444 wiphy needs to be initialized before wiphy registration */
8445
8446 status = vos_nv_open();
8447 if (!VOS_IS_STATUS_SUCCESS(status))
8448 {
8449 /* NV module cannot be initialized */
8450 hddLog( VOS_TRACE_LEVEL_FATAL,
8451 "%s: vos_nv_open failed", __func__);
8452 goto err_clkvote;
8453 }
8454
8455 status = vos_init_wiphy_from_nv_bin();
8456 if (!VOS_IS_STATUS_SUCCESS(status))
8457 {
8458 /* NV module cannot be initialized */
8459 hddLog( VOS_TRACE_LEVEL_FATAL,
8460 "%s: vos_init_wiphy failed", __func__);
8461 goto err_vos_nv_close;
8462 }
8463
Amar Singhala49cbc52013-10-08 18:37:44 -07008464#endif
8465
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308466 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008467 if ( !VOS_IS_STATUS_SUCCESS( status ))
8468 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008469 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308470 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008471 }
8472
Jeff Johnson295189b2012-06-20 16:38:30 -07008473 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8474
8475 if ( NULL == pHddCtx->hHal )
8476 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008477 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 goto err_vosclose;
8479 }
8480
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008481 status = vos_preStart( pHddCtx->pvosContext );
8482 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8483 {
8484 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308485 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008486 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008487
Arif Hussaineaf68602013-12-30 23:10:44 -08008488 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8489 {
8490 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8491 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8492 __func__, enable_dfs_chan_scan);
8493 }
8494 if (0 == enable_11d || 1 == enable_11d)
8495 {
8496 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8497 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8498 __func__, enable_11d);
8499 }
8500
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008501 /* Note that the vos_preStart() sequence triggers the cfg download.
8502 The cfg download must occur before we update the SME config
8503 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008504 status = hdd_set_sme_config( pHddCtx );
8505
8506 if ( VOS_STATUS_SUCCESS != status )
8507 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008508 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308509 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008510 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008511
8512 //Initialize the WMM module
Leela Venkata Kiran Kumar Reddy Chirala8e69fbc2013-10-30 18:51:13 -07008513 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra);
8514 status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p);
Jeff Johnson295189b2012-06-20 16:38:30 -07008515 if (!VOS_IS_STATUS_SUCCESS(status))
8516 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008517 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308518 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008519 }
8520
Jeff Johnson295189b2012-06-20 16:38:30 -07008521 /* In the integrated architecture we update the configuration from
8522 the INI file and from NV before vOSS has been started so that
8523 the final contents are available to send down to the cCPU */
8524
8525 // Apply the cfg.ini to cfg.dat
8526 if (FALSE == hdd_update_config_dat(pHddCtx))
8527 {
8528 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308529 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008530 }
8531
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308532 // Get mac addr from platform driver
8533 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8534
8535 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008536 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308537 /* Store the mac addr for first interface */
8538 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8539
8540 hddLog(VOS_TRACE_LEVEL_ERROR,
8541 "%s: WLAN Mac Addr: "
8542 MAC_ADDRESS_STR, __func__,
8543 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8544
8545 /* Here, passing Arg2 as 1 because we do not want to change the
8546 last 3 bytes (means non OUI bytes) of first interface mac
8547 addr.
8548 */
8549 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8550 {
8551 hddLog(VOS_TRACE_LEVEL_ERROR,
8552 "%s: Failed to generate wlan interface mac addr "
8553 "using MAC from ini file ", __func__);
8554 }
8555 }
8556 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8557 {
8558 // Apply the NV to cfg.dat
8559 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008560#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8561 /* There was not a valid set of MAC Addresses in NV. See if the
8562 default addresses were modified by the cfg.ini settings. If so,
8563 we'll use them, but if not, we'll autogenerate a set of MAC
8564 addresses based upon the device serial number */
8565
8566 static const v_MACADDR_t default_address =
8567 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008568
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308569 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8570 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008571 {
8572 /* cfg.ini has the default address, invoke autogen logic */
8573
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308574 /* Here, passing Arg2 as 0 because we want to change the
8575 last 3 bytes (means non OUI bytes) of all the interfaces
8576 mac addr.
8577 */
8578 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8579 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308581 hddLog(VOS_TRACE_LEVEL_ERROR,
8582 "%s: Failed to generate wlan interface mac addr "
8583 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8584 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008585 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008586 }
8587 else
8588#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8589 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008590 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 "%s: Invalid MAC address in NV, using MAC from ini file "
8592 MAC_ADDRESS_STR, __func__,
8593 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8594 }
8595 }
8596 {
8597 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308598
8599 /* Set the MAC Address Currently this is used by HAL to
8600 * add self sta. Remove this once self sta is added as
8601 * part of session open.
8602 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008603 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8604 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8605 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308606
Jeff Johnson295189b2012-06-20 16:38:30 -07008607 if (!HAL_STATUS_SUCCESS( halStatus ))
8608 {
8609 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8610 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308611 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008612 }
8613 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008614
8615 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8616 Note: Firmware image will be read and downloaded inside vos_start API */
8617 status = vos_start( pHddCtx->pvosContext );
8618 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8619 {
8620 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308621 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008622 }
8623
Leo Chang6cec3e22014-01-21 15:33:49 -08008624#ifdef FEATURE_WLAN_CH_AVOID
8625 /* Plug in avoid channel notification callback
8626 * This should happen before ADD_SELF_STA
8627 * FW will send first IND with ADD_SELF_STA REQ from host */
8628 sme_AddChAvoidCallback(pHddCtx->hHal,
8629 hdd_hostapd_ch_avoid_cb);
8630#endif /* FEATURE_WLAN_CH_AVOID */
8631
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008632 /* Exchange capability info between Host and FW and also get versioning info from FW */
8633 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008634
8635 status = hdd_post_voss_start_config( pHddCtx );
8636 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8637 {
8638 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8639 __func__);
8640 goto err_vosstop;
8641 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008642
8643#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308644 wlan_hdd_cfg80211_update_reg_info( wiphy );
8645
8646 /* registration of wiphy dev with cfg80211 */
8647 if (0 > wlan_hdd_cfg80211_register(wiphy))
8648 {
8649 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8650 goto err_vosstop;
8651 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008652#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008653
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308654#ifdef CONFIG_ENABLE_LINUX_REG
8655 status = wlan_hdd_init_channels(pHddCtx);
8656 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8657 {
8658 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8659 __func__);
8660 goto err_vosstop;
8661 }
8662
8663 /* registration of wiphy dev with cfg80211 */
8664 if (0 > wlan_hdd_cfg80211_register(wiphy))
8665 {
8666 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8667 goto err_vosstop;
8668 }
8669
8670 status = wlan_hdd_init_channels_for_cc(pHddCtx);
8671 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8672 {
8673 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
8674 __func__);
8675 goto err_unregister_wiphy;
8676 }
8677#endif
8678
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 if (VOS_STA_SAP_MODE == hdd_get_conparam())
8680 {
8681 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
8682 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8683 }
8684 else
8685 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008686 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
8687 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
8688 if (pAdapter != NULL)
8689 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308690 if ( pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated )
Jeff Johnson295189b2012-06-20 16:38:30 -07008691 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308692 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
8693 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
8694 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07008695
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308696 /* Generate the P2P Device Address. This consists of the device's
8697 * primary MAC address with the locally administered bit set.
8698 */
8699 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07008700 }
8701 else
8702 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05308703 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
8704 if (p2p_dev_addr != NULL)
8705 {
8706 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
8707 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
8708 }
8709 else
8710 {
8711 hddLog(VOS_TRACE_LEVEL_FATAL,
8712 "%s: Failed to allocate mac_address for p2p_device",
8713 __func__);
8714 goto err_close_adapter;
8715 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008717
8718 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
8719 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
8720 if ( NULL == pP2pAdapter )
8721 {
8722 hddLog(VOS_TRACE_LEVEL_FATAL,
8723 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008724 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008725 goto err_close_adapter;
8726 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008727 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008728 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008729
8730 if( pAdapter == NULL )
8731 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008732 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
8733 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008735
Arif Hussain66559122013-11-21 10:11:40 -08008736 if (country_code)
8737 {
8738 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08008739 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08008740 hdd_checkandupdate_dfssetting(pAdapter, country_code);
8741#ifndef CONFIG_ENABLE_LINUX_REG
8742 hdd_checkandupdate_phymode(pAdapter, country_code);
8743#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08008744 ret = sme_ChangeCountryCode(pHddCtx->hHal,
8745 (void *)(tSmeChangeCountryCallback)
8746 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08008747 country_code,
8748 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308749 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08008750 if (eHAL_STATUS_SUCCESS == ret)
8751 {
Arif Hussaincb607082013-12-20 11:57:42 -08008752 ret = wait_for_completion_interruptible_timeout(
8753 &pAdapter->change_country_code,
8754 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
8755
8756 if (0 >= ret)
8757 {
8758 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8759 "%s: SME while setting country code timed out", __func__);
8760 }
Arif Hussain66559122013-11-21 10:11:40 -08008761 }
8762 else
8763 {
Arif Hussaincb607082013-12-20 11:57:42 -08008764 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8765 "%s: SME Change Country code from module param fail ret=%d",
8766 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08008767 }
8768 }
8769
Jeff Johnson295189b2012-06-20 16:38:30 -07008770#ifdef WLAN_BTAMP_FEATURE
8771 vStatus = WLANBAP_Open(pVosContext);
8772 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8773 {
8774 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8775 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07008776 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008777 }
8778
8779 vStatus = BSL_Init(pVosContext);
8780 if(!VOS_IS_STATUS_SUCCESS(vStatus))
8781 {
8782 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8783 "%s: Failed to Init BSL",__func__);
8784 goto err_bap_close;
8785 }
8786 vStatus = WLANBAP_Start(pVosContext);
8787 if (!VOS_IS_STATUS_SUCCESS(vStatus))
8788 {
8789 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8790 "%s: Failed to start TL",__func__);
8791 goto err_bap_close;
8792 }
8793
8794 pConfig = pHddCtx->cfg_ini;
8795 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
8796 status = WLANBAP_SetConfig(&btAmpConfig);
8797
8798#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07008799
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07008800#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
8801 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
8802 {
8803 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
8804 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
8805 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
8806 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
8807 }
8808#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008809#ifdef FEATURE_WLAN_SCAN_PNO
8810 /*SME must send channel update configuration to RIVA*/
8811 sme_UpdateChannelConfig(pHddCtx->hHal);
8812#endif
8813
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308814 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
8815
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 /* Register with platform driver as client for Suspend/Resume */
8817 status = hddRegisterPmOps(pHddCtx);
8818 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8819 {
8820 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
8821#ifdef WLAN_BTAMP_FEATURE
8822 goto err_bap_stop;
8823#else
Jeff Johnsone7245742012-09-05 17:12:55 -07008824 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07008825#endif //WLAN_BTAMP_FEATURE
8826 }
8827
Yue Ma0d4891e2013-08-06 17:01:45 -07008828 /* Open debugfs interface */
8829 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
8830 {
8831 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8832 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07008833 }
8834
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 /* Register TM level change handler function to the platform */
8836 status = hddDevTmRegisterNotifyCallback(pHddCtx);
8837 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8838 {
8839 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
8840 goto err_unregister_pmops;
8841 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008842
8843 /* register for riva power on lock to platform driver */
8844 if (req_riva_power_on_lock("wlan"))
8845 {
8846 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
8847 __func__);
8848 goto err_unregister_pmops;
8849 }
8850
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 // register net device notifier for device change notification
8852 ret = register_netdevice_notifier(&hdd_netdev_notifier);
8853
8854 if(ret < 0)
8855 {
8856 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
8857 goto err_free_power_on_lock;
8858 }
8859
8860 //Initialize the nlink service
8861 if(nl_srv_init() != 0)
8862 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308863 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008864 goto err_reg_netdev;
8865 }
8866
Leo Chang4ce1cc52013-10-21 18:27:15 -07008867#ifdef WLAN_KD_READY_NOTIFIER
8868 pHddCtx->kd_nl_init = 1;
8869#endif /* WLAN_KD_READY_NOTIFIER */
8870
Jeff Johnson295189b2012-06-20 16:38:30 -07008871 //Initialize the BTC service
8872 if(btc_activate_service(pHddCtx) != 0)
8873 {
8874 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
8875 goto err_nl_srv;
8876 }
8877
8878#ifdef PTT_SOCK_SVC_ENABLE
8879 //Initialize the PTT service
8880 if(ptt_sock_activate_svc(pHddCtx) != 0)
8881 {
8882 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
8883 goto err_nl_srv;
8884 }
8885#endif
8886
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308887#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
8888 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
8889 {
8890 if(wlan_logging_sock_activate_svc(
8891 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
8892 pHddCtx->cfg_ini->wlanLoggingNumBuf))
8893 {
8894 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
8895 " failed", __func__);
8896 goto err_nl_srv;
8897 }
8898 }
8899#endif
8900
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008902 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07008904 /* Action frame registered in one adapter which will
8905 * applicable to all interfaces
8906 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308907 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008909
8910 mutex_init(&pHddCtx->sap_lock);
8911
Mihir Shete18156292014-03-11 15:38:30 +05308912 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008913
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008914#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008915#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8916 /* Initialize the wake lcok */
8917 wake_lock_init(&pHddCtx->rx_wake_lock,
8918 WAKE_LOCK_SUSPEND,
8919 "qcom_rx_wakelock");
8920#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008921 /* Initialize the wake lcok */
8922 wake_lock_init(&pHddCtx->sap_wake_lock,
8923 WAKE_LOCK_SUSPEND,
8924 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008925#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008926
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008927 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
8928 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07008929
8930 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8931 hdd_allow_suspend();
Abhishek Singha306a442013-11-07 18:39:01 +05308932#ifndef CONFIG_ENABLE_LINUX_REG
8933 /*updating wiphy so that regulatory user hints can be processed*/
8934 if (wiphy)
8935 {
8936 regulatory_hint(wiphy, "00");
8937 }
8938#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008939 // Initialize the restart logic
8940 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05308941
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008942 //Register the traffic monitor timer now
8943 if ( pHddCtx->cfg_ini->dynSplitscan)
8944 {
8945 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
8946 VOS_TIMER_TYPE_SW,
8947 hdd_tx_rx_pkt_cnt_stat_timer_handler,
8948 (void *)pHddCtx);
8949 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 goto success;
8951
8952err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07008953#ifdef WLAN_KD_READY_NOTIFIER
8954 nl_srv_exit(pHddCtx->ptt_pid);
8955#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07008957#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07008958err_reg_netdev:
8959 unregister_netdevice_notifier(&hdd_netdev_notifier);
8960
8961err_free_power_on_lock:
8962 free_riva_power_on_lock("wlan");
8963
8964err_unregister_pmops:
8965 hddDevTmUnregisterNotifyCallback(pHddCtx);
8966 hddDeregisterPmOps(pHddCtx);
8967
Yue Ma0d4891e2013-08-06 17:01:45 -07008968 hdd_debugfs_exit(pHddCtx);
8969
Jeff Johnson295189b2012-06-20 16:38:30 -07008970#ifdef WLAN_BTAMP_FEATURE
8971err_bap_stop:
8972 WLANBAP_Stop(pVosContext);
8973#endif
8974
8975#ifdef WLAN_BTAMP_FEATURE
8976err_bap_close:
8977 WLANBAP_Close(pVosContext);
8978#endif
8979
Jeff Johnson295189b2012-06-20 16:38:30 -07008980err_close_adapter:
8981 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308982err_unregister_wiphy:
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308983 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008984err_vosstop:
8985 vos_stop(pVosContext);
8986
Amar Singhala49cbc52013-10-08 18:37:44 -07008987err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07008988 status = vos_sched_close( pVosContext );
8989 if (!VOS_IS_STATUS_SUCCESS(status)) {
8990 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8991 "%s: Failed to close VOSS Scheduler", __func__);
8992 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
8993 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008994 vos_close(pVosContext );
8995
Amar Singhal0a402232013-10-11 20:57:16 -07008996err_vos_nv_close:
8997
c_hpothue6a36282014-03-19 12:27:38 +05308998#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008999 vos_nv_close();
9000
Jeff Johnson295189b2012-06-20 16:38:30 -07009001err_clkvote:
c_hpothu70f8d812014-03-22 22:59:23 +05309002#endif
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009003 vos_chipVoteOffXOBuffer(NULL, NULL, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009004
9005err_wdclose:
9006 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9007 vos_watchdog_close(pVosContext);
9008
Jeff Johnson295189b2012-06-20 16:38:30 -07009009err_config:
9010 kfree(pHddCtx->cfg_ini);
9011 pHddCtx->cfg_ini= NULL;
9012
9013err_free_hdd_context:
9014 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009015 wiphy_free(wiphy) ;
9016 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009017 VOS_BUG(1);
9018
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009019 if (hdd_is_ssr_required())
9020 {
9021 /* WDI timeout had happened during load, so SSR is needed here */
9022 subsystem_restart("wcnss");
9023 msleep(5000);
9024 }
9025 hdd_set_ssr_required (VOS_FALSE);
9026
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009027 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009028
9029success:
9030 EXIT();
9031 return 0;
9032}
9033
9034/**---------------------------------------------------------------------------
9035
Jeff Johnson32d95a32012-09-10 13:15:23 -07009036 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009037
Jeff Johnson32d95a32012-09-10 13:15:23 -07009038 This is the driver entry point - called in different timeline depending
9039 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009040
9041 \param - None
9042
9043 \return - 0 for success, non zero for failure
9044
9045 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009046static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009047{
9048 VOS_STATUS status;
9049 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009050 struct device *dev = NULL;
9051 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009052#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9053 int max_retries = 0;
9054#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009055
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309056#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9057 wlan_logging_sock_init_svc();
9058#endif
9059
Jeff Johnson295189b2012-06-20 16:38:30 -07009060 ENTER();
9061
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009062#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009063 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009064#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009065
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309066 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009067 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9068 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9069
9070 //Power Up Libra WLAN card first if not already powered up
9071 status = vos_chipPowerUp(NULL,NULL,NULL);
9072 if (!VOS_IS_STATUS_SUCCESS(status))
9073 {
9074 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Libra WLAN not Powered Up. "
9075 "exiting", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309076#ifdef WLAN_OPEN_SOURCE
9077 wake_lock_destroy(&wlan_wake_lock);
9078#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309079
9080#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9081 wlan_logging_sock_deinit_svc();
9082#endif
9083
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009084 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009085 }
9086
Jeff Johnson295189b2012-06-20 16:38:30 -07009087#ifdef ANI_BUS_TYPE_PCI
9088
9089 dev = wcnss_wlan_get_device();
9090
9091#endif // ANI_BUS_TYPE_PCI
9092
9093#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009094
9095#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9096 /* wait until WCNSS driver downloads NV */
9097 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9098 msleep(1000);
9099 }
9100 if (max_retries >= 5) {
9101 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309102#ifdef WLAN_OPEN_SOURCE
9103 wake_lock_destroy(&wlan_wake_lock);
9104#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309105
9106#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9107 wlan_logging_sock_deinit_svc();
9108#endif
9109
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009110 return -ENODEV;
9111 }
9112#endif
9113
Jeff Johnson295189b2012-06-20 16:38:30 -07009114 dev = wcnss_wlan_get_device();
9115#endif // ANI_BUS_TYPE_PLATFORM
9116
9117
9118 do {
9119 if (NULL == dev) {
9120 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9121 ret_status = -1;
9122 break;
9123 }
9124
Jeff Johnson295189b2012-06-20 16:38:30 -07009125#ifdef TIMER_MANAGER
9126 vos_timer_manager_init();
9127#endif
9128
9129 /* Preopen VOSS so that it is ready to start at least SAL */
9130 status = vos_preOpen(&pVosContext);
9131
9132 if (!VOS_IS_STATUS_SUCCESS(status))
9133 {
9134 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9135 ret_status = -1;
9136 break;
9137 }
9138
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009139#ifndef MODULE
9140 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9141 */
9142 hdd_set_conparam((v_UINT_t)con_mode);
9143#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009144
9145 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009146 if (hdd_wlan_startup(dev))
9147 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009148 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009149 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 vos_preClose( &pVosContext );
9151 ret_status = -1;
9152 break;
9153 }
9154
9155 /* Cancel the vote for XO Core ON
9156 * This is done here for safety purposes in case we re-initialize without turning
9157 * it OFF in any error scenario.
9158 */
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009159 hddLog(VOS_TRACE_LEVEL_INFO, "In module init: Ensure Force XO Core is OFF"
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 " when WLAN is turned ON so Core toggles"
Madan Mohan Koyyalamudi8b7f1e62012-10-05 14:56:51 -07009161 " unless we enter PSD");
Jeff Johnson295189b2012-06-20 16:38:30 -07009162 if (vos_chipVoteXOCore(NULL, NULL, NULL, VOS_FALSE) != VOS_STATUS_SUCCESS)
9163 {
9164 hddLog(VOS_TRACE_LEVEL_ERROR, "Could not cancel XO Core ON vote. Not returning failure."
Arif Hussain6d2a3322013-11-17 19:50:10 -08009165 " Power consumed will be high");
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 }
9167 } while (0);
9168
9169 if (0 != ret_status)
9170 {
9171 //Assert Deep sleep signal now to put Libra HW in lowest power state
9172 status = vos_chipAssertDeepSleep( NULL, NULL, NULL );
9173 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status) );
9174
9175 //Vote off any PMIC voltage supplies
9176 vos_chipPowerDown(NULL, NULL, NULL);
9177#ifdef TIMER_MANAGER
9178 vos_timer_exit();
9179#endif
9180#ifdef MEMORY_DEBUG
9181 vos_mem_exit();
9182#endif
9183
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009184#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009185 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009186#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309187
9188#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9189 wlan_logging_sock_deinit_svc();
9190#endif
9191
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9193 }
9194 else
9195 {
9196 //Send WLAN UP indication to Nlink Service
9197 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9198
9199 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009200 }
9201
9202 EXIT();
9203
9204 return ret_status;
9205}
9206
Jeff Johnson32d95a32012-09-10 13:15:23 -07009207/**---------------------------------------------------------------------------
9208
9209 \brief hdd_module_init() - Init Function
9210
9211 This is the driver entry point (invoked when module is loaded using insmod)
9212
9213 \param - None
9214
9215 \return - 0 for success, non zero for failure
9216
9217 --------------------------------------------------------------------------*/
9218#ifdef MODULE
9219static int __init hdd_module_init ( void)
9220{
9221 return hdd_driver_init();
9222}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009223#else /* #ifdef MODULE */
9224static int __init hdd_module_init ( void)
9225{
9226 /* Driver initialization is delayed to fwpath_changed_handler */
9227 return 0;
9228}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009229#endif /* #ifdef MODULE */
9230
Jeff Johnson295189b2012-06-20 16:38:30 -07009231
9232/**---------------------------------------------------------------------------
9233
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009234 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009235
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009236 This is the driver exit point (invoked when module is unloaded using rmmod
9237 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009238
9239 \param - None
9240
9241 \return - None
9242
9243 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009244static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009245{
9246 hdd_context_t *pHddCtx = NULL;
9247 v_CONTEXT_t pVosContext = NULL;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309248 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009249
9250 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9251
9252 //Get the global vos context
9253 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9254
9255 if(!pVosContext)
9256 {
9257 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9258 goto done;
9259 }
9260
9261 //Get the HDD context.
9262 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9263
9264 if(!pHddCtx)
9265 {
9266 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9267 }
9268 else
9269 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309270 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9271
9272 if (pHddCtx->isLogpInProgress)
9273 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309275 "%s:SSR in Progress; block rmmod !!!", __func__);
9276 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9277 msecs_to_jiffies(30000));
9278 if(!rc)
9279 {
9280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9281 "%s:SSR timedout, fatal error", __func__);
9282 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009283 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309284 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009285
Mihir Shete18156292014-03-11 15:38:30 +05309286 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9288
9289 //Do all the cleanup before deregistering the driver
9290 hdd_wlan_exit(pHddCtx);
9291 }
9292
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 vos_preClose( &pVosContext );
9294
9295#ifdef TIMER_MANAGER
9296 vos_timer_exit();
9297#endif
9298#ifdef MEMORY_DEBUG
9299 vos_mem_exit();
9300#endif
9301
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309302#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9303 wlan_logging_sock_deinit_svc();
9304#endif
9305
Jeff Johnson295189b2012-06-20 16:38:30 -07009306done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009307#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009309#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309310
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9312}
9313
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009314/**---------------------------------------------------------------------------
9315
9316 \brief hdd_module_exit() - Exit function
9317
9318 This is the driver exit point (invoked when module is unloaded using rmmod)
9319
9320 \param - None
9321
9322 \return - None
9323
9324 --------------------------------------------------------------------------*/
9325static void __exit hdd_module_exit(void)
9326{
9327 hdd_driver_exit();
9328}
9329
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009330#ifdef MODULE
9331static int fwpath_changed_handler(const char *kmessage,
9332 struct kernel_param *kp)
9333{
Jeff Johnson76052702013-04-16 13:55:05 -07009334 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009335}
9336
9337static int con_mode_handler(const char *kmessage,
9338 struct kernel_param *kp)
9339{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009340 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009341}
9342#else /* #ifdef MODULE */
9343/**---------------------------------------------------------------------------
9344
Jeff Johnson76052702013-04-16 13:55:05 -07009345 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009346
Jeff Johnson76052702013-04-16 13:55:05 -07009347 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009348 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009349 - invoked when module parameter fwpath is modified from userspace to signal
9350 initializing the WLAN driver or when con_mode is modified from userspace
9351 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009352
9353 \return - 0 for success, non zero for failure
9354
9355 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009356static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009357{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009358 int ret_status;
9359
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009360 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009361 ret_status = hdd_driver_init();
9362 wlan_hdd_inited = ret_status ? 0 : 1;
9363 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009364 }
9365
9366 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009367
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009368 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009369
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009370 ret_status = hdd_driver_init();
9371 wlan_hdd_inited = ret_status ? 0 : 1;
9372 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009373}
9374
Jeff Johnson295189b2012-06-20 16:38:30 -07009375/**---------------------------------------------------------------------------
9376
Jeff Johnson76052702013-04-16 13:55:05 -07009377 \brief fwpath_changed_handler() - Handler Function
9378
9379 Handle changes to the fwpath parameter
9380
9381 \return - 0 for success, non zero for failure
9382
9383 --------------------------------------------------------------------------*/
9384static int fwpath_changed_handler(const char *kmessage,
9385 struct kernel_param *kp)
9386{
9387 int ret;
9388
9389 ret = param_set_copystring(kmessage, kp);
9390 if (0 == ret)
9391 ret = kickstart_driver();
9392 return ret;
9393}
9394
9395/**---------------------------------------------------------------------------
9396
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009397 \brief con_mode_handler() -
9398
9399 Handler function for module param con_mode when it is changed by userspace
9400 Dynamically linked - do nothing
9401 Statically linked - exit and init driver, as in rmmod and insmod
9402
Jeff Johnson76052702013-04-16 13:55:05 -07009403 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009404
Jeff Johnson76052702013-04-16 13:55:05 -07009405 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009406
9407 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009408static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009409{
Jeff Johnson76052702013-04-16 13:55:05 -07009410 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009411
Jeff Johnson76052702013-04-16 13:55:05 -07009412 ret = param_set_int(kmessage, kp);
9413 if (0 == ret)
9414 ret = kickstart_driver();
9415 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009416}
9417#endif /* #ifdef MODULE */
9418
9419/**---------------------------------------------------------------------------
9420
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 \brief hdd_get_conparam() -
9422
9423 This is the driver exit point (invoked when module is unloaded using rmmod)
9424
9425 \param - None
9426
9427 \return - tVOS_CON_MODE
9428
9429 --------------------------------------------------------------------------*/
9430tVOS_CON_MODE hdd_get_conparam ( void )
9431{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009432#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009433 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009434#else
9435 return (tVOS_CON_MODE)curr_con_mode;
9436#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009437}
9438void hdd_set_conparam ( v_UINT_t newParam )
9439{
9440 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009441#ifndef MODULE
9442 curr_con_mode = con_mode;
9443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009444}
9445/**---------------------------------------------------------------------------
9446
9447 \brief hdd_softap_sta_deauth() - function
9448
9449 This to take counter measure to handle deauth req from HDD
9450
9451 \param - pAdapter - Pointer to the HDD
9452
9453 \param - enable - boolean value
9454
9455 \return - None
9456
9457 --------------------------------------------------------------------------*/
9458
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009459VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009460{
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009462 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009463
9464 ENTER();
9465
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009466 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9467 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009468
9469 //Ignore request to deauth bcmc station
9470 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009471 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009472
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009473 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009474
9475 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009476 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009477}
9478
9479/**---------------------------------------------------------------------------
9480
9481 \brief hdd_softap_sta_disassoc() - function
9482
9483 This to take counter measure to handle deauth req from HDD
9484
9485 \param - pAdapter - Pointer to the HDD
9486
9487 \param - enable - boolean value
9488
9489 \return - None
9490
9491 --------------------------------------------------------------------------*/
9492
9493void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9494{
9495 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9496
9497 ENTER();
9498
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309499 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009500
9501 //Ignore request to disassoc bcmc station
9502 if( pDestMacAddress[0] & 0x1 )
9503 return;
9504
9505 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9506}
9507
9508void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9509{
9510 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9511
9512 ENTER();
9513
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309514 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009515
9516 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9517}
9518
Jeff Johnson295189b2012-06-20 16:38:30 -07009519/**---------------------------------------------------------------------------
9520 *
9521 * \brief hdd_get__concurrency_mode() -
9522 *
9523 *
9524 * \param - None
9525 *
9526 * \return - CONCURRENCY MODE
9527 *
9528 * --------------------------------------------------------------------------*/
9529tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9530{
9531 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9532 hdd_context_t *pHddCtx;
9533
9534 if (NULL != pVosContext)
9535 {
9536 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9537 if (NULL != pHddCtx)
9538 {
9539 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9540 }
9541 }
9542
9543 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009544 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009545 return VOS_STA;
9546}
9547
9548/* Decide whether to allow/not the apps power collapse.
9549 * Allow apps power collapse if we are in connected state.
9550 * if not, allow only if we are in IMPS */
9551v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9552{
9553 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009554 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009555 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9557 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9558 hdd_adapter_t *pAdapter = NULL;
9559 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -08009560 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009561
Jeff Johnson295189b2012-06-20 16:38:30 -07009562 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9563 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009564
Yathish9f22e662012-12-10 14:21:35 -08009565 concurrent_state = hdd_get_concurrency_mode();
9566
9567#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
9568 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
9569 (concurrent_state == (VOS_STA | VOS_P2P_GO))) &&
9570 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
9571 return TRUE;
9572#endif
9573
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 /*loop through all adapters. TBD fix for Concurrency */
9575 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9576 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9577 {
9578 pAdapter = pAdapterNode->pAdapter;
9579 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
9580 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9581 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009582 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +05309583 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -08009584 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009585 (eANI_BOOLEAN_TRUE == scanRspPending) ||
9586 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 {
Srikant Kuppafef66a72013-01-30 17:32:44 -08009588 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009589 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
9590 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -07009591 return FALSE;
9592 }
9593 }
9594 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9595 pAdapterNode = pNext;
9596 }
9597 return TRUE;
9598}
9599
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -08009600/* Decides whether to send suspend notification to Riva
9601 * if any adapter is in BMPS; then it is required */
9602v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
9603{
9604 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
9605 hdd_config_t *pConfig = pHddCtx->cfg_ini;
9606
9607 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
9608 {
9609 return TRUE;
9610 }
9611 return FALSE;
9612}
9613
Jeff Johnson295189b2012-06-20 16:38:30 -07009614void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9615{
9616 switch(mode)
9617 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009618 case VOS_STA_MODE:
9619 case VOS_P2P_CLIENT_MODE:
9620 case VOS_P2P_GO_MODE:
9621 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -07009622 pHddCtx->concurrency_mode |= (1 << mode);
9623 pHddCtx->no_of_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 break;
9625 default:
9626 break;
9627
9628 }
9629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9630 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9631}
9632
9633
9634void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
9635{
9636 switch(mode)
9637 {
Chilam Ngc4244af2013-04-01 15:37:32 -07009638 case VOS_STA_MODE:
9639 case VOS_P2P_CLIENT_MODE:
9640 case VOS_P2P_GO_MODE:
9641 case VOS_STA_SAP_MODE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 pHddCtx->no_of_sessions[mode]--;
9643 if (!(pHddCtx->no_of_sessions[mode]))
9644 pHddCtx->concurrency_mode &= (~(1 << mode));
9645 break;
9646 default:
9647 break;
9648 }
9649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: concurrency_mode = 0x%x NumberofSessions for mode %d = %d",
9650 __func__,pHddCtx->concurrency_mode,mode,pHddCtx->no_of_sessions[mode]);
9651}
9652
Jeff Johnsone7245742012-09-05 17:12:55 -07009653/**---------------------------------------------------------------------------
9654 *
9655 * \brief wlan_hdd_restart_init
9656 *
9657 * This function initalizes restart timer/flag. An internal function.
9658 *
9659 * \param - pHddCtx
9660 *
9661 * \return - None
9662 *
9663 * --------------------------------------------------------------------------*/
9664
9665static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
9666{
9667 /* Initialize */
9668 pHddCtx->hdd_restart_retries = 0;
9669 atomic_set(&pHddCtx->isRestartInProgress, 0);
9670 vos_timer_init(&pHddCtx->hdd_restart_timer,
9671 VOS_TIMER_TYPE_SW,
9672 wlan_hdd_restart_timer_cb,
9673 pHddCtx);
9674}
9675/**---------------------------------------------------------------------------
9676 *
9677 * \brief wlan_hdd_restart_deinit
9678 *
9679 * This function cleans up the resources used. An internal function.
9680 *
9681 * \param - pHddCtx
9682 *
9683 * \return - None
9684 *
9685 * --------------------------------------------------------------------------*/
9686
9687static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
9688{
9689
9690 VOS_STATUS vos_status;
9691 /* Block any further calls */
9692 atomic_set(&pHddCtx->isRestartInProgress, 1);
9693 /* Cleanup */
9694 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
9695 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309696 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009697 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
9698 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309699 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -07009700
9701}
9702
9703/**---------------------------------------------------------------------------
9704 *
9705 * \brief wlan_hdd_framework_restart
9706 *
9707 * This function uses a cfg80211 API to start a framework initiated WLAN
9708 * driver module unload/load.
9709 *
9710 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
9711 *
9712 *
9713 * \param - pHddCtx
9714 *
9715 * \return - VOS_STATUS_SUCCESS: Success
9716 * VOS_STATUS_E_EMPTY: Adapter is Empty
9717 * VOS_STATUS_E_NOMEM: No memory
9718
9719 * --------------------------------------------------------------------------*/
9720
9721static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
9722{
9723 VOS_STATUS status = VOS_STATUS_SUCCESS;
9724 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009725 int len = (sizeof (struct ieee80211_mgmt));
9726 struct ieee80211_mgmt *mgmt = NULL;
9727
9728 /* Prepare the DEAUTH managment frame with reason code */
9729 mgmt = kzalloc(len, GFP_KERNEL);
9730 if(mgmt == NULL)
9731 {
9732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9733 "%s: memory allocation failed (%d bytes)", __func__, len);
9734 return VOS_STATUS_E_NOMEM;
9735 }
9736 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -07009737
9738 /* Iterate over all adapters/devices */
9739 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9740 do
9741 {
9742 if( (status == VOS_STATUS_SUCCESS) &&
9743 pAdapterNode &&
9744 pAdapterNode->pAdapter)
9745 {
9746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9747 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
9748 pAdapterNode->pAdapter->dev->name,
9749 pAdapterNode->pAdapter->device_mode,
9750 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009751 /*
9752 * CFG80211 event to restart the driver
9753 *
9754 * 'cfg80211_send_unprot_deauth' sends a
9755 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
9756 * of SME(Linux Kernel) state machine.
9757 *
9758 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
9759 * the driver.
9760 *
9761 */
9762
9763 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -07009764 }
9765 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9766 pAdapterNode = pNext;
9767 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
9768
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -07009769
9770 /* Free the allocated management frame */
9771 kfree(mgmt);
9772
Jeff Johnsone7245742012-09-05 17:12:55 -07009773 /* Retry until we unload or reach max count */
9774 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
9775 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
9776
9777 return status;
9778
9779}
9780/**---------------------------------------------------------------------------
9781 *
9782 * \brief wlan_hdd_restart_timer_cb
9783 *
9784 * Restart timer callback. An internal function.
9785 *
9786 * \param - User data:
9787 *
9788 * \return - None
9789 *
9790 * --------------------------------------------------------------------------*/
9791
9792void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
9793{
9794 hdd_context_t *pHddCtx = usrDataForCallback;
9795 wlan_hdd_framework_restart(pHddCtx);
9796 return;
9797
9798}
9799
9800
9801/**---------------------------------------------------------------------------
9802 *
9803 * \brief wlan_hdd_restart_driver
9804 *
9805 * This function sends an event to supplicant to restart the WLAN driver.
9806 *
9807 * This function is called from vos_wlanRestart.
9808 *
9809 * \param - pHddCtx
9810 *
9811 * \return - VOS_STATUS_SUCCESS: Success
9812 * VOS_STATUS_E_EMPTY: Adapter is Empty
9813 * VOS_STATUS_E_ALREADY: Request already in progress
9814
9815 * --------------------------------------------------------------------------*/
9816VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
9817{
9818 VOS_STATUS status = VOS_STATUS_SUCCESS;
9819
9820 /* A tight check to make sure reentrancy */
9821 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
9822 {
9823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9824 "%s: WLAN restart is already in progress", __func__);
9825
9826 return VOS_STATUS_E_ALREADY;
9827 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -07009828 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -08009829#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -07009830 wcnss_reset_intr();
9831#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07009832
Jeff Johnsone7245742012-09-05 17:12:55 -07009833 return status;
9834}
9835
Mihir Shetee1093ba2014-01-21 20:13:32 +05309836/**---------------------------------------------------------------------------
9837 *
9838 * \brief wlan_hdd_init_channels
9839 *
9840 * This function is used to initialize the channel list in CSR
9841 *
9842 * This function is called from hdd_wlan_startup
9843 *
9844 * \param - pHddCtx: HDD context
9845 *
9846 * \return - VOS_STATUS_SUCCESS: Success
9847 * VOS_STATUS_E_FAULT: Failure reported by SME
9848
9849 * --------------------------------------------------------------------------*/
9850static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
9851{
9852 eHalStatus status;
9853
9854 status = sme_InitChannels(pHddCtx->hHal);
9855 if (HAL_STATUS_SUCCESS(status))
9856 {
9857 return VOS_STATUS_SUCCESS;
9858 }
9859 else
9860 {
9861 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
9862 __func__, status);
9863 return VOS_STATUS_E_FAULT;
9864 }
9865}
9866
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309867static VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx)
9868{
9869 eHalStatus status;
9870
9871 status = sme_InitChannelsForCC(pHddCtx->hHal);
9872 if (HAL_STATUS_SUCCESS(status))
9873 {
9874 return VOS_STATUS_SUCCESS;
9875 }
9876 else
9877 {
9878 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
9879 __func__, status);
9880 return VOS_STATUS_E_FAULT;
9881 }
9882}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -07009883/*
9884 * API to find if there is any STA or P2P-Client is connected
9885 */
9886VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
9887{
9888 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
9889}
Jeff Johnsone7245742012-09-05 17:12:55 -07009890
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309891int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
9892{
9893 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9894 hdd_scaninfo_t *pScanInfo = NULL;
9895 int status;
9896
9897 pScanInfo = &pHddCtx->scan_info;
9898 if (pScanInfo->mScanPending)
9899 {
9900 INIT_COMPLETION(pScanInfo->abortscan_event_var);
9901 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
9902 eCSR_SCAN_ABORT_DEFAULT);
9903
9904 status = wait_for_completion_interruptible_timeout(
9905 &pScanInfo->abortscan_event_var,
9906 msecs_to_jiffies(5000));
9907 if ((!status) || (status == -ERESTARTSYS))
9908 {
9909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9910 "%s: Timeout occurred while waiting for abort scan",
9911 __func__);
9912 return -ETIMEDOUT;
9913 }
9914 }
9915 return status;
9916}
9917
Jeff Johnson295189b2012-06-20 16:38:30 -07009918//Register the module init/exit functions
9919module_init(hdd_module_init);
9920module_exit(hdd_module_exit);
9921
9922MODULE_LICENSE("Dual BSD/GPL");
9923MODULE_AUTHOR("Qualcomm Atheros, Inc.");
9924MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
9925
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009926module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
9927 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -07009928
Jeff Johnson76052702013-04-16 13:55:05 -07009929module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009930 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -08009931
9932module_param(enable_dfs_chan_scan, int,
9933 S_IRUSR | S_IRGRP | S_IROTH);
9934
9935module_param(enable_11d, int,
9936 S_IRUSR | S_IRGRP | S_IROTH);
9937
9938module_param(country_code, charp,
9939 S_IRUSR | S_IRGRP | S_IROTH);