blob: 0e9877d7092474b8f9b5db474c30603112961f2b [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
37 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
38
39 Qualcomm Confidential and Proprietary.
40
41 ========================================================================*/
42
43/**=========================================================================
44
45 EDIT HISTORY FOR FILE
46
47
48 This section contains comments describing changes made to the module.
49 Notice that changes are listed in reverse chronological order.
50
51
52 $Header:$ $DateTime: $ $Author: $
53
54
55 when who what, where, why
56 -------- --- --------------------------------------------------------
57 04/5/09 Shailender Created module.
58 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
59 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
60 ==========================================================================*/
61
62/*--------------------------------------------------------------------------
63 Include Files
64 ------------------------------------------------------------------------*/
65//#include <wlan_qct_driver.h>
66#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <vos_api.h>
68#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070069#include <linux/etherdevice.h>
70#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070071#ifdef ANI_BUS_TYPE_PLATFORM
72#include <linux/wcnss_wlan.h>
73#endif //ANI_BUS_TYPE_PLATFORM
74#ifdef ANI_BUS_TYPE_PCI
75#include "wcnss_wlan.h"
76#endif /* ANI_BUS_TYPE_PCI */
77#include <wlan_hdd_tx_rx.h>
78#include <palTimer.h>
79#include <wniApi.h>
80#include <wlan_nlink_srv.h>
81#include <wlan_btc_svc.h>
82#include <wlan_hdd_cfg.h>
83#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053084#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070085#include <wlan_hdd_wowl.h>
86#include <wlan_hdd_misc.h>
87#include <wlan_hdd_wext.h>
88#ifdef WLAN_BTAMP_FEATURE
89#include <bap_hdd_main.h>
90#include <bapInternal.h>
91#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053092#include "wlan_hdd_trace.h"
93#include "vos_types.h"
94#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070095#include <linux/wireless.h>
96#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053097#include <linux/inetdevice.h>
98#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099#include "wlan_hdd_cfg80211.h"
100#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700101#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700102int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700103#include "sapApi.h"
104#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700105#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
107#include <soc/qcom/subsystem_restart.h>
108#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include <wlan_hdd_hostapd.h>
112#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700113#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700114#include "wlan_hdd_dev_pwr.h"
115#ifdef WLAN_BTAMP_FEATURE
116#include "bap_hdd_misc.h"
117#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700118#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700119#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800120#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530121#ifdef FEATURE_WLAN_TDLS
122#include "wlan_hdd_tdls.h"
123#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700124#include "wlan_hdd_debugfs.h"
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
Atul Mittal1d722422014-03-19 11:15:07 +0530190/*
191 * Maximum buffer size used for returning the data back to user space
192 */
193#define WLAN_MAX_BUF_SIZE 1024
194#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700195
c_hpothu92367912014-05-01 15:18:17 +0530196//wait time for beacon miss rate.
197#define BCN_MISS_RATE_TIME 500
198
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800199#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700200static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700201#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700202/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700203static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700204
205//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700206static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
207static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
208static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
209void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800210void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700211
Jeff Johnson295189b2012-06-20 16:38:30 -0700212v_U16_t hdd_select_queue(struct net_device *dev,
213 struct sk_buff *skb);
214
215#ifdef WLAN_FEATURE_PACKET_FILTERING
216static void hdd_set_multicast_list(struct net_device *dev);
217#endif
218
219void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
220
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800221#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800222void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
223static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700224static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
225 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
226 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700227static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
228 tANI_U8 *pTargetApBssid,
229 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800230#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800231#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700232VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800233#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700234
Mihir Shetee1093ba2014-01-21 20:13:32 +0530235static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530236const char * hdd_device_modetoString(v_U8_t device_mode)
237{
238 switch(device_mode)
239 {
240 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
241 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
242 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
243 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
244 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
245 CASE_RETURN_STRING( WLAN_HDD_FTM );
246 CASE_RETURN_STRING( WLAN_HDD_IBSS );
247 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
248 default:
249 return "device_mode Unknown";
250 }
251}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530252
Jeff Johnson295189b2012-06-20 16:38:30 -0700253static int hdd_netdev_notifier_call(struct notifier_block * nb,
254 unsigned long state,
255 void *ndev)
256{
257 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700258 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700259 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700260#ifdef WLAN_BTAMP_FEATURE
261 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530263 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700264
265 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700266 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700267 (strncmp(dev->name, "p2p", 3)))
268 return NOTIFY_DONE;
269
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700271 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700272
Jeff Johnson27cee452013-03-27 11:10:24 -0700273 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700274 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800275 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700276 VOS_ASSERT(0);
277 return NOTIFY_DONE;
278 }
279
Jeff Johnson27cee452013-03-27 11:10:24 -0700280 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
281 if (NULL == pHddCtx)
282 {
283 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
284 VOS_ASSERT(0);
285 return NOTIFY_DONE;
286 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800287 if (pHddCtx->isLogpInProgress)
288 return NOTIFY_DONE;
289
Jeff Johnson27cee452013-03-27 11:10:24 -0700290
291 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
292 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700293
294 switch (state) {
295 case NETDEV_REGISTER:
296 break;
297
298 case NETDEV_UNREGISTER:
299 break;
300
301 case NETDEV_UP:
302 break;
303
304 case NETDEV_DOWN:
305 break;
306
307 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700308 if(TRUE == pAdapter->isLinkUpSvcNeeded)
309 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700310 break;
311
312 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530313 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530314 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530315 {
316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
317 "%s: Timeout occurred while waiting for abortscan %ld",
318 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700319 }
320 else
321 {
322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530323 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700324 }
325#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 status = WLANBAP_StopAmp();
328 if(VOS_STATUS_SUCCESS != status )
329 {
330 pHddCtx->isAmpAllowed = VOS_TRUE;
331 hddLog(VOS_TRACE_LEVEL_FATAL,
332 "%s: Failed to stop AMP", __func__);
333 }
334 else
335 {
336 //a state m/c implementation in PAL is TBD to avoid this delay
337 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700338 if ( pHddCtx->isAmpAllowed )
339 {
340 WLANBAP_DeregisterFromHCI();
341 pHddCtx->isAmpAllowed = VOS_FALSE;
342 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700343 }
344#endif //WLAN_BTAMP_FEATURE
345 break;
346
347 default:
348 break;
349 }
350
351 return NOTIFY_DONE;
352}
353
354struct notifier_block hdd_netdev_notifier = {
355 .notifier_call = hdd_netdev_notifier_call,
356};
357
358/*---------------------------------------------------------------------------
359 * Function definitions
360 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700361void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
362void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700363//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700364static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700365#ifndef MODULE
366/* current con_mode - used only for statically linked driver
367 * con_mode is changed by userspace to indicate a mode change which will
368 * result in calling the module exit and init functions. The module
369 * exit function will clean up based on the value of con_mode prior to it
370 * being changed by userspace. So curr_con_mode records the current con_mode
371 * for exit when con_mode becomes the next mode for init
372 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700373static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700374#endif
375
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800376/**---------------------------------------------------------------------------
377
378 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
379
380 Called immediately after the cfg.ini is read in order to configure
381 the desired trace levels.
382
383 \param - moduleId - module whose trace level is being configured
384 \param - bitmask - bitmask of log levels to be enabled
385
386 \return - void
387
388 --------------------------------------------------------------------------*/
389static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
390{
391 wpt_tracelevel level;
392
393 /* if the bitmask is the default value, then a bitmask was not
394 specified in cfg.ini, so leave the logging level alone (it
395 will remain at the "compiled in" default value) */
396 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
397 {
398 return;
399 }
400
401 /* a mask was specified. start by disabling all logging */
402 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
403
404 /* now cycle through the bitmask until all "set" bits are serviced */
405 level = VOS_TRACE_LEVEL_FATAL;
406 while (0 != bitmask)
407 {
408 if (bitmask & 1)
409 {
410 vos_trace_setValue(moduleId, level, 1);
411 }
412 level++;
413 bitmask >>= 1;
414 }
415}
416
417
Jeff Johnson295189b2012-06-20 16:38:30 -0700418/**---------------------------------------------------------------------------
419
420 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
421
422 Called immediately after the cfg.ini is read in order to configure
423 the desired trace levels in the WDI.
424
425 \param - moduleId - module whose trace level is being configured
426 \param - bitmask - bitmask of log levels to be enabled
427
428 \return - void
429
430 --------------------------------------------------------------------------*/
431static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
432{
433 wpt_tracelevel level;
434
435 /* if the bitmask is the default value, then a bitmask was not
436 specified in cfg.ini, so leave the logging level alone (it
437 will remain at the "compiled in" default value) */
438 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
439 {
440 return;
441 }
442
443 /* a mask was specified. start by disabling all logging */
444 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
445
446 /* now cycle through the bitmask until all "set" bits are serviced */
447 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
448 while (0 != bitmask)
449 {
450 if (bitmask & 1)
451 {
452 wpalTraceSetLevel(moduleId, level, 1);
453 }
454 level++;
455 bitmask >>= 1;
456 }
457}
Jeff Johnson295189b2012-06-20 16:38:30 -0700458
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530459/*
460 * FUNCTION: wlan_hdd_validate_context
461 * This function is used to check the HDD context
462 */
463int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
464{
465 ENTER();
466
467 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
468 {
469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
470 "%s: HDD context is Null", __func__);
471 return -ENODEV;
472 }
473
474 if (pHddCtx->isLogpInProgress)
475 {
476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
477 "%s: LOGP in Progress. Ignore!!!", __func__);
478 return -EAGAIN;
479 }
480
Mihir Shete18156292014-03-11 15:38:30 +0530481 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530482 {
483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
484 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
485 return -EAGAIN;
486 }
487 return 0;
488}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700489#ifdef CONFIG_ENABLE_LINUX_REG
490void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
491{
492 hdd_adapter_t *pAdapter = NULL;
493 hdd_station_ctx_t *pHddStaCtx = NULL;
494 eCsrPhyMode phyMode;
495 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530496
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700497 if (NULL == pHddCtx)
498 {
499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
500 "HDD Context is null !!");
501 return ;
502 }
503
504 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
505 if (NULL == pAdapter)
506 {
507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
508 "pAdapter is null !!");
509 return ;
510 }
511
512 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
513 if (NULL == pHddStaCtx)
514 {
515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
516 "pHddStaCtx is null !!");
517 return ;
518 }
519
520 cfg_param = pHddCtx->cfg_ini;
521 if (NULL == cfg_param)
522 {
523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
524 "cfg_params not available !!");
525 return ;
526 }
527
528 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
529
530 if (!pHddCtx->isVHT80Allowed)
531 {
532 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
533 (eCSR_DOT11_MODE_11ac == phyMode) ||
534 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
535 {
536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
537 "Setting phymode to 11n!!");
538 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
539 }
540 }
541 else
542 {
543 /*New country Supports 11ac as well resetting value back from .ini*/
544 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
545 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
546 return ;
547 }
548
549 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
550 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
551 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
552 {
553 VOS_STATUS vosStatus;
554
555 // need to issue a disconnect to CSR.
556 INIT_COMPLETION(pAdapter->disconnect_comp_var);
557 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
558 pAdapter->sessionId,
559 eCSR_DISCONNECT_REASON_UNSPECIFIED );
560
561 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530562 {
563 long ret;
564
565 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700566 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530567 if (0 >= ret)
568 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
569 ret);
570 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700571
572 }
573}
574#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530575void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
576{
577 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
578 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
579 hdd_config_t *cfg_param;
580 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530581 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530582
583 if (NULL == pHddCtx)
584 {
585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
586 "HDD Context is null !!");
587 return ;
588 }
589
590 cfg_param = pHddCtx->cfg_ini;
591
592 if (NULL == cfg_param)
593 {
594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
595 "cfg_params not available !!");
596 return ;
597 }
598
599 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
600
601 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
602 {
603 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
604 (eCSR_DOT11_MODE_11ac == phyMode) ||
605 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
606 {
607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
608 "Setting phymode to 11n!!");
609 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
610 }
611 }
612 else
613 {
614 /*New country Supports 11ac as well resetting value back from .ini*/
615 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
616 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
617 return ;
618 }
619
620 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
621 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
622 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
623 {
624 VOS_STATUS vosStatus;
625
626 // need to issue a disconnect to CSR.
627 INIT_COMPLETION(pAdapter->disconnect_comp_var);
628 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
629 pAdapter->sessionId,
630 eCSR_DISCONNECT_REASON_UNSPECIFIED );
631
632 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530633 {
634 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530635 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530636 if (ret <= 0)
637 {
638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
639 "wait on disconnect_comp_var is failed %ld", ret);
640 }
641 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530642
643 }
644}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700645#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530646
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700647void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
648{
649 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
650 hdd_config_t *cfg_param;
651
652 if (NULL == pHddCtx)
653 {
654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
655 "HDD Context is null !!");
656 return ;
657 }
658
659 cfg_param = pHddCtx->cfg_ini;
660
661 if (NULL == cfg_param)
662 {
663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
664 "cfg_params not available !!");
665 return ;
666 }
667
Agarwal Ashish738843c2014-09-25 12:27:56 +0530668 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
669 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700670 {
671 /*New country doesn't support DFS */
672 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
673 }
674 else
675 {
676 /*New country Supports DFS as well resetting value back from .ini*/
677 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
678 }
679
680}
681
Rajeev79dbe4c2013-10-05 11:03:42 +0530682#ifdef FEATURE_WLAN_BATCH_SCAN
683
684/**---------------------------------------------------------------------------
685
686 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
687 input string
688
689 This function extracts assigned integer from string in below format:
690 "STRING=10" : extracts integer 10 from this string
691
692 \param - pInPtr Pointer to input string
693 \param - base Base for string to int conversion(10 for decimal 16 for hex)
694 \param - pOutPtr Pointer to variable in which extracted integer needs to be
695 assigned
696 \param - pLastArg to tell whether it is last arguement in input string or
697 not
698
699 \return - NULL for failure cases
700 pointer to next arguement in input string for success cases
701 --------------------------------------------------------------------------*/
702static tANI_U8 *
703hdd_extract_assigned_int_from_str
704(
705 tANI_U8 *pInPtr,
706 tANI_U8 base,
707 tANI_U32 *pOutPtr,
708 tANI_U8 *pLastArg
709)
710{
711 int tempInt;
712 int v = 0;
713 char buf[32];
714 int val = 0;
715 *pLastArg = FALSE;
716
717 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
718 if (NULL == pInPtr)
719 {
720 return NULL;
721 }
722
723 pInPtr++;
724
725 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
726
727 val = sscanf(pInPtr, "%32s ", buf);
728 if (val < 0 && val > strlen(pInPtr))
729 {
730 return NULL;
731 }
732 pInPtr += val;
733 v = kstrtos32(buf, base, &tempInt);
734 if (v < 0)
735 {
736 return NULL;
737 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800738 if (tempInt < 0)
739 {
740 tempInt = 0;
741 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530742 *pOutPtr = tempInt;
743
744 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
745 if (NULL == pInPtr)
746 {
747 *pLastArg = TRUE;
748 return NULL;
749 }
750 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
751
752 return pInPtr;
753}
754
755/**---------------------------------------------------------------------------
756
757 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
758 input string
759
760 This function extracts assigned character from string in below format:
761 "STRING=A" : extracts char 'A' from this string
762
763 \param - pInPtr Pointer to input string
764 \param - pOutPtr Pointer to variable in which extracted char needs to be
765 assigned
766 \param - pLastArg to tell whether it is last arguement in input string or
767 not
768
769 \return - NULL for failure cases
770 pointer to next arguement in input string for success cases
771 --------------------------------------------------------------------------*/
772static tANI_U8 *
773hdd_extract_assigned_char_from_str
774(
775 tANI_U8 *pInPtr,
776 tANI_U8 *pOutPtr,
777 tANI_U8 *pLastArg
778)
779{
780 *pLastArg = FALSE;
781
782 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
783 if (NULL == pInPtr)
784 {
785 return NULL;
786 }
787
788 pInPtr++;
789
790 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
791
792 *pOutPtr = *pInPtr;
793
794 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
795 if (NULL == pInPtr)
796 {
797 *pLastArg = TRUE;
798 return NULL;
799 }
800 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
801
802 return pInPtr;
803}
804
805
806/**---------------------------------------------------------------------------
807
808 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
809
810 This function parses set batch scan command in below format:
811 WLS_BATCHING_SET <space> followed by below arguements
812 "SCANFREQ=XX" : Optional defaults to 30 sec
813 "MSCAN=XX" : Required number of scans to attempt to batch
814 "BESTN=XX" : Best Network (RSSI) defaults to 16
815 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
816 A. implies only 5 GHz , B. implies only 2.4GHz
817 "RTT=X" : optional defaults to 0
818 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
819 error
820
821 For example input commands:
822 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
823 translated into set batch scan with following parameters:
824 a) Frequence 60 seconds
825 b) Batch 10 scans together
826 c) Best RSSI to be 20
827 d) 5GHz band only
828 e) RTT is equal to 0
829
830 \param - pValue Pointer to input channel list
831 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
832
833 \return - 0 for success non-zero for failure
834
835 --------------------------------------------------------------------------*/
836static int
837hdd_parse_set_batchscan_command
838(
839 tANI_U8 *pValue,
840 tSirSetBatchScanReq *pHddSetBatchScanReq
841)
842{
843 tANI_U8 *inPtr = pValue;
844 tANI_U8 val = 0;
845 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800846 tANI_U32 nScanFreq;
847 tANI_U32 nMscan;
848 tANI_U32 nBestN;
849 tANI_U8 ucRfBand;
850 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800851 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530852
853 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800854 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
855 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
856 nRtt = 0;
857 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530858
859 /*go to space after WLS_BATCHING_SET command*/
860 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
861 /*no argument after the command*/
862 if (NULL == inPtr)
863 {
864 return -EINVAL;
865 }
866
867 /*no space after the command*/
868 else if (SPACE_ASCII_VALUE != *inPtr)
869 {
870 return -EINVAL;
871 }
872
873 /*removing empty spaces*/
874 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
875
876 /*no argument followed by spaces*/
877 if ('\0' == *inPtr)
878 {
879 return -EINVAL;
880 }
881
882 /*check and parse SCANFREQ*/
883 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
884 {
885 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800886 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800887
Rajeev Kumarc933d982013-11-18 20:04:20 -0800888 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800889 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800890 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800891 }
892
Rajeev79dbe4c2013-10-05 11:03:42 +0530893 if ( (NULL == inPtr) || (TRUE == lastArg))
894 {
895 return -EINVAL;
896 }
897 }
898
899 /*check and parse MSCAN*/
900 if ((strncmp(inPtr, "MSCAN", 5) == 0))
901 {
902 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800903 &nMscan, &lastArg);
904
905 if (0 == nMscan)
906 {
907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
908 "invalid MSCAN=%d", nMscan);
909 return -EINVAL;
910 }
911
Rajeev79dbe4c2013-10-05 11:03:42 +0530912 if (TRUE == lastArg)
913 {
914 goto done;
915 }
916 else if (NULL == inPtr)
917 {
918 return -EINVAL;
919 }
920 }
921 else
922 {
923 return -EINVAL;
924 }
925
926 /*check and parse BESTN*/
927 if ((strncmp(inPtr, "BESTN", 5) == 0))
928 {
929 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800930 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800931
Rajeev Kumarc933d982013-11-18 20:04:20 -0800932 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800933 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800934 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800935 }
936
Rajeev79dbe4c2013-10-05 11:03:42 +0530937 if (TRUE == lastArg)
938 {
939 goto done;
940 }
941 else if (NULL == inPtr)
942 {
943 return -EINVAL;
944 }
945 }
946
947 /*check and parse CHANNEL*/
948 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
949 {
950 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800951
Rajeev79dbe4c2013-10-05 11:03:42 +0530952 if (('A' == val) || ('a' == val))
953 {
c_hpothuebf89732014-02-25 13:00:24 +0530954 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530955 }
956 else if (('B' == val) || ('b' == val))
957 {
c_hpothuebf89732014-02-25 13:00:24 +0530958 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530959 }
960 else
961 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800962 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
963 }
964
965 if (TRUE == lastArg)
966 {
967 goto done;
968 }
969 else if (NULL == inPtr)
970 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530971 return -EINVAL;
972 }
973 }
974
975 /*check and parse RTT*/
976 if ((strncmp(inPtr, "RTT", 3) == 0))
977 {
978 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800979 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530980 if (TRUE == lastArg)
981 {
982 goto done;
983 }
984 if (NULL == inPtr)
985 {
986 return -EINVAL;
987 }
988 }
989
990
991done:
992
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800993 pHddSetBatchScanReq->scanFrequency = nScanFreq;
994 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
995 pHddSetBatchScanReq->bestNetwork = nBestN;
996 pHddSetBatchScanReq->rfBand = ucRfBand;
997 pHddSetBatchScanReq->rtt = nRtt;
998
Rajeev79dbe4c2013-10-05 11:03:42 +0530999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1000 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1001 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1002 pHddSetBatchScanReq->scanFrequency,
1003 pHddSetBatchScanReq->numberOfScansToBatch,
1004 pHddSetBatchScanReq->bestNetwork,
1005 pHddSetBatchScanReq->rfBand,
1006 pHddSetBatchScanReq->rtt);
1007
1008 return 0;
1009}/*End of hdd_parse_set_batchscan_command*/
1010
1011/**---------------------------------------------------------------------------
1012
1013 \brief hdd_set_batch_scan_req_callback () - This function is called after
1014 receiving set batch scan response from FW and it saves set batch scan
1015 response data FW to HDD context and sets the completion event on
1016 which hdd_ioctl is waiting
1017
1018 \param - callbackContext Pointer to HDD adapter
1019 \param - pRsp Pointer to set batch scan response data received from FW
1020
1021 \return - nothing
1022
1023 --------------------------------------------------------------------------*/
1024static void hdd_set_batch_scan_req_callback
1025(
1026 void *callbackContext,
1027 tSirSetBatchScanRsp *pRsp
1028)
1029{
1030 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1031 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1032
1033 /*sanity check*/
1034 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1035 {
1036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1037 "%s: Invalid pAdapter magic", __func__);
1038 VOS_ASSERT(0);
1039 return;
1040 }
1041 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1042
1043 /*save set batch scan response*/
1044 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1045
1046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1047 "Received set batch scan rsp from FW with nScansToBatch=%d",
1048 pHddSetBatchScanRsp->nScansToBatch);
1049
1050 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1051 complete(&pAdapter->hdd_set_batch_scan_req_var);
1052
1053 return;
1054}/*End of hdd_set_batch_scan_req_callback*/
1055
1056
1057/**---------------------------------------------------------------------------
1058
1059 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1060 info in hdd batch scan response queue
1061
1062 \param - pAdapter Pointer to hdd adapter
1063 \param - pAPMetaInfo Pointer to access point meta info
1064 \param - scanId scan ID of batch scan response
1065 \param - isLastAp tells whether AP is last AP in batch scan response or not
1066
1067 \return - nothing
1068
1069 --------------------------------------------------------------------------*/
1070static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1071 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1072{
1073 tHddBatchScanRsp *pHead;
1074 tHddBatchScanRsp *pNode;
1075 tHddBatchScanRsp *pPrev;
1076 tHddBatchScanRsp *pTemp;
1077 tANI_U8 ssidLen;
1078
1079 /*head of hdd batch scan response queue*/
1080 pHead = pAdapter->pBatchScanRsp;
1081
1082 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1083 if (NULL == pNode)
1084 {
1085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1086 "%s: Could not allocate memory", __func__);
1087 VOS_ASSERT(0);
1088 return;
1089 }
1090
1091 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1092 sizeof(pNode->ApInfo.bssid));
1093 ssidLen = strlen(pApMetaInfo->ssid);
1094 if (SIR_MAX_SSID_SIZE < ssidLen)
1095 {
1096 /*invalid scan result*/
1097 vos_mem_free(pNode);
1098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1099 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1100 return;
1101 }
1102 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1103 /*null terminate ssid*/
1104 pNode->ApInfo.ssid[ssidLen] = '\0';
1105 pNode->ApInfo.ch = pApMetaInfo->ch;
1106 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1107 pNode->ApInfo.age = pApMetaInfo->timestamp;
1108 pNode->ApInfo.batchId = scanId;
1109 pNode->ApInfo.isLastAp = isLastAp;
1110
1111 pNode->pNext = NULL;
1112 if (NULL == pHead)
1113 {
1114 pAdapter->pBatchScanRsp = pNode;
1115 }
1116 else
1117 {
1118 pTemp = pHead;
1119 while (NULL != pTemp)
1120 {
1121 pPrev = pTemp;
1122 pTemp = pTemp->pNext;
1123 }
1124 pPrev->pNext = pNode;
1125 }
1126
1127 return;
1128}/*End of hdd_populate_batch_scan_rsp_queue*/
1129
1130/**---------------------------------------------------------------------------
1131
1132 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1133 receiving batch scan response indication from FW. It saves get batch scan
1134 response data in HDD batch scan response queue. This callback sets the
1135 completion event on which hdd_ioctl is waiting only after getting complete
1136 batch scan response data from FW
1137
1138 \param - callbackContext Pointer to HDD adapter
1139 \param - pRsp Pointer to get batch scan response data received from FW
1140
1141 \return - nothing
1142
1143 --------------------------------------------------------------------------*/
1144static void hdd_batch_scan_result_ind_callback
1145(
1146 void *callbackContext,
1147 void *pRsp
1148)
1149{
1150 v_BOOL_t isLastAp;
1151 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001152 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301153 tANI_U32 numberScanList;
1154 tANI_U32 nextScanListOffset;
1155 tANI_U32 nextApMetaInfoOffset;
1156 hdd_adapter_t* pAdapter;
1157 tpSirBatchScanList pScanList;
1158 tpSirBatchScanNetworkInfo pApMetaInfo;
1159 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1160 tSirSetBatchScanReq *pReq;
1161
1162 pAdapter = (hdd_adapter_t *)callbackContext;
1163 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001164 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301165 {
1166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1167 "%s: Invalid pAdapter magic", __func__);
1168 VOS_ASSERT(0);
1169 return;
1170 }
1171
1172 /*initialize locals*/
1173 pReq = &pAdapter->hddSetBatchScanReq;
1174 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1175 isLastAp = FALSE;
1176 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001177 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301178 numberScanList = 0;
1179 nextScanListOffset = 0;
1180 nextApMetaInfoOffset = 0;
1181 pScanList = NULL;
1182 pApMetaInfo = NULL;
1183
1184 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1185 {
1186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1187 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1188 isLastAp = TRUE;
1189 goto done;
1190 }
1191
1192 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1194 "Batch scan rsp: numberScalList %d", numberScanList);
1195
1196 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1197 {
1198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1199 "%s: numberScanList %d", __func__, numberScanList);
1200 isLastAp = TRUE;
1201 goto done;
1202 }
1203
1204 while (numberScanList)
1205 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001206 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301207 nextScanListOffset);
1208 if (NULL == pScanList)
1209 {
1210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1211 "%s: pScanList is %p", __func__, pScanList);
1212 isLastAp = TRUE;
1213 goto done;
1214 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001215 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001217 "Batch scan rsp: numApMetaInfo %d scanId %d",
1218 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301219
1220 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1221 {
1222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1223 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1224 isLastAp = TRUE;
1225 goto done;
1226 }
1227
Rajeev Kumarce651e42013-10-21 18:57:15 -07001228 /*Initialize next AP meta info offset for next scan list*/
1229 nextApMetaInfoOffset = 0;
1230
Rajeev79dbe4c2013-10-05 11:03:42 +05301231 while (numApMetaInfo)
1232 {
1233 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1234 nextApMetaInfoOffset);
1235 if (NULL == pApMetaInfo)
1236 {
1237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1238 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1239 isLastAp = TRUE;
1240 goto done;
1241 }
1242 /*calculate AP age*/
1243 pApMetaInfo->timestamp =
1244 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1245
1246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001247 "%s: bssId "MAC_ADDRESS_STR
1248 " ch %d rssi %d timestamp %d", __func__,
1249 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1250 pApMetaInfo->ch, pApMetaInfo->rssi,
1251 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301252
1253 /*mark last AP in batch scan response*/
1254 if ((TRUE == pBatchScanRsp->isLastResult) &&
1255 (1 == numberScanList) && (1 == numApMetaInfo))
1256 {
1257 isLastAp = TRUE;
1258 }
1259
1260 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1261 /*store batch scan repsonse in hdd queue*/
1262 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1263 pScanList->scanId, isLastAp);
1264 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1265
1266 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1267 numApMetaInfo--;
1268 }
1269
Rajeev Kumarce651e42013-10-21 18:57:15 -07001270 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1271 + (sizeof(tSirBatchScanNetworkInfo)
1272 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301273 numberScanList--;
1274 }
1275
1276done:
1277
1278 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1279 requested from hdd_ioctl*/
1280 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1281 (TRUE == isLastAp))
1282 {
1283 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1284 complete(&pAdapter->hdd_get_batch_scan_req_var);
1285 }
1286
1287 return;
1288}/*End of hdd_batch_scan_result_ind_callback*/
1289
1290/**---------------------------------------------------------------------------
1291
1292 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1293 response as per batch scan FR request format by putting proper markers
1294
1295 \param - pDest pointer to destination buffer
1296 \param - cur_len current length
1297 \param - tot_len total remaining size which can be written to user space
1298 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1299 \param - pAdapter Pointer to HDD adapter
1300
1301 \return - ret no of characters written
1302
1303 --------------------------------------------------------------------------*/
1304static tANI_U32
1305hdd_format_batch_scan_rsp
1306(
1307 tANI_U8 *pDest,
1308 tANI_U32 cur_len,
1309 tANI_U32 tot_len,
1310 tHddBatchScanRsp *pApMetaInfo,
1311 hdd_adapter_t* pAdapter
1312)
1313{
1314 tANI_U32 ret = 0;
1315 tANI_U32 rem_len = 0;
1316 tANI_U8 temp_len = 0;
1317 tANI_U8 temp_total_len = 0;
1318 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1319 tANI_U8 *pTemp = temp;
1320
1321 /*Batch scan reponse needs to be returned to user space in
1322 following format:
1323 "scancount=X\n" where X is the number of scans in current batch
1324 batch
1325 "trunc\n" optional present if current scan truncated
1326 "bssid=XX:XX:XX:XX:XX:XX\n"
1327 "ssid=XXXX\n"
1328 "freq=X\n" frequency in Mhz
1329 "level=XX\n"
1330 "age=X\n" ms
1331 "dist=X\n" cm (-1 if not available)
1332 "errror=X\n" (-1if not available)
1333 "====\n" (end of ap marker)
1334 "####\n" (end of scan marker)
1335 "----\n" (end of results)*/
1336 /*send scan result in above format to user space based on
1337 available length*/
1338 /*The GET response may have more data than the driver can return in its
1339 buffer. In that case the buffer should be filled to the nearest complete
1340 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1341 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1342 The final buffer should end with "----\n"*/
1343
1344 /*sanity*/
1345 if (cur_len > tot_len)
1346 {
1347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1348 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1349 return 0;
1350 }
1351 else
1352 {
1353 rem_len = (tot_len - cur_len);
1354 }
1355
1356 /*end scan marker*/
1357 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1358 {
1359 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1360 pTemp += temp_len;
1361 temp_total_len += temp_len;
1362 }
1363
1364 /*bssid*/
1365 temp_len = snprintf(pTemp, sizeof(temp),
1366 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1367 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1368 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1369 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1370 pTemp += temp_len;
1371 temp_total_len += temp_len;
1372
1373 /*ssid*/
1374 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1375 pApMetaInfo->ApInfo.ssid);
1376 pTemp += temp_len;
1377 temp_total_len += temp_len;
1378
1379 /*freq*/
1380 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001381 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301382 pTemp += temp_len;
1383 temp_total_len += temp_len;
1384
1385 /*level*/
1386 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1387 pApMetaInfo->ApInfo.rssi);
1388 pTemp += temp_len;
1389 temp_total_len += temp_len;
1390
1391 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001392 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301393 pApMetaInfo->ApInfo.age);
1394 pTemp += temp_len;
1395 temp_total_len += temp_len;
1396
1397 /*dist*/
1398 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1399 pTemp += temp_len;
1400 temp_total_len += temp_len;
1401
1402 /*error*/
1403 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1404 pTemp += temp_len;
1405 temp_total_len += temp_len;
1406
1407 /*end AP marker*/
1408 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1409 pTemp += temp_len;
1410 temp_total_len += temp_len;
1411
1412 /*last AP in batch scan response*/
1413 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1414 {
1415 /*end scan marker*/
1416 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1417 pTemp += temp_len;
1418 temp_total_len += temp_len;
1419
1420 /*end batch scan result marker*/
1421 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1422 pTemp += temp_len;
1423 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001424
Rajeev79dbe4c2013-10-05 11:03:42 +05301425 }
1426
1427 if (temp_total_len < rem_len)
1428 {
1429 ret = temp_total_len + 1;
1430 strlcpy(pDest, temp, ret);
1431 pAdapter->isTruncated = FALSE;
1432 }
1433 else
1434 {
1435 pAdapter->isTruncated = TRUE;
1436 if (rem_len >= strlen("%%%%"))
1437 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001438 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301439 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001440 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301441 {
1442 ret = 0;
1443 }
1444 }
1445
1446 return ret;
1447
1448}/*End of hdd_format_batch_scan_rsp*/
1449
1450/**---------------------------------------------------------------------------
1451
1452 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1453 buffer starting with head of hdd batch scan response queue
1454
1455 \param - pAdapter Pointer to HDD adapter
1456 \param - pDest Pointer to user data buffer
1457 \param - cur_len current offset in user buffer
1458 \param - rem_len remaining no of bytes in user buffer
1459
1460 \return - number of bytes written in user buffer
1461
1462 --------------------------------------------------------------------------*/
1463
1464tANI_U32 hdd_populate_user_batch_scan_rsp
1465(
1466 hdd_adapter_t* pAdapter,
1467 tANI_U8 *pDest,
1468 tANI_U32 cur_len,
1469 tANI_U32 rem_len
1470)
1471{
1472 tHddBatchScanRsp *pHead;
1473 tHddBatchScanRsp *pPrev;
1474 tANI_U32 len;
1475
Rajeev79dbe4c2013-10-05 11:03:42 +05301476 pAdapter->isTruncated = FALSE;
1477
1478 /*head of hdd batch scan response queue*/
1479 pHead = pAdapter->pBatchScanRsp;
1480 while (pHead)
1481 {
1482 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1483 pAdapter);
1484 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001485 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301486 cur_len += len;
1487 if(TRUE == pAdapter->isTruncated)
1488 {
1489 /*result is truncated return rest of scan rsp in next req*/
1490 cur_len = rem_len;
1491 break;
1492 }
1493 pPrev = pHead;
1494 pHead = pHead->pNext;
1495 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001496 if (TRUE == pPrev->ApInfo.isLastAp)
1497 {
1498 pAdapter->prev_batch_id = 0;
1499 }
1500 else
1501 {
1502 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1503 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301504 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001505 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301506 }
1507
1508 return cur_len;
1509}/*End of hdd_populate_user_batch_scan_rsp*/
1510
1511/**---------------------------------------------------------------------------
1512
1513 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1514 scan response data from HDD queue to user space
1515 It does following in detail:
1516 a) if HDD has enough data in its queue then it 1st copies data to user
1517 space and then send get batch scan indication message to FW. In this
1518 case it does not wait on any event and batch scan response data will
1519 be populated in HDD response queue in MC thread context after receiving
1520 indication from FW
1521 b) else send get batch scan indication message to FW and wait on an event
1522 which will be set once HDD receives complete batch scan response from
1523 FW and then this function returns batch scan response to user space
1524
1525 \param - pAdapter Pointer to HDD adapter
1526 \param - pPrivData Pointer to priv_data
1527
1528 \return - 0 for success -EFAULT for failure
1529
1530 --------------------------------------------------------------------------*/
1531
1532int hdd_return_batch_scan_rsp_to_user
1533(
1534 hdd_adapter_t* pAdapter,
1535 hdd_priv_data_t *pPrivData,
1536 tANI_U8 *command
1537)
1538{
1539 tANI_U8 *pDest;
1540 tANI_U32 count = 0;
1541 tANI_U32 len = 0;
1542 tANI_U32 cur_len = 0;
1543 tANI_U32 rem_len = 0;
1544 eHalStatus halStatus;
1545 unsigned long rc;
1546 tSirTriggerBatchScanResultInd *pReq;
1547
1548 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1549 pReq->param = 0;/*batch scan client*/
1550 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1551 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1552
1553 cur_len = pPrivData->used_len;
1554 if (pPrivData->total_len > pPrivData->used_len)
1555 {
1556 rem_len = pPrivData->total_len - pPrivData->used_len;
1557 }
1558 else
1559 {
1560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1561 "%s: Invalid user data buffer total_len %d used_len %d",
1562 __func__, pPrivData->total_len, pPrivData->used_len);
1563 return -EFAULT;
1564 }
1565
1566 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1567 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1568 cur_len, rem_len);
1569 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1570
1571 /*enough scan result available in cache to return to user space or
1572 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001573 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301574 {
1575 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1576 halStatus = sme_TriggerBatchScanResultInd(
1577 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1578 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1579 pAdapter);
1580 if ( eHAL_STATUS_SUCCESS == halStatus )
1581 {
1582 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1583 {
1584 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1585 rc = wait_for_completion_timeout(
1586 &pAdapter->hdd_get_batch_scan_req_var,
1587 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1588 if (0 == rc)
1589 {
1590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1591 "%s: Timeout waiting to fetch batch scan rsp from fw",
1592 __func__);
1593 return -EFAULT;
1594 }
1595 }
1596
1597 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001598 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301599 pDest += len;
1600 cur_len += len;
1601
1602 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1603 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1604 cur_len, rem_len);
1605 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1606
1607 count = 0;
1608 len = (len - pPrivData->used_len);
1609 pDest = (command + pPrivData->used_len);
1610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001611 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301612 while(count < len)
1613 {
1614 printk("%c", *(pDest + count));
1615 count++;
1616 }
1617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1618 "%s: copy %d data to user buffer", __func__, len);
1619 if (copy_to_user(pPrivData->buf, pDest, len))
1620 {
1621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1622 "%s: failed to copy data to user buffer", __func__);
1623 return -EFAULT;
1624 }
1625 }
1626 else
1627 {
1628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1629 "sme_GetBatchScanScan returned failure halStatus %d",
1630 halStatus);
1631 return -EINVAL;
1632 }
1633 }
1634 else
1635 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301636 count = 0;
1637 len = (len - pPrivData->used_len);
1638 pDest = (command + pPrivData->used_len);
1639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001640 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301641 while(count < len)
1642 {
1643 printk("%c", *(pDest + count));
1644 count++;
1645 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1647 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301648 if (copy_to_user(pPrivData->buf, pDest, len))
1649 {
1650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1651 "%s: failed to copy data to user buffer", __func__);
1652 return -EFAULT;
1653 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301654 }
1655
1656 return 0;
1657} /*End of hdd_return_batch_scan_rsp_to_user*/
1658
Rajeev Kumar8b373292014-01-08 20:36:55 -08001659
1660/**---------------------------------------------------------------------------
1661
1662 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1663 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1664 WLS_BATCHING VERSION
1665 WLS_BATCHING SET
1666 WLS_BATCHING GET
1667 WLS_BATCHING STOP
1668
1669 \param - pAdapter Pointer to HDD adapter
1670 \param - pPrivdata Pointer to priv_data
1671 \param - command Pointer to command
1672
1673 \return - 0 for success -EFAULT for failure
1674
1675 --------------------------------------------------------------------------*/
1676
1677int hdd_handle_batch_scan_ioctl
1678(
1679 hdd_adapter_t *pAdapter,
1680 hdd_priv_data_t *pPrivdata,
1681 tANI_U8 *command
1682)
1683{
1684 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001685 hdd_context_t *pHddCtx;
1686
1687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1688 ret = wlan_hdd_validate_context(pHddCtx);
1689 if (ret)
1690 {
1691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1692 "%s: HDD context is not valid!", __func__);
1693 goto exit;
1694 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001695
1696 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1697 {
1698 char extra[32];
1699 tANI_U8 len = 0;
1700 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1701
1702 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1703 {
1704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1705 "%s: Batch scan feature is not supported by FW", __func__);
1706 ret = -EINVAL;
1707 goto exit;
1708 }
1709
1710 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1711 version);
1712 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1713 {
1714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1715 "%s: failed to copy data to user buffer", __func__);
1716 ret = -EFAULT;
1717 goto exit;
1718 }
1719 ret = HDD_BATCH_SCAN_VERSION;
1720 }
1721 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1722 {
1723 int status;
1724 tANI_U8 *value = (command + 16);
1725 eHalStatus halStatus;
1726 unsigned long rc;
1727 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1728 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1729
1730 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1731 {
1732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1733 "%s: Batch scan feature is not supported by FW", __func__);
1734 ret = -EINVAL;
1735 goto exit;
1736 }
1737
1738 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1739 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1740 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1741 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1742 {
1743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301744 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001745 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301746 hdd_device_modetoString(pAdapter->device_mode),
1747 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001748 ret = -EINVAL;
1749 goto exit;
1750 }
1751
1752 status = hdd_parse_set_batchscan_command(value, pReq);
1753 if (status)
1754 {
1755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1756 "Invalid WLS_BATCHING SET command");
1757 ret = -EINVAL;
1758 goto exit;
1759 }
1760
1761
1762 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1763 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1764 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1765 pAdapter);
1766
1767 if ( eHAL_STATUS_SUCCESS == halStatus )
1768 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301769 char extra[32];
1770 tANI_U8 len = 0;
1771 tANI_U8 mScan = 0;
1772
Rajeev Kumar8b373292014-01-08 20:36:55 -08001773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1774 "sme_SetBatchScanReq returned success halStatus %d",
1775 halStatus);
1776 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1777 {
1778 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1779 rc = wait_for_completion_timeout(
1780 &pAdapter->hdd_set_batch_scan_req_var,
1781 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1782 if (0 == rc)
1783 {
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1785 "%s: Timeout waiting for set batch scan to complete",
1786 __func__);
1787 ret = -EINVAL;
1788 goto exit;
1789 }
1790 }
1791 if ( !pRsp->nScansToBatch )
1792 {
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1794 "%s: Received set batch scan failure response from FW",
1795 __func__);
1796 ret = -EINVAL;
1797 goto exit;
1798 }
1799 /*As per the Batch Scan Framework API we should return the MIN of
1800 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301801 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001802
1803 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1804
1805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1806 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301807 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1808 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1809 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1810 {
1811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1812 "%s: failed to copy MSCAN value to user buffer", __func__);
1813 ret = -EFAULT;
1814 goto exit;
1815 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001816 }
1817 else
1818 {
1819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "sme_SetBatchScanReq returned failure halStatus %d",
1821 halStatus);
1822 ret = -EINVAL;
1823 goto exit;
1824 }
1825 }
1826 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1827 {
1828 eHalStatus halStatus;
1829 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1830 pInd->param = 0;
1831
1832 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1833 {
1834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1835 "%s: Batch scan feature is not supported by FW", __func__);
1836 ret = -EINVAL;
1837 goto exit;
1838 }
1839
1840 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1841 {
1842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1843 "Batch scan is not yet enabled batch scan state %d",
1844 pAdapter->batchScanState);
1845 ret = -EINVAL;
1846 goto exit;
1847 }
1848
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001849 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1850 hdd_deinit_batch_scan(pAdapter);
1851 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1852
Rajeev Kumar8b373292014-01-08 20:36:55 -08001853 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1854
1855 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1856 pAdapter->sessionId);
1857 if ( eHAL_STATUS_SUCCESS == halStatus )
1858 {
1859 ret = 0;
1860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1861 "sme_StopBatchScanInd returned success halStatus %d",
1862 halStatus);
1863 }
1864 else
1865 {
1866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1867 "sme_StopBatchScanInd returned failure halStatus %d",
1868 halStatus);
1869 ret = -EINVAL;
1870 goto exit;
1871 }
1872 }
1873 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1874 {
1875 tANI_U32 remain_len;
1876
1877 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1878 {
1879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1880 "%s: Batch scan feature is not supported by FW", __func__);
1881 ret = -EINVAL;
1882 goto exit;
1883 }
1884
1885 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1886 {
1887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1888 "Batch scan is not yet enabled could not return results"
1889 "Batch Scan state %d",
1890 pAdapter->batchScanState);
1891 ret = -EINVAL;
1892 goto exit;
1893 }
1894
1895 pPrivdata->used_len = 16;
1896 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1897 if (remain_len < pPrivdata->total_len)
1898 {
1899 /*Clear previous batch scan response data if any*/
1900 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1901 }
1902 else
1903 {
1904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1905 "Invalid total length from user space can't fetch batch"
1906 " scan response total_len %d used_len %d remain len %d",
1907 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1908 ret = -EINVAL;
1909 goto exit;
1910 }
1911 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1912 }
1913
1914exit:
1915
1916 return ret;
1917}
1918
1919
Rajeev79dbe4c2013-10-05 11:03:42 +05301920#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1921
c_hpothu92367912014-05-01 15:18:17 +05301922static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1923{
c_hpothu39eb1e32014-06-26 16:31:50 +05301924 bcnMissRateContext_t *pCBCtx;
1925
1926 if (NULL == data)
1927 {
1928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1929 return;
1930 }
c_hpothu92367912014-05-01 15:18:17 +05301931
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
c_hpothu39eb1e32014-06-26 16:31:50 +05301938 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301939 gbcnMissRate = -1;
1940
c_hpothu39eb1e32014-06-26 16:31:50 +05301941 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301942 {
1943 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301944 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301945 spin_unlock(&hdd_context_lock);
1946 return ;
1947 }
1948
1949 if (VOS_STATUS_SUCCESS == status)
1950 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301951 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301952 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301953 else
1954 {
1955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1956 }
1957
c_hpothu92367912014-05-01 15:18:17 +05301958 complete(&(pCBCtx->completion));
1959 spin_unlock(&hdd_context_lock);
1960
1961 return;
1962}
1963
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05301964static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
1965{
1966 int ret = 0;
1967
1968 if (!pCfg || !command || !extra || !len)
1969 {
1970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1971 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
1972 ret = -EINVAL;
1973 return ret;
1974 }
1975
1976 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
1977 {
1978 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
1979 (int)pCfg->nActiveMaxChnTime);
1980 return ret;
1981 }
1982 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
1983 {
1984 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
1985 (int)pCfg->nActiveMinChnTime);
1986 return ret;
1987 }
1988 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
1989 {
1990 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
1991 (int)pCfg->nPassiveMaxChnTime);
1992 return ret;
1993 }
1994 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
1995 {
1996 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
1997 (int)pCfg->nPassiveMinChnTime);
1998 return ret;
1999 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302000 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2001 {
2002 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2003 (int)pCfg->nActiveMaxChnTime);
2004 return ret;
2005 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302006 else
2007 {
2008 ret = -EINVAL;
2009 }
2010
2011 return ret;
2012}
2013
2014static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2015{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302016 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302017 hdd_config_t *pCfg;
2018 tANI_U8 *value = command;
2019 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302020 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302021
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302022 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2023 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302024 {
2025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2026 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2027 ret = -EINVAL;
2028 return ret;
2029 }
2030
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302031 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2032 sme_GetConfigParam(hHal, &smeConfig);
2033
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302034 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2035 {
2036 value = value + 24;
2037 temp = kstrtou32(value, 10, &val);
2038 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2039 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2040 {
2041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2042 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2043 ret = -EFAULT;
2044 return ret;
2045 }
2046 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302047 smeConfig.csrConfig.nActiveMaxChnTime = val;
2048 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302049 }
2050 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2051 {
2052 value = value + 24;
2053 temp = kstrtou32(value, 10, &val);
2054 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2055 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2056 {
2057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2058 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2059 ret = -EFAULT;
2060 return ret;
2061 }
2062 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302063 smeConfig.csrConfig.nActiveMinChnTime = val;
2064 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302065 }
2066 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2067 {
2068 value = value + 25;
2069 temp = kstrtou32(value, 10, &val);
2070 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2071 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2072 {
2073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2074 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2075 ret = -EFAULT;
2076 return ret;
2077 }
2078 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302079 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2080 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302081 }
2082 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2083 {
2084 value = value + 25;
2085 temp = kstrtou32(value, 10, &val);
2086 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2087 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2088 {
2089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2090 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2091 ret = -EFAULT;
2092 return ret;
2093 }
2094 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302095 smeConfig.csrConfig.nPassiveMinChnTime = val;
2096 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302097 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302098 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2099 {
2100 value = value + 13;
2101 temp = kstrtou32(value, 10, &val);
2102 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2103 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2104 {
2105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2106 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2107 ret = -EFAULT;
2108 return ret;
2109 }
2110 pCfg->nActiveMaxChnTime = val;
2111 smeConfig.csrConfig.nActiveMaxChnTime = val;
2112 sme_UpdateConfig(hHal, &smeConfig);
2113 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302114 else
2115 {
2116 ret = -EINVAL;
2117 }
2118
2119 return ret;
2120}
2121
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002122static int hdd_driver_command(hdd_adapter_t *pAdapter,
2123 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002124{
Jeff Johnson295189b2012-06-20 16:38:30 -07002125 hdd_priv_data_t priv_data;
2126 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302127 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2128 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002129 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302130 int status;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002131 /*
2132 * Note that valid pointers are provided by caller
2133 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002134
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002135 /* copy to local struct to avoid numerous changes to legacy code */
2136 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002137
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002138 if (priv_data.total_len <= 0 ||
2139 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002140 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002141 hddLog(VOS_TRACE_LEVEL_WARN,
2142 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2143 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002144 ret = -EINVAL;
2145 goto exit;
2146 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302147 status = wlan_hdd_validate_context(pHddCtx);
2148 if (0 != status)
2149 {
2150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2151 "%s: HDD context is not valid", __func__);
2152 return status;
2153 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002154 /* Allocate +1 for '\0' */
2155 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002156 if (!command)
2157 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002158 hddLog(VOS_TRACE_LEVEL_ERROR,
2159 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002160 ret = -ENOMEM;
2161 goto exit;
2162 }
2163
2164 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2165 {
2166 ret = -EFAULT;
2167 goto exit;
2168 }
2169
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002170 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002171 command[priv_data.total_len] = '\0';
2172
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002173 /* at one time the following block of code was conditional. braces
2174 * have been retained to avoid re-indenting the legacy code
2175 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002176 {
2177 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2178
2179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002180 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002181
2182 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2183 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302184 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2185 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2186 pAdapter->sessionId, (unsigned)
2187 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2188 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2189 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2190 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002191 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2192 sizeof(tSirMacAddr)))
2193 {
2194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002195 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002196 ret = -EFAULT;
2197 }
2198 }
Amar Singhal0974e402013-02-12 14:27:46 -08002199 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 {
Amar Singhal0974e402013-02-12 14:27:46 -08002201 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002202
Jeff Johnson295189b2012-06-20 16:38:30 -07002203 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002204
2205 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002206 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002208 "%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 -07002209 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002210 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302211 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302212 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002213 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002214 }
Kiet Lamf040f472013-11-20 21:15:23 +05302215 else if(strncmp(command, "SETWMMPS", 8) == 0)
2216 {
2217 tANI_U8 *ptr = command;
2218 ret = hdd_wmmps_helper(pAdapter, ptr);
2219 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002220 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2221 {
2222 char *country_code;
2223
2224 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002225
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002226 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002227 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002228#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302229 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002230#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002231 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2232 (void *)(tSmeChangeCountryCallback)
2233 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302234 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002235 if (eHAL_STATUS_SUCCESS == ret)
2236 {
2237 ret = wait_for_completion_interruptible_timeout(
2238 &pAdapter->change_country_code,
2239 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2240 if (0 >= ret)
2241 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302243 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002244 }
2245 }
2246 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002247 {
2248 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002249 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002250 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002251 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002252
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002253 }
2254 /*
2255 command should be a string having format
2256 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2257 */
Amar Singhal0974e402013-02-12 14:27:46 -08002258 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002259 {
Amar Singhal0974e402013-02-12 14:27:46 -08002260 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002261
2262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002263 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002264
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002265 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002266 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002267 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2268 {
2269 int suspend = 0;
2270 tANI_U8 *ptr = (tANI_U8*)command + 15;
2271
2272 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302273 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2274 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2275 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002276 hdd_set_wlan_suspend_mode(suspend);
2277 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002278#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2279 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2280 {
2281 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002282 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002283 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2284 eHalStatus status = eHAL_STATUS_SUCCESS;
2285
2286 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2287 value = value + 15;
2288
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002289 /* Convert the value from ascii to integer */
2290 ret = kstrtos8(value, 10, &rssi);
2291 if (ret < 0)
2292 {
2293 /* If the input value is greater than max value of datatype, then also
2294 kstrtou8 fails */
2295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2296 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002297 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002298 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2299 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2300 ret = -EINVAL;
2301 goto exit;
2302 }
2303
Srinivas Girigowdade697412013-02-14 16:31:48 -08002304 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002305
Srinivas Girigowdade697412013-02-14 16:31:48 -08002306 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2307 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2308 {
2309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2310 "Neighbor lookup threshold value %d is out of range"
2311 " (Min: %d Max: %d)", lookUpThreshold,
2312 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2313 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2314 ret = -EINVAL;
2315 goto exit;
2316 }
2317
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302318 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2319 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2320 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2322 "%s: Received Command to Set Roam trigger"
2323 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2324
2325 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2326 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2327 if (eHAL_STATUS_SUCCESS != status)
2328 {
2329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2330 "%s: Failed to set roam trigger, try again", __func__);
2331 ret = -EPERM;
2332 goto exit;
2333 }
2334
2335 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302336 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002337 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2338 }
2339 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2340 {
2341 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2342 int rssi = (-1) * lookUpThreshold;
2343 char extra[32];
2344 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302345 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2346 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2347 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002348 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002349 if (copy_to_user(priv_data.buf, &extra, len + 1))
2350 {
2351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2352 "%s: failed to copy data to user buffer", __func__);
2353 ret = -EFAULT;
2354 goto exit;
2355 }
2356 }
2357 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2358 {
2359 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002360 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002361 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002362
Srinivas Girigowdade697412013-02-14 16:31:48 -08002363 /* input refresh period is in terms of seconds */
2364 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2365 value = value + 18;
2366 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002367 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002368 if (ret < 0)
2369 {
2370 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002371 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002373 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002374 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002375 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2376 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002377 ret = -EINVAL;
2378 goto exit;
2379 }
2380
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002381 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2382 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002383 {
2384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002385 "Roam scan period value %d is out of range"
2386 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002387 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2388 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002389 ret = -EINVAL;
2390 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302391 }
2392 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2393 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2394 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002395 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002396
2397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2398 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002399 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002400
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002401 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2402 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002403 }
2404 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2405 {
2406 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2407 char extra[32];
2408 tANI_U8 len = 0;
2409
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302410 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2411 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2412 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002413 len = scnprintf(extra, sizeof(extra), "%s %d",
2414 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002415 /* Returned value is in units of seconds */
2416 if (copy_to_user(priv_data.buf, &extra, len + 1))
2417 {
2418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2419 "%s: failed to copy data to user buffer", __func__);
2420 ret = -EFAULT;
2421 goto exit;
2422 }
2423 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002424 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2425 {
2426 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002427 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002428 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002429
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002430 /* input refresh period is in terms of seconds */
2431 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2432 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002433
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002434 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002435 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002436 if (ret < 0)
2437 {
2438 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002439 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002441 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002442 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002443 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2444 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2445 ret = -EINVAL;
2446 goto exit;
2447 }
2448
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002449 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2450 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2451 {
2452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2453 "Neighbor scan results refresh period value %d is out of range"
2454 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2455 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2456 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2457 ret = -EINVAL;
2458 goto exit;
2459 }
2460 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2461
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2463 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002464 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002465
2466 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2467 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2468 }
2469 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2470 {
2471 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2472 char extra[32];
2473 tANI_U8 len = 0;
2474
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002475 len = scnprintf(extra, sizeof(extra), "%s %d",
2476 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002477 /* Returned value is in units of seconds */
2478 if (copy_to_user(priv_data.buf, &extra, len + 1))
2479 {
2480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2481 "%s: failed to copy data to user buffer", __func__);
2482 ret = -EFAULT;
2483 goto exit;
2484 }
2485 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002486#ifdef FEATURE_WLAN_LFR
2487 /* SETROAMMODE */
2488 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2489 {
2490 tANI_U8 *value = command;
2491 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2492
2493 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2494 value = value + SIZE_OF_SETROAMMODE + 1;
2495
2496 /* Convert the value from ascii to integer */
2497 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2498 if (ret < 0)
2499 {
2500 /* If the input value is greater than max value of datatype, then also
2501 kstrtou8 fails */
2502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2503 "%s: kstrtou8 failed range [%d - %d]", __func__,
2504 CFG_LFR_FEATURE_ENABLED_MIN,
2505 CFG_LFR_FEATURE_ENABLED_MAX);
2506 ret = -EINVAL;
2507 goto exit;
2508 }
2509 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2510 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2511 {
2512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2513 "Roam Mode value %d is out of range"
2514 " (Min: %d Max: %d)", roamMode,
2515 CFG_LFR_FEATURE_ENABLED_MIN,
2516 CFG_LFR_FEATURE_ENABLED_MAX);
2517 ret = -EINVAL;
2518 goto exit;
2519 }
2520
2521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2522 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2523 /*
2524 * Note that
2525 * SETROAMMODE 0 is to enable LFR while
2526 * SETROAMMODE 1 is to disable LFR, but
2527 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2528 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2529 */
2530 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2531 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2532 else
2533 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2534
2535 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2536 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2537 }
2538 /* GETROAMMODE */
2539 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2540 {
2541 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2542 char extra[32];
2543 tANI_U8 len = 0;
2544
2545 /*
2546 * roamMode value shall be inverted because the sementics is different.
2547 */
2548 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2549 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2550 else
2551 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2552
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002553 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002554 if (copy_to_user(priv_data.buf, &extra, len + 1))
2555 {
2556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2557 "%s: failed to copy data to user buffer", __func__);
2558 ret = -EFAULT;
2559 goto exit;
2560 }
2561 }
2562#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002563#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002564#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002565 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2566 {
2567 tANI_U8 *value = command;
2568 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2569
2570 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2571 value = value + 13;
2572 /* Convert the value from ascii to integer */
2573 ret = kstrtou8(value, 10, &roamRssiDiff);
2574 if (ret < 0)
2575 {
2576 /* If the input value is greater than max value of datatype, then also
2577 kstrtou8 fails */
2578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2579 "%s: kstrtou8 failed range [%d - %d]", __func__,
2580 CFG_ROAM_RSSI_DIFF_MIN,
2581 CFG_ROAM_RSSI_DIFF_MAX);
2582 ret = -EINVAL;
2583 goto exit;
2584 }
2585
2586 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2587 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2588 {
2589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2590 "Roam rssi diff value %d is out of range"
2591 " (Min: %d Max: %d)", roamRssiDiff,
2592 CFG_ROAM_RSSI_DIFF_MIN,
2593 CFG_ROAM_RSSI_DIFF_MAX);
2594 ret = -EINVAL;
2595 goto exit;
2596 }
2597
2598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2599 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2600
2601 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2602 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2603 }
2604 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2605 {
2606 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2607 char extra[32];
2608 tANI_U8 len = 0;
2609
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302610 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2611 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2612 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002613 len = scnprintf(extra, sizeof(extra), "%s %d",
2614 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002615 if (copy_to_user(priv_data.buf, &extra, len + 1))
2616 {
2617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2618 "%s: failed to copy data to user buffer", __func__);
2619 ret = -EFAULT;
2620 goto exit;
2621 }
2622 }
2623#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002624#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002625 else if (strncmp(command, "GETBAND", 7) == 0)
2626 {
2627 int band = -1;
2628 char extra[32];
2629 tANI_U8 len = 0;
2630 hdd_getBand_helper(pHddCtx, &band);
2631
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302632 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2633 TRACE_CODE_HDD_GETBAND_IOCTL,
2634 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002635 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002636 if (copy_to_user(priv_data.buf, &extra, len + 1))
2637 {
2638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2639 "%s: failed to copy data to user buffer", __func__);
2640 ret = -EFAULT;
2641 goto exit;
2642 }
2643 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002644 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2645 {
2646 tANI_U8 *value = command;
2647 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2648 tANI_U8 numChannels = 0;
2649 eHalStatus status = eHAL_STATUS_SUCCESS;
2650
2651 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2652 if (eHAL_STATUS_SUCCESS != status)
2653 {
2654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2655 "%s: Failed to parse channel list information", __func__);
2656 ret = -EINVAL;
2657 goto exit;
2658 }
2659
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302660 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2661 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2662 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002663 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2664 {
2665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2666 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2667 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2668 ret = -EINVAL;
2669 goto exit;
2670 }
2671 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2672 numChannels);
2673 if (eHAL_STATUS_SUCCESS != status)
2674 {
2675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2676 "%s: Failed to update channel list information", __func__);
2677 ret = -EINVAL;
2678 goto exit;
2679 }
2680 }
2681 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2682 {
2683 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2684 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002685 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002686 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002687 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002688
2689 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2690 ChannelList, &numChannels ))
2691 {
2692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2693 "%s: failed to get roam scan channel list", __func__);
2694 ret = -EFAULT;
2695 goto exit;
2696 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302697 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2698 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2699 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002700 /* output channel list is of the format
2701 [Number of roam scan channels][Channel1][Channel2]... */
2702 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002703 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002704 for (j = 0; (j < numChannels); j++)
2705 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002706 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2707 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002708 }
2709
2710 if (copy_to_user(priv_data.buf, &extra, len + 1))
2711 {
2712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2713 "%s: failed to copy data to user buffer", __func__);
2714 ret = -EFAULT;
2715 goto exit;
2716 }
2717 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002718 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2719 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002720 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002721 char extra[32];
2722 tANI_U8 len = 0;
2723
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002724 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002725 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002726 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002727 hdd_is_okc_mode_enabled(pHddCtx) &&
2728 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2729 {
2730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002731 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002732 " hence this operation is not permitted!", __func__);
2733 ret = -EPERM;
2734 goto exit;
2735 }
2736
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002737 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002738 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002739 if (copy_to_user(priv_data.buf, &extra, len + 1))
2740 {
2741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2742 "%s: failed to copy data to user buffer", __func__);
2743 ret = -EFAULT;
2744 goto exit;
2745 }
2746 }
2747 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2748 {
2749 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2750 char extra[32];
2751 tANI_U8 len = 0;
2752
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002753 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002754 then this operation is not permitted (return FAILURE) */
2755 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002756 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002757 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2758 {
2759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002760 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002761 " hence this operation is not permitted!", __func__);
2762 ret = -EPERM;
2763 goto exit;
2764 }
2765
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002766 len = scnprintf(extra, sizeof(extra), "%s %d",
2767 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002768 if (copy_to_user(priv_data.buf, &extra, len + 1))
2769 {
2770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2771 "%s: failed to copy data to user buffer", __func__);
2772 ret = -EFAULT;
2773 goto exit;
2774 }
2775 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002776 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002777 {
2778 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2779 char extra[32];
2780 tANI_U8 len = 0;
2781
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002782 len = scnprintf(extra, sizeof(extra), "%s %d",
2783 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002784 if (copy_to_user(priv_data.buf, &extra, len + 1))
2785 {
2786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2787 "%s: failed to copy data to user buffer", __func__);
2788 ret = -EFAULT;
2789 goto exit;
2790 }
2791 }
2792 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2793 {
2794 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2795 char extra[32];
2796 tANI_U8 len = 0;
2797
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002798 len = scnprintf(extra, sizeof(extra), "%s %d",
2799 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002800 if (copy_to_user(priv_data.buf, &extra, len + 1))
2801 {
2802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2803 "%s: failed to copy data to user buffer", __func__);
2804 ret = -EFAULT;
2805 goto exit;
2806 }
2807 }
2808 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2809 {
2810 tANI_U8 *value = command;
2811 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2812
2813 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2814 value = value + 26;
2815 /* Convert the value from ascii to integer */
2816 ret = kstrtou8(value, 10, &minTime);
2817 if (ret < 0)
2818 {
2819 /* If the input value is greater than max value of datatype, then also
2820 kstrtou8 fails */
2821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2822 "%s: kstrtou8 failed range [%d - %d]", __func__,
2823 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2824 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2825 ret = -EINVAL;
2826 goto exit;
2827 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002828 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2829 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2830 {
2831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2832 "scan min channel time value %d is out of range"
2833 " (Min: %d Max: %d)", minTime,
2834 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2835 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2836 ret = -EINVAL;
2837 goto exit;
2838 }
2839
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302840 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2841 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2842 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2844 "%s: Received Command to change channel min time = %d", __func__, minTime);
2845
2846 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2847 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2848 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002849 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2850 {
2851 tANI_U8 *value = command;
2852 tANI_U8 channel = 0;
2853 tANI_U8 dwellTime = 0;
2854 tANI_U8 bufLen = 0;
2855 tANI_U8 *buf = NULL;
2856 tSirMacAddr targetApBssid;
2857 eHalStatus status = eHAL_STATUS_SUCCESS;
2858 struct ieee80211_channel chan;
2859 tANI_U8 finalLen = 0;
2860 tANI_U8 *finalBuf = NULL;
2861 tANI_U8 temp = 0;
2862 u64 cookie;
2863 hdd_station_ctx_t *pHddStaCtx = NULL;
2864 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2865
2866 /* if not associated, no need to send action frame */
2867 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2868 {
2869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2870 ret = -EINVAL;
2871 goto exit;
2872 }
2873
2874 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2875 &dwellTime, &buf, &bufLen);
2876 if (eHAL_STATUS_SUCCESS != status)
2877 {
2878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2879 "%s: Failed to parse send action frame data", __func__);
2880 ret = -EINVAL;
2881 goto exit;
2882 }
2883
2884 /* if the target bssid is different from currently associated AP,
2885 then no need to send action frame */
2886 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2887 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2888 {
2889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2890 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002891 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002892 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002893 goto exit;
2894 }
2895
2896 /* if the channel number is different from operating channel then
2897 no need to send action frame */
2898 if (channel != pHddStaCtx->conn_info.operationChannel)
2899 {
2900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2901 "%s: channel(%d) is different from operating channel(%d)",
2902 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2903 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002904 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002905 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002906 goto exit;
2907 }
2908 chan.center_freq = sme_ChnToFreq(channel);
2909
2910 finalLen = bufLen + 24;
2911 finalBuf = vos_mem_malloc(finalLen);
2912 if (NULL == finalBuf)
2913 {
2914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2915 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002916 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002917 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002918 goto exit;
2919 }
2920 vos_mem_zero(finalBuf, finalLen);
2921
2922 /* Fill subtype */
2923 temp = SIR_MAC_MGMT_ACTION << 4;
2924 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2925
2926 /* Fill type */
2927 temp = SIR_MAC_MGMT_FRAME;
2928 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2929
2930 /* Fill destination address (bssid of the AP) */
2931 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2932
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002933 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002934 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
2935
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07002936 /* Fill BSSID (AP mac address) */
2937 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002938
2939 /* Fill received buffer from 24th address */
2940 vos_mem_copy(finalBuf + 24, buf, bufLen);
2941
Jeff Johnson11c33152013-04-16 17:52:40 -07002942 /* done with the parsed buffer */
2943 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002944 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002945
DARAM SUDHA39eede62014-02-12 11:16:40 +05302946 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07002947#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2948 &(pAdapter->wdev),
2949#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002950 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07002951#endif
2952 &chan, 0,
2953#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2954 NL80211_CHAN_HT20, 1,
2955#endif
2956 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002957 1, &cookie );
2958 vos_mem_free(finalBuf);
2959 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002960 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
2961 {
2962 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
2963 char extra[32];
2964 tANI_U8 len = 0;
2965
2966 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002967 len = scnprintf(extra, sizeof(extra), "%s %d",
2968 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302969 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2970 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
2971 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002972 if (copy_to_user(priv_data.buf, &extra, len + 1))
2973 {
2974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2975 "%s: failed to copy data to user buffer", __func__);
2976 ret = -EFAULT;
2977 goto exit;
2978 }
2979 }
2980 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
2981 {
2982 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002983 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002984
2985 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
2986 value = value + 19;
2987 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002988 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002989 if (ret < 0)
2990 {
2991 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002992 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07002994 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002995 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
2996 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
2997 ret = -EINVAL;
2998 goto exit;
2999 }
3000
3001 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3002 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3003 {
3004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3005 "lfr mode value %d is out of range"
3006 " (Min: %d Max: %d)", maxTime,
3007 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3008 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3009 ret = -EINVAL;
3010 goto exit;
3011 }
3012
3013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3014 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3015
3016 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3017 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3018 }
3019 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3020 {
3021 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3022 char extra[32];
3023 tANI_U8 len = 0;
3024
3025 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003026 len = scnprintf(extra, sizeof(extra), "%s %d",
3027 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003028 if (copy_to_user(priv_data.buf, &extra, len + 1))
3029 {
3030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3031 "%s: failed to copy data to user buffer", __func__);
3032 ret = -EFAULT;
3033 goto exit;
3034 }
3035 }
3036 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3037 {
3038 tANI_U8 *value = command;
3039 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3040
3041 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3042 value = value + 16;
3043 /* Convert the value from ascii to integer */
3044 ret = kstrtou16(value, 10, &val);
3045 if (ret < 0)
3046 {
3047 /* If the input value is greater than max value of datatype, then also
3048 kstrtou16 fails */
3049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3050 "%s: kstrtou16 failed range [%d - %d]", __func__,
3051 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3052 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3053 ret = -EINVAL;
3054 goto exit;
3055 }
3056
3057 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3058 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3059 {
3060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3061 "scan home time value %d is out of range"
3062 " (Min: %d Max: %d)", val,
3063 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3064 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3065 ret = -EINVAL;
3066 goto exit;
3067 }
3068
3069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3070 "%s: Received Command to change scan home time = %d", __func__, val);
3071
3072 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3073 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3074 }
3075 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3076 {
3077 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3078 char extra[32];
3079 tANI_U8 len = 0;
3080
3081 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003082 len = scnprintf(extra, sizeof(extra), "%s %d",
3083 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003084 if (copy_to_user(priv_data.buf, &extra, len + 1))
3085 {
3086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3087 "%s: failed to copy data to user buffer", __func__);
3088 ret = -EFAULT;
3089 goto exit;
3090 }
3091 }
3092 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3093 {
3094 tANI_U8 *value = command;
3095 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3096
3097 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3098 value = value + 17;
3099 /* Convert the value from ascii to integer */
3100 ret = kstrtou8(value, 10, &val);
3101 if (ret < 0)
3102 {
3103 /* If the input value is greater than max value of datatype, then also
3104 kstrtou8 fails */
3105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3106 "%s: kstrtou8 failed range [%d - %d]", __func__,
3107 CFG_ROAM_INTRA_BAND_MIN,
3108 CFG_ROAM_INTRA_BAND_MAX);
3109 ret = -EINVAL;
3110 goto exit;
3111 }
3112
3113 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3114 (val > CFG_ROAM_INTRA_BAND_MAX))
3115 {
3116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3117 "intra band mode value %d is out of range"
3118 " (Min: %d Max: %d)", val,
3119 CFG_ROAM_INTRA_BAND_MIN,
3120 CFG_ROAM_INTRA_BAND_MAX);
3121 ret = -EINVAL;
3122 goto exit;
3123 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3125 "%s: Received Command to change intra band = %d", __func__, val);
3126
3127 pHddCtx->cfg_ini->nRoamIntraBand = val;
3128 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3129 }
3130 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3131 {
3132 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3133 char extra[32];
3134 tANI_U8 len = 0;
3135
3136 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003137 len = scnprintf(extra, sizeof(extra), "%s %d",
3138 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003139 if (copy_to_user(priv_data.buf, &extra, len + 1))
3140 {
3141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3142 "%s: failed to copy data to user buffer", __func__);
3143 ret = -EFAULT;
3144 goto exit;
3145 }
3146 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003147 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3148 {
3149 tANI_U8 *value = command;
3150 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3151
3152 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3153 value = value + 15;
3154 /* Convert the value from ascii to integer */
3155 ret = kstrtou8(value, 10, &nProbes);
3156 if (ret < 0)
3157 {
3158 /* If the input value is greater than max value of datatype, then also
3159 kstrtou8 fails */
3160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3161 "%s: kstrtou8 failed range [%d - %d]", __func__,
3162 CFG_ROAM_SCAN_N_PROBES_MIN,
3163 CFG_ROAM_SCAN_N_PROBES_MAX);
3164 ret = -EINVAL;
3165 goto exit;
3166 }
3167
3168 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3169 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3170 {
3171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3172 "NProbes value %d is out of range"
3173 " (Min: %d Max: %d)", nProbes,
3174 CFG_ROAM_SCAN_N_PROBES_MIN,
3175 CFG_ROAM_SCAN_N_PROBES_MAX);
3176 ret = -EINVAL;
3177 goto exit;
3178 }
3179
3180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3181 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3182
3183 pHddCtx->cfg_ini->nProbes = nProbes;
3184 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3185 }
3186 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3187 {
3188 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3189 char extra[32];
3190 tANI_U8 len = 0;
3191
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003192 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003193 if (copy_to_user(priv_data.buf, &extra, len + 1))
3194 {
3195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3196 "%s: failed to copy data to user buffer", __func__);
3197 ret = -EFAULT;
3198 goto exit;
3199 }
3200 }
3201 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3202 {
3203 tANI_U8 *value = command;
3204 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3205
3206 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3207 /* input value is in units of msec */
3208 value = value + 20;
3209 /* Convert the value from ascii to integer */
3210 ret = kstrtou16(value, 10, &homeAwayTime);
3211 if (ret < 0)
3212 {
3213 /* If the input value is greater than max value of datatype, then also
3214 kstrtou8 fails */
3215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3216 "%s: kstrtou8 failed range [%d - %d]", __func__,
3217 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3218 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3219 ret = -EINVAL;
3220 goto exit;
3221 }
3222
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003223 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3224 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3225 {
3226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3227 "homeAwayTime value %d is out of range"
3228 " (Min: %d Max: %d)", homeAwayTime,
3229 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3230 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3231 ret = -EINVAL;
3232 goto exit;
3233 }
3234
3235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3236 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003237 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3238 {
3239 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3240 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3241 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003242 }
3243 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3244 {
3245 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3246 char extra[32];
3247 tANI_U8 len = 0;
3248
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003249 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003250 if (copy_to_user(priv_data.buf, &extra, len + 1))
3251 {
3252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3253 "%s: failed to copy data to user buffer", __func__);
3254 ret = -EFAULT;
3255 goto exit;
3256 }
3257 }
3258 else if (strncmp(command, "REASSOC", 7) == 0)
3259 {
3260 tANI_U8 *value = command;
3261 tANI_U8 channel = 0;
3262 tSirMacAddr targetApBssid;
3263 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003264#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3265 tCsrHandoffRequest handoffInfo;
3266#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003267 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003268 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3269
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003270 /* if not associated, no need to proceed with reassoc */
3271 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3272 {
3273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3274 ret = -EINVAL;
3275 goto exit;
3276 }
3277
3278 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3279 if (eHAL_STATUS_SUCCESS != status)
3280 {
3281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3282 "%s: Failed to parse reassoc command data", __func__);
3283 ret = -EINVAL;
3284 goto exit;
3285 }
3286
3287 /* if the target bssid is same as currently associated AP,
3288 then no need to proceed with reassoc */
3289 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3290 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3291 {
3292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3293 ret = -EINVAL;
3294 goto exit;
3295 }
3296
3297 /* Check channel number is a valid channel number */
3298 if(VOS_STATUS_SUCCESS !=
3299 wlan_hdd_validate_operation_channel(pAdapter, channel))
3300 {
3301 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003302 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003303 return -EINVAL;
3304 }
3305
3306 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003307#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3308 handoffInfo.channel = channel;
3309 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3310 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3311#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003312 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003313 else if (strncmp(command, "SETWESMODE", 10) == 0)
3314 {
3315 tANI_U8 *value = command;
3316 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3317
3318 /* Move pointer to ahead of SETWESMODE<delimiter> */
3319 value = value + 11;
3320 /* Convert the value from ascii to integer */
3321 ret = kstrtou8(value, 10, &wesMode);
3322 if (ret < 0)
3323 {
3324 /* If the input value is greater than max value of datatype, then also
3325 kstrtou8 fails */
3326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3327 "%s: kstrtou8 failed range [%d - %d]", __func__,
3328 CFG_ENABLE_WES_MODE_NAME_MIN,
3329 CFG_ENABLE_WES_MODE_NAME_MAX);
3330 ret = -EINVAL;
3331 goto exit;
3332 }
3333
3334 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3335 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3336 {
3337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3338 "WES Mode value %d is out of range"
3339 " (Min: %d Max: %d)", wesMode,
3340 CFG_ENABLE_WES_MODE_NAME_MIN,
3341 CFG_ENABLE_WES_MODE_NAME_MAX);
3342 ret = -EINVAL;
3343 goto exit;
3344 }
3345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3346 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3347
3348 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3349 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3350 }
3351 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3352 {
3353 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3354 char extra[32];
3355 tANI_U8 len = 0;
3356
Arif Hussain826d9412013-11-12 16:44:54 -08003357 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003358 if (copy_to_user(priv_data.buf, &extra, len + 1))
3359 {
3360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3361 "%s: failed to copy data to user buffer", __func__);
3362 ret = -EFAULT;
3363 goto exit;
3364 }
3365 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003366#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003367#ifdef FEATURE_WLAN_LFR
3368 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3369 {
3370 tANI_U8 *value = command;
3371 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3372
3373 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3374 value = value + 12;
3375 /* Convert the value from ascii to integer */
3376 ret = kstrtou8(value, 10, &lfrMode);
3377 if (ret < 0)
3378 {
3379 /* If the input value is greater than max value of datatype, then also
3380 kstrtou8 fails */
3381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3382 "%s: kstrtou8 failed range [%d - %d]", __func__,
3383 CFG_LFR_FEATURE_ENABLED_MIN,
3384 CFG_LFR_FEATURE_ENABLED_MAX);
3385 ret = -EINVAL;
3386 goto exit;
3387 }
3388
3389 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3390 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3391 {
3392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3393 "lfr mode value %d is out of range"
3394 " (Min: %d Max: %d)", lfrMode,
3395 CFG_LFR_FEATURE_ENABLED_MIN,
3396 CFG_LFR_FEATURE_ENABLED_MAX);
3397 ret = -EINVAL;
3398 goto exit;
3399 }
3400
3401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3402 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3403
3404 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3405 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3406 }
3407#endif
3408#ifdef WLAN_FEATURE_VOWIFI_11R
3409 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3410 {
3411 tANI_U8 *value = command;
3412 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3413
3414 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3415 value = value + 18;
3416 /* Convert the value from ascii to integer */
3417 ret = kstrtou8(value, 10, &ft);
3418 if (ret < 0)
3419 {
3420 /* If the input value is greater than max value of datatype, then also
3421 kstrtou8 fails */
3422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3423 "%s: kstrtou8 failed range [%d - %d]", __func__,
3424 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3425 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3426 ret = -EINVAL;
3427 goto exit;
3428 }
3429
3430 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3431 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3432 {
3433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3434 "ft mode value %d is out of range"
3435 " (Min: %d Max: %d)", ft,
3436 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3437 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3438 ret = -EINVAL;
3439 goto exit;
3440 }
3441
3442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3443 "%s: Received Command to change ft mode = %d", __func__, ft);
3444
3445 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3446 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3447 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303448
3449 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3450 {
3451 tANI_U8 *value = command;
3452 tSirMacAddr targetApBssid;
3453 tANI_U8 trigger = 0;
3454 eHalStatus status = eHAL_STATUS_SUCCESS;
3455 hdd_station_ctx_t *pHddStaCtx = NULL;
3456 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3457
3458 /* if not associated, no need to proceed with reassoc */
3459 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3460 {
3461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3462 ret = -EINVAL;
3463 goto exit;
3464 }
3465
3466 status = hdd_parse_reassoc_command_data(value, targetApBssid, &trigger);
3467 if (eHAL_STATUS_SUCCESS != status)
3468 {
3469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3470 "%s: Failed to parse reassoc command data", __func__);
3471 ret = -EINVAL;
3472 goto exit;
3473 }
3474
3475 /* if the target bssid is same as currently associated AP,
3476 then no need to proceed with reassoc */
3477 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3478 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3479 {
3480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3481 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3482 __func__);
3483 ret = -EINVAL;
3484 goto exit;
3485 }
3486
3487 /* Proceed with scan/roam */
3488 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3489 &targetApBssid[0],
3490 (tSmeFastRoamTrigger)(trigger));
3491 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003492#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003493#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003494 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3495 {
3496 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003497 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003498
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003499 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003500 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003501 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003502 hdd_is_okc_mode_enabled(pHddCtx) &&
3503 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3504 {
3505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003506 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003507 " hence this operation is not permitted!", __func__);
3508 ret = -EPERM;
3509 goto exit;
3510 }
3511
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003512 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3513 value = value + 11;
3514 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003515 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003516 if (ret < 0)
3517 {
3518 /* If the input value is greater than max value of datatype, then also
3519 kstrtou8 fails */
3520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3521 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003522 CFG_ESE_FEATURE_ENABLED_MIN,
3523 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003524 ret = -EINVAL;
3525 goto exit;
3526 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003527 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3528 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003529 {
3530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003531 "Ese mode value %d is out of range"
3532 " (Min: %d Max: %d)", eseMode,
3533 CFG_ESE_FEATURE_ENABLED_MIN,
3534 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003535 ret = -EINVAL;
3536 goto exit;
3537 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003539 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003540
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003541 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3542 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003543 }
3544#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003545 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3546 {
3547 tANI_U8 *value = command;
3548 tANI_BOOLEAN roamScanControl = 0;
3549
3550 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3551 value = value + 19;
3552 /* Convert the value from ascii to integer */
3553 ret = kstrtou8(value, 10, &roamScanControl);
3554 if (ret < 0)
3555 {
3556 /* If the input value is greater than max value of datatype, then also
3557 kstrtou8 fails */
3558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3559 "%s: kstrtou8 failed ", __func__);
3560 ret = -EINVAL;
3561 goto exit;
3562 }
3563
3564 if (0 != roamScanControl)
3565 {
3566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3567 "roam scan control invalid value = %d",
3568 roamScanControl);
3569 ret = -EINVAL;
3570 goto exit;
3571 }
3572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3573 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3574
3575 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3576 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003577#ifdef FEATURE_WLAN_OKC
3578 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3579 {
3580 tANI_U8 *value = command;
3581 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3582
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003583 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003584 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003585 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003586 hdd_is_okc_mode_enabled(pHddCtx) &&
3587 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3588 {
3589 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003590 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003591 " hence this operation is not permitted!", __func__);
3592 ret = -EPERM;
3593 goto exit;
3594 }
3595
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003596 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3597 value = value + 11;
3598 /* Convert the value from ascii to integer */
3599 ret = kstrtou8(value, 10, &okcMode);
3600 if (ret < 0)
3601 {
3602 /* If the input value is greater than max value of datatype, then also
3603 kstrtou8 fails */
3604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3605 "%s: kstrtou8 failed range [%d - %d]", __func__,
3606 CFG_OKC_FEATURE_ENABLED_MIN,
3607 CFG_OKC_FEATURE_ENABLED_MAX);
3608 ret = -EINVAL;
3609 goto exit;
3610 }
3611
3612 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3613 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3614 {
3615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3616 "Okc mode value %d is out of range"
3617 " (Min: %d Max: %d)", okcMode,
3618 CFG_OKC_FEATURE_ENABLED_MIN,
3619 CFG_OKC_FEATURE_ENABLED_MAX);
3620 ret = -EINVAL;
3621 goto exit;
3622 }
3623
3624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3625 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3626
3627 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3628 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003629#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003630 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3631 {
3632 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3633 char extra[32];
3634 tANI_U8 len = 0;
3635
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003636 len = scnprintf(extra, sizeof(extra), "%s %d",
3637 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003638 if (copy_to_user(priv_data.buf, &extra, len + 1))
3639 {
3640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3641 "%s: failed to copy data to user buffer", __func__);
3642 ret = -EFAULT;
3643 goto exit;
3644 }
3645 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303646#ifdef WLAN_FEATURE_PACKET_FILTERING
3647 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3648 {
3649 tANI_U8 filterType = 0;
3650 tANI_U8 *value = command;
3651
3652 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3653 value = value + 22;
3654
3655 /* Convert the value from ascii to integer */
3656 ret = kstrtou8(value, 10, &filterType);
3657 if (ret < 0)
3658 {
3659 /* If the input value is greater than max value of datatype,
3660 * then also kstrtou8 fails
3661 */
3662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3663 "%s: kstrtou8 failed range ", __func__);
3664 ret = -EINVAL;
3665 goto exit;
3666 }
3667
3668 if (filterType != 0 && filterType != 1)
3669 {
3670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3671 "%s: Accepted Values are 0 and 1 ", __func__);
3672 ret = -EINVAL;
3673 goto exit;
3674 }
3675 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3676 pAdapter->sessionId);
3677 }
3678#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303679 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3680 {
Kiet Lamad161252014-07-22 11:23:32 -07003681 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303682 int ret;
3683
Kiet Lamad161252014-07-22 11:23:32 -07003684 dhcpPhase = command + 11;
3685 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303686 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lamad161252014-07-22 11:23:32 -07003688 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303689
3690 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003691
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303692 ret = wlan_hdd_scan_abort(pAdapter);
3693 if (ret < 0)
3694 {
3695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3696 FL("failed to abort existing scan %d"), ret);
3697 }
3698
Kiet Lamad161252014-07-22 11:23:32 -07003699 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3700 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303701 }
Kiet Lamad161252014-07-22 11:23:32 -07003702 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303703 {
c_hpothu9b781ba2013-12-30 20:57:45 +05303704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kiet Lamad161252014-07-22 11:23:32 -07003705 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303706
3707 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003708
3709 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3710 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303711 }
3712 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003713 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3714 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3716 FL("making default scan to ACTIVE"));
3717 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003718 }
3719 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3720 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3722 FL("making default scan to PASSIVE"));
3723 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003724 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303725 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3726 {
3727 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3728 char extra[32];
3729 tANI_U8 len = 0;
3730
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303731 memset(extra, 0, sizeof(extra));
3732 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3733 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303734 {
3735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3736 "%s: failed to copy data to user buffer", __func__);
3737 ret = -EFAULT;
3738 goto exit;
3739 }
3740 ret = len;
3741 }
3742 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3743 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303744 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303745 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003746 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3747 {
3748 tANI_U8 filterType = 0;
3749 tANI_U8 *value;
3750 value = command + 9;
3751
3752 /* Convert the value from ascii to integer */
3753 ret = kstrtou8(value, 10, &filterType);
3754 if (ret < 0)
3755 {
3756 /* If the input value is greater than max value of datatype,
3757 * then also kstrtou8 fails
3758 */
3759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3760 "%s: kstrtou8 failed range ", __func__);
3761 ret = -EINVAL;
3762 goto exit;
3763 }
3764 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3765 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3766 {
3767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3768 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3769 " 2-Sink ", __func__);
3770 ret = -EINVAL;
3771 goto exit;
3772 }
3773 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3774 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303775 pScanInfo = &pHddCtx->scan_info;
3776 if (filterType && pScanInfo != NULL &&
3777 pHddCtx->scan_info.mScanPending)
3778 {
3779 /*Miracast Session started. Abort Scan */
3780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3781 "%s, Aborting Scan For Miracast",__func__);
3782 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3783 eCSR_SCAN_ABORT_DEFAULT);
3784 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003785 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303786 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003787 }
Leo Chang614d2072013-08-22 14:59:44 -07003788 else if (strncmp(command, "SETMCRATE", 9) == 0)
3789 {
Leo Chang614d2072013-08-22 14:59:44 -07003790 tANI_U8 *value = command;
3791 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003792 tSirRateUpdateInd *rateUpdate;
3793 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003794
3795 /* Only valid for SAP mode */
3796 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3797 {
3798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3799 "%s: SAP mode is not running", __func__);
3800 ret = -EFAULT;
3801 goto exit;
3802 }
3803
3804 /* Move pointer to ahead of SETMCRATE<delimiter> */
3805 /* input value is in units of hundred kbps */
3806 value = value + 10;
3807 /* Convert the value from ascii to integer, decimal base */
3808 ret = kstrtouint(value, 10, &targetRate);
3809
Leo Chang1f98cbd2013-10-17 15:03:52 -07003810 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3811 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003812 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003813 hddLog(VOS_TRACE_LEVEL_ERROR,
3814 "%s: SETMCRATE indication alloc fail", __func__);
3815 ret = -EFAULT;
3816 goto exit;
3817 }
3818 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3819
3820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3821 "MC Target rate %d", targetRate);
3822 /* Ignore unicast */
3823 rateUpdate->ucastDataRate = -1;
3824 rateUpdate->mcastDataRate24GHz = targetRate;
3825 rateUpdate->mcastDataRate5GHz = targetRate;
3826 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3827 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3828 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3829 if (eHAL_STATUS_SUCCESS != status)
3830 {
3831 hddLog(VOS_TRACE_LEVEL_ERROR,
3832 "%s: SET_MC_RATE failed", __func__);
3833 vos_mem_free(rateUpdate);
3834 ret = -EFAULT;
3835 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003836 }
3837 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303838#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003839 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303840 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003841 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303842 }
3843#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003844#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003845 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3846 {
3847 tANI_U8 *value = command;
3848 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3849 tANI_U8 numChannels = 0;
3850 eHalStatus status = eHAL_STATUS_SUCCESS;
3851
3852 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3853 if (eHAL_STATUS_SUCCESS != status)
3854 {
3855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3856 "%s: Failed to parse channel list information", __func__);
3857 ret = -EINVAL;
3858 goto exit;
3859 }
3860
3861 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3862 {
3863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3864 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3865 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3866 ret = -EINVAL;
3867 goto exit;
3868 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003869 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003870 ChannelList,
3871 numChannels);
3872 if (eHAL_STATUS_SUCCESS != status)
3873 {
3874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3875 "%s: Failed to update channel list information", __func__);
3876 ret = -EINVAL;
3877 goto exit;
3878 }
3879 }
3880 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3881 {
3882 tANI_U8 *value = command;
3883 char extra[128] = {0};
3884 int len = 0;
3885 tANI_U8 tid = 0;
3886 hdd_station_ctx_t *pHddStaCtx = NULL;
3887 tAniTrafStrmMetrics tsmMetrics;
3888 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3889
3890 /* if not associated, return error */
3891 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3892 {
3893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3894 ret = -EINVAL;
3895 goto exit;
3896 }
3897
3898 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3899 value = value + 12;
3900 /* Convert the value from ascii to integer */
3901 ret = kstrtou8(value, 10, &tid);
3902 if (ret < 0)
3903 {
3904 /* If the input value is greater than max value of datatype, then also
3905 kstrtou8 fails */
3906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3907 "%s: kstrtou8 failed range [%d - %d]", __func__,
3908 TID_MIN_VALUE,
3909 TID_MAX_VALUE);
3910 ret = -EINVAL;
3911 goto exit;
3912 }
3913
3914 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
3915 {
3916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3917 "tid value %d is out of range"
3918 " (Min: %d Max: %d)", tid,
3919 TID_MIN_VALUE,
3920 TID_MAX_VALUE);
3921 ret = -EINVAL;
3922 goto exit;
3923 }
3924
3925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3926 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
3927
3928 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
3929 {
3930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3931 "%s: failed to get tsm stats", __func__);
3932 ret = -EFAULT;
3933 goto exit;
3934 }
3935
3936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3937 "UplinkPktQueueDly(%d)\n"
3938 "UplinkPktQueueDlyHist[0](%d)\n"
3939 "UplinkPktQueueDlyHist[1](%d)\n"
3940 "UplinkPktQueueDlyHist[2](%d)\n"
3941 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05303942 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003943 "UplinkPktLoss(%d)\n"
3944 "UplinkPktCount(%d)\n"
3945 "RoamingCount(%d)\n"
3946 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
3947 tsmMetrics.UplinkPktQueueDlyHist[0],
3948 tsmMetrics.UplinkPktQueueDlyHist[1],
3949 tsmMetrics.UplinkPktQueueDlyHist[2],
3950 tsmMetrics.UplinkPktQueueDlyHist[3],
3951 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
3952 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
3953
3954 /* Output TSM stats is of the format
3955 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
3956 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08003957 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003958 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
3959 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
3960 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
3961 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
3962 tsmMetrics.RoamingDly);
3963
3964 if (copy_to_user(priv_data.buf, &extra, len + 1))
3965 {
3966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3967 "%s: failed to copy data to user buffer", __func__);
3968 ret = -EFAULT;
3969 goto exit;
3970 }
3971 }
3972 else if (strncmp(command, "SETCCKMIE", 9) == 0)
3973 {
3974 tANI_U8 *value = command;
3975 tANI_U8 *cckmIe = NULL;
3976 tANI_U8 cckmIeLen = 0;
3977 eHalStatus status = eHAL_STATUS_SUCCESS;
3978
3979 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
3980 if (eHAL_STATUS_SUCCESS != status)
3981 {
3982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3983 "%s: Failed to parse cckm ie data", __func__);
3984 ret = -EINVAL;
3985 goto exit;
3986 }
3987
3988 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
3989 {
3990 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3991 "%s: CCKM Ie input length is more than max[%d]", __func__,
3992 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003993 vos_mem_free(cckmIe);
3994 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003995 ret = -EINVAL;
3996 goto exit;
3997 }
3998 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003999 vos_mem_free(cckmIe);
4000 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004001 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004002 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4003 {
4004 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004005 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004006 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004007
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004008 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004009 if (eHAL_STATUS_SUCCESS != status)
4010 {
4011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004012 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004013 ret = -EINVAL;
4014 goto exit;
4015 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004016 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4017 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4018 hdd_indicateEseBcnReportNoResults (pAdapter,
4019 eseBcnReq.bcnReq[0].measurementToken,
4020 0x02, //BIT(1) set for measurement done
4021 0); // no BSS
4022 goto exit;
4023 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004024
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004025 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4026 if (eHAL_STATUS_SUCCESS != status)
4027 {
4028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4029 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4030 ret = -EINVAL;
4031 goto exit;
4032 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004033 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004034#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304035 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4036 {
4037 eHalStatus status;
4038 char buf[32], len;
4039 long waitRet;
4040 bcnMissRateContext_t getBcnMissRateCtx;
4041
4042 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4043
4044 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4045 {
4046 hddLog(VOS_TRACE_LEVEL_WARN,
4047 FL("GETBCNMISSRATE: STA is not in connected state"));
4048 ret = -1;
4049 goto exit;
4050 }
4051
4052 init_completion(&(getBcnMissRateCtx.completion));
4053 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4054
4055 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4056 pAdapter->sessionId,
4057 (void *)getBcnMissRateCB,
4058 (void *)(&getBcnMissRateCtx));
4059 if( eHAL_STATUS_SUCCESS != status)
4060 {
4061 hddLog(VOS_TRACE_LEVEL_INFO,
4062 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4063 ret = -EINVAL;
4064 goto exit;
4065 }
4066
4067 waitRet = wait_for_completion_interruptible_timeout
4068 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4069 if(waitRet <= 0)
4070 {
4071 hddLog(VOS_TRACE_LEVEL_ERROR,
4072 FL("failed to wait on bcnMissRateComp %d"), ret);
4073
4074 //Make magic number to zero so that callback is not called.
4075 spin_lock(&hdd_context_lock);
4076 getBcnMissRateCtx.magic = 0x0;
4077 spin_unlock(&hdd_context_lock);
4078 ret = -EINVAL;
4079 goto exit;
4080 }
4081
4082 hddLog(VOS_TRACE_LEVEL_INFO,
4083 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4084
4085 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4086 if (copy_to_user(priv_data.buf, &buf, len + 1))
4087 {
4088 hddLog(VOS_TRACE_LEVEL_ERROR,
4089 "%s: failed to copy data to user buffer", __func__);
4090 ret = -EFAULT;
4091 goto exit;
4092 }
4093 ret = len;
4094 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304095#ifdef FEATURE_WLAN_TDLS
4096 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4097 tANI_U8 *value = command;
4098 int set_value;
4099 /* Move pointer to ahead of TDLSOFFCH*/
4100 value += 26;
4101 sscanf(value, "%d", &set_value);
4102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4103 "%s: Tdls offchannel offset:%d",
4104 __func__, set_value);
4105 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4106 if (ret < 0)
4107 {
4108 ret = -EINVAL;
4109 goto exit;
4110 }
4111
4112 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4113 tANI_U8 *value = command;
4114 int set_value;
4115 /* Move pointer to ahead of tdlsoffchnmode*/
4116 value += 18;
4117 sscanf(value, "%d", &set_value);
4118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4119 "%s: Tdls offchannel mode:%d",
4120 __func__, set_value);
4121 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4122 if (ret < 0)
4123 {
4124 ret = -EINVAL;
4125 goto exit;
4126 }
4127 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4128 tANI_U8 *value = command;
4129 int set_value;
4130 /* Move pointer to ahead of TDLSOFFCH*/
4131 value += 14;
4132 sscanf(value, "%d", &set_value);
4133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4134 "%s: Tdls offchannel num: %d",
4135 __func__, set_value);
4136 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4137 if (ret < 0)
4138 {
4139 ret = -EINVAL;
4140 goto exit;
4141 }
4142 }
4143#endif
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004144 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304145 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4146 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4147 pAdapter->sessionId, 0));
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004148 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s",
4149 __func__, command);
4150 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004151 }
4152exit:
4153 if (command)
4154 {
4155 kfree(command);
4156 }
4157 return ret;
4158}
4159
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004160#ifdef CONFIG_COMPAT
4161static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4162{
4163 struct {
4164 compat_uptr_t buf;
4165 int used_len;
4166 int total_len;
4167 } compat_priv_data;
4168 hdd_priv_data_t priv_data;
4169 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004170
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004171 /*
4172 * Note that pAdapter and ifr have already been verified by caller,
4173 * and HDD context has also been validated
4174 */
4175 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4176 sizeof(compat_priv_data))) {
4177 ret = -EFAULT;
4178 goto exit;
4179 }
4180 priv_data.buf = compat_ptr(compat_priv_data.buf);
4181 priv_data.used_len = compat_priv_data.used_len;
4182 priv_data.total_len = compat_priv_data.total_len;
4183 ret = hdd_driver_command(pAdapter, &priv_data);
4184 exit:
4185 return ret;
4186}
4187#else /* CONFIG_COMPAT */
4188static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4189{
4190 /* will never be invoked */
4191 return 0;
4192}
4193#endif /* CONFIG_COMPAT */
4194
4195static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4196{
4197 hdd_priv_data_t priv_data;
4198 int ret = 0;
4199
4200 /*
4201 * Note that pAdapter and ifr have already been verified by caller,
4202 * and HDD context has also been validated
4203 */
4204 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4205 ret = -EFAULT;
4206 } else {
4207 ret = hdd_driver_command(pAdapter, &priv_data);
4208 }
4209 return ret;
4210}
4211
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304212int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004213{
4214 hdd_adapter_t *pAdapter;
4215 hdd_context_t *pHddCtx;
4216 int ret;
4217
4218 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4219 if (NULL == pAdapter) {
4220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4221 "%s: HDD adapter context is Null", __func__);
4222 ret = -ENODEV;
4223 goto exit;
4224 }
4225 if (dev != pAdapter->dev) {
4226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4227 "%s: HDD adapter/dev inconsistency", __func__);
4228 ret = -ENODEV;
4229 goto exit;
4230 }
4231
4232 if ((!ifr) || (!ifr->ifr_data)) {
4233 ret = -EINVAL;
4234 goto exit;
4235 }
4236
4237 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4238 ret = wlan_hdd_validate_context(pHddCtx);
4239 if (ret) {
Mahesh A Saptasagar5b16d0a2014-11-03 17:55:29 +05304240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004241 "%s: invalid context", __func__);
4242 ret = -EBUSY;
4243 goto exit;
4244 }
4245
4246 switch (cmd) {
4247 case (SIOCDEVPRIVATE + 1):
4248 if (is_compat_task())
4249 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4250 else
4251 ret = hdd_driver_ioctl(pAdapter, ifr);
4252 break;
4253 default:
4254 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4255 __func__, cmd);
4256 ret = -EINVAL;
4257 break;
4258 }
4259 exit:
4260 return ret;
4261}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004262
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304263int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4264{
4265 int ret;
4266
4267 vos_ssr_protect(__func__);
4268 ret = __hdd_ioctl(dev, ifr, cmd);
4269 vos_ssr_unprotect(__func__);
4270
4271 return ret;
4272}
4273
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004274#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004275/**---------------------------------------------------------------------------
4276
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004277 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004278
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004279 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004280 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4281 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4282 <space>Scan Mode N<space>Meas Duration N
4283 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4284 then take N.
4285 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4286 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4287 This function does not take care of removing duplicate channels from the list
4288
4289 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004290 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004291
4292 \return - 0 for success non-zero for failure
4293
4294 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004295static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4296 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004297{
4298 tANI_U8 *inPtr = pValue;
4299 int tempInt = 0;
4300 int j = 0, i = 0, v = 0;
4301 char buf[32];
4302
4303 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4304 /*no argument after the command*/
4305 if (NULL == inPtr)
4306 {
4307 return -EINVAL;
4308 }
4309 /*no space after the command*/
4310 else if (SPACE_ASCII_VALUE != *inPtr)
4311 {
4312 return -EINVAL;
4313 }
4314
4315 /*removing empty spaces*/
4316 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4317
4318 /*no argument followed by spaces*/
4319 if ('\0' == *inPtr) return -EINVAL;
4320
4321 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004322 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004323 if (1 != v) return -EINVAL;
4324
4325 v = kstrtos32(buf, 10, &tempInt);
4326 if ( v < 0) return -EINVAL;
4327
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004328 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004329
4330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004331 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004332
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004333 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004334 {
4335 for (i = 0; i < 4; i++)
4336 {
4337 /*inPtr pointing to the beginning of first space after number of ie fields*/
4338 inPtr = strpbrk( inPtr, " " );
4339 /*no ie data after the number of ie fields argument*/
4340 if (NULL == inPtr) return -EINVAL;
4341
4342 /*removing empty space*/
4343 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4344
4345 /*no ie data after the number of ie fields argument and spaces*/
4346 if ( '\0' == *inPtr ) return -EINVAL;
4347
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004348 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004349 if (1 != v) return -EINVAL;
4350
4351 v = kstrtos32(buf, 10, &tempInt);
4352 if (v < 0) return -EINVAL;
4353
4354 switch (i)
4355 {
4356 case 0: /* Measurement token */
4357 if (tempInt <= 0)
4358 {
4359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4360 "Invalid Measurement Token(%d)", tempInt);
4361 return -EINVAL;
4362 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004363 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004364 break;
4365
4366 case 1: /* Channel number */
4367 if ((tempInt <= 0) ||
4368 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4369 {
4370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4371 "Invalid Channel Number(%d)", tempInt);
4372 return -EINVAL;
4373 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004374 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004375 break;
4376
4377 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004378 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004379 {
4380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4381 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4382 return -EINVAL;
4383 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004384 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004385 break;
4386
4387 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004388 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4389 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004390 {
4391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4392 "Invalid Measurement Duration(%d)", tempInt);
4393 return -EINVAL;
4394 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004395 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004396 break;
4397 }
4398 }
4399 }
4400
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004401 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004402 {
4403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304404 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004405 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004406 pEseBcnReq->bcnReq[j].measurementToken,
4407 pEseBcnReq->bcnReq[j].channel,
4408 pEseBcnReq->bcnReq[j].scanMode,
4409 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004410 }
4411
4412 return VOS_STATUS_SUCCESS;
4413}
4414
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004415static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4416{
4417 struct statsContext *pStatsContext = NULL;
4418 hdd_adapter_t *pAdapter = NULL;
4419
4420 if (NULL == pContext)
4421 {
4422 hddLog(VOS_TRACE_LEVEL_ERROR,
4423 "%s: Bad param, pContext [%p]",
4424 __func__, pContext);
4425 return;
4426 }
4427
Jeff Johnson72a40512013-12-19 10:14:15 -08004428 /* there is a race condition that exists between this callback
4429 function and the caller since the caller could time out either
4430 before or while this code is executing. we use a spinlock to
4431 serialize these actions */
4432 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004433
4434 pStatsContext = pContext;
4435 pAdapter = pStatsContext->pAdapter;
4436 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4437 {
4438 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004439 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004440 hddLog(VOS_TRACE_LEVEL_WARN,
4441 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4442 __func__, pAdapter, pStatsContext->magic);
4443 return;
4444 }
4445
Jeff Johnson72a40512013-12-19 10:14:15 -08004446 /* context is valid so caller is still waiting */
4447
4448 /* paranoia: invalidate the magic */
4449 pStatsContext->magic = 0;
4450
4451 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004452 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4453 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4454 tsmMetrics.UplinkPktQueueDlyHist,
4455 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4456 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4457 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4458 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4459 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4460 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4461 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4462
Jeff Johnson72a40512013-12-19 10:14:15 -08004463 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004464 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004465
4466 /* serialization is complete */
4467 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004468}
4469
4470
4471
4472static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4473 tAniTrafStrmMetrics* pTsmMetrics)
4474{
4475 hdd_station_ctx_t *pHddStaCtx = NULL;
4476 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004477 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004478 long lrc;
4479 struct statsContext context;
4480 hdd_context_t *pHddCtx = NULL;
4481
4482 if (NULL == pAdapter)
4483 {
4484 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4485 return VOS_STATUS_E_FAULT;
4486 }
4487
4488 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4489 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4490
4491 /* we are connected prepare our callback context */
4492 init_completion(&context.completion);
4493 context.pAdapter = pAdapter;
4494 context.magic = STATS_CONTEXT_MAGIC;
4495
4496 /* query tsm stats */
4497 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4498 pHddStaCtx->conn_info.staId[ 0 ],
4499 pHddStaCtx->conn_info.bssId,
4500 &context, pHddCtx->pvosContext, tid);
4501
4502 if (eHAL_STATUS_SUCCESS != hstatus)
4503 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004504 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4505 __func__);
4506 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004507 }
4508 else
4509 {
4510 /* request was sent -- wait for the response */
4511 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4512 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004513 if (lrc <= 0)
4514 {
4515 hddLog(VOS_TRACE_LEVEL_ERROR,
4516 "%s: SME %s while retrieving statistics",
4517 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004518 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004519 }
4520 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004521
Jeff Johnson72a40512013-12-19 10:14:15 -08004522 /* either we never sent a request, we sent a request and received a
4523 response or we sent a request and timed out. if we never sent a
4524 request or if we sent a request and got a response, we want to
4525 clear the magic out of paranoia. if we timed out there is a
4526 race condition such that the callback function could be
4527 executing at the same time we are. of primary concern is if the
4528 callback function had already verified the "magic" but had not
4529 yet set the completion variable when a timeout occurred. we
4530 serialize these activities by invalidating the magic while
4531 holding a shared spinlock which will cause us to block if the
4532 callback is currently executing */
4533 spin_lock(&hdd_context_lock);
4534 context.magic = 0;
4535 spin_unlock(&hdd_context_lock);
4536
4537 if (VOS_STATUS_SUCCESS == vstatus)
4538 {
4539 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4540 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4541 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4542 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4543 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4544 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4545 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4546 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4547 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4548 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4549 }
4550 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004551}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004552#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004553
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004554#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004555void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4556{
4557 eCsrBand band = -1;
4558 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4559 switch (band)
4560 {
4561 case eCSR_BAND_ALL:
4562 *pBand = WLAN_HDD_UI_BAND_AUTO;
4563 break;
4564
4565 case eCSR_BAND_24:
4566 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4567 break;
4568
4569 case eCSR_BAND_5G:
4570 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4571 break;
4572
4573 default:
4574 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4575 *pBand = -1;
4576 break;
4577 }
4578}
4579
4580/**---------------------------------------------------------------------------
4581
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004582 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4583
4584 This function parses the send action frame data passed in the format
4585 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4586
Srinivas Girigowda56076852013-08-20 14:00:50 -07004587 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004588 \param - pTargetApBssid Pointer to target Ap bssid
4589 \param - pChannel Pointer to the Target AP channel
4590 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4591 \param - pBuf Pointer to data
4592 \param - pBufLen Pointer to data length
4593
4594 \return - 0 for success non-zero for failure
4595
4596 --------------------------------------------------------------------------*/
4597VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4598 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4599{
4600 tANI_U8 *inPtr = pValue;
4601 tANI_U8 *dataEnd;
4602 int tempInt;
4603 int j = 0;
4604 int i = 0;
4605 int v = 0;
4606 tANI_U8 tempBuf[32];
4607 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004608 /* 12 hexa decimal digits, 5 ':' and '\0' */
4609 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004610
4611 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4612 /*no argument after the command*/
4613 if (NULL == inPtr)
4614 {
4615 return -EINVAL;
4616 }
4617
4618 /*no space after the command*/
4619 else if (SPACE_ASCII_VALUE != *inPtr)
4620 {
4621 return -EINVAL;
4622 }
4623
4624 /*removing empty spaces*/
4625 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4626
4627 /*no argument followed by spaces*/
4628 if ('\0' == *inPtr)
4629 {
4630 return -EINVAL;
4631 }
4632
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004633 v = sscanf(inPtr, "%17s", macAddress);
4634 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004635 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4637 "Invalid MAC address or All hex inputs are not read (%d)", v);
4638 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004639 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004640
4641 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4642 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4643 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4644 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4645 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4646 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004647
4648 /* point to the next argument */
4649 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4650 /*no argument after the command*/
4651 if (NULL == inPtr) return -EINVAL;
4652
4653 /*removing empty spaces*/
4654 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4655
4656 /*no argument followed by spaces*/
4657 if ('\0' == *inPtr)
4658 {
4659 return -EINVAL;
4660 }
4661
4662 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004663 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004664 if (1 != v) return -EINVAL;
4665
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004666 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304667 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304668 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004669
4670 *pChannel = tempInt;
4671
4672 /* point to the next argument */
4673 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4674 /*no argument after the command*/
4675 if (NULL == inPtr) return -EINVAL;
4676 /*removing empty spaces*/
4677 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4678
4679 /*no argument followed by spaces*/
4680 if ('\0' == *inPtr)
4681 {
4682 return -EINVAL;
4683 }
4684
4685 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004686 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004687 if (1 != v) return -EINVAL;
4688
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004689 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004690 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004691
4692 *pDwellTime = tempInt;
4693
4694 /* point to the next argument */
4695 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4696 /*no argument after the command*/
4697 if (NULL == inPtr) return -EINVAL;
4698 /*removing empty spaces*/
4699 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4700
4701 /*no argument followed by spaces*/
4702 if ('\0' == *inPtr)
4703 {
4704 return -EINVAL;
4705 }
4706
4707 /* find the length of data */
4708 dataEnd = inPtr;
4709 while(('\0' != *dataEnd) )
4710 {
4711 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004712 }
Kiet Lambe150c22013-11-21 16:30:32 +05304713 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004714 if ( *pBufLen <= 0) return -EINVAL;
4715
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004716 /* Allocate the number of bytes based on the number of input characters
4717 whether it is even or odd.
4718 if the number of input characters are even, then we need N/2 byte.
4719 if the number of input characters are odd, then we need do (N+1)/2 to
4720 compensate rounding off.
4721 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4722 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4723 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004724 if (NULL == *pBuf)
4725 {
4726 hddLog(VOS_TRACE_LEVEL_FATAL,
4727 "%s: vos_mem_alloc failed ", __func__);
4728 return -EINVAL;
4729 }
4730
4731 /* the buffer received from the upper layer is character buffer,
4732 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4733 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4734 and f0 in 3rd location */
4735 for (i = 0, j = 0; j < *pBufLen; j += 2)
4736 {
Kiet Lambe150c22013-11-21 16:30:32 +05304737 if( j+1 == *pBufLen)
4738 {
4739 tempByte = hdd_parse_hex(inPtr[j]);
4740 }
4741 else
4742 {
4743 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4744 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004745 (*pBuf)[i++] = tempByte;
4746 }
4747 *pBufLen = i;
4748 return VOS_STATUS_SUCCESS;
4749}
4750
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004751/**---------------------------------------------------------------------------
4752
Srinivas Girigowdade697412013-02-14 16:31:48 -08004753 \brief hdd_parse_channellist() - HDD Parse channel list
4754
4755 This function parses the channel list passed in the format
4756 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004757 if the Number of channels (N) does not match with the actual number of channels passed
4758 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4759 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4760 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4761 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004762
4763 \param - pValue Pointer to input channel list
4764 \param - ChannelList Pointer to local output array to record channel list
4765 \param - pNumChannels Pointer to number of roam scan channels
4766
4767 \return - 0 for success non-zero for failure
4768
4769 --------------------------------------------------------------------------*/
4770VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4771{
4772 tANI_U8 *inPtr = pValue;
4773 int tempInt;
4774 int j = 0;
4775 int v = 0;
4776 char buf[32];
4777
4778 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4779 /*no argument after the command*/
4780 if (NULL == inPtr)
4781 {
4782 return -EINVAL;
4783 }
4784
4785 /*no space after the command*/
4786 else if (SPACE_ASCII_VALUE != *inPtr)
4787 {
4788 return -EINVAL;
4789 }
4790
4791 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004792 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004793
4794 /*no argument followed by spaces*/
4795 if ('\0' == *inPtr)
4796 {
4797 return -EINVAL;
4798 }
4799
4800 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004801 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004802 if (1 != v) return -EINVAL;
4803
Srinivas Girigowdade697412013-02-14 16:31:48 -08004804 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004805 if ((v < 0) ||
4806 (tempInt <= 0) ||
4807 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4808 {
4809 return -EINVAL;
4810 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004811
4812 *pNumChannels = tempInt;
4813
4814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4815 "Number of channels are: %d", *pNumChannels);
4816
4817 for (j = 0; j < (*pNumChannels); j++)
4818 {
4819 /*inPtr pointing to the beginning of first space after number of channels*/
4820 inPtr = strpbrk( inPtr, " " );
4821 /*no channel list after the number of channels argument*/
4822 if (NULL == inPtr)
4823 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004824 if (0 != j)
4825 {
4826 *pNumChannels = j;
4827 return VOS_STATUS_SUCCESS;
4828 }
4829 else
4830 {
4831 return -EINVAL;
4832 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004833 }
4834
4835 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004836 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004837
4838 /*no channel list after the number of channels argument and spaces*/
4839 if ( '\0' == *inPtr )
4840 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004841 if (0 != j)
4842 {
4843 *pNumChannels = j;
4844 return VOS_STATUS_SUCCESS;
4845 }
4846 else
4847 {
4848 return -EINVAL;
4849 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004850 }
4851
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004852 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004853 if (1 != v) return -EINVAL;
4854
Srinivas Girigowdade697412013-02-14 16:31:48 -08004855 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004856 if ((v < 0) ||
4857 (tempInt <= 0) ||
4858 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4859 {
4860 return -EINVAL;
4861 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004862 pChannelList[j] = tempInt;
4863
4864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
4865 "Channel %d added to preferred channel list",
4866 pChannelList[j] );
4867 }
4868
Srinivas Girigowdade697412013-02-14 16:31:48 -08004869 return VOS_STATUS_SUCCESS;
4870}
4871
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004872
4873/**---------------------------------------------------------------------------
4874
4875 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
4876
4877 This function parses the reasoc command data passed in the format
4878 REASSOC<space><bssid><space><channel>
4879
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004880 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004881 \param - pTargetApBssid Pointer to target Ap bssid
4882 \param - pChannel Pointer to the Target AP channel
4883
4884 \return - 0 for success non-zero for failure
4885
4886 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004887VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
4888 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004889{
4890 tANI_U8 *inPtr = pValue;
4891 int tempInt;
4892 int v = 0;
4893 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08004894 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004895 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004896
4897 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4898 /*no argument after the command*/
4899 if (NULL == inPtr)
4900 {
4901 return -EINVAL;
4902 }
4903
4904 /*no space after the command*/
4905 else if (SPACE_ASCII_VALUE != *inPtr)
4906 {
4907 return -EINVAL;
4908 }
4909
4910 /*removing empty spaces*/
4911 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4912
4913 /*no argument followed by spaces*/
4914 if ('\0' == *inPtr)
4915 {
4916 return -EINVAL;
4917 }
4918
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004919 v = sscanf(inPtr, "%17s", macAddress);
4920 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004921 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4923 "Invalid MAC address or All hex inputs are not read (%d)", v);
4924 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004925 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004926
4927 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4928 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4929 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4930 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4931 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4932 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004933
4934 /* point to the next argument */
4935 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4936 /*no argument after the command*/
4937 if (NULL == inPtr) return -EINVAL;
4938
4939 /*removing empty spaces*/
4940 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4941
4942 /*no argument followed by spaces*/
4943 if ('\0' == *inPtr)
4944 {
4945 return -EINVAL;
4946 }
4947
4948 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004949 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004950 if (1 != v) return -EINVAL;
4951
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004952 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004953 if ((v < 0) ||
4954 (tempInt <= 0) ||
4955 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4956 {
4957 return -EINVAL;
4958 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004959
4960 *pChannel = tempInt;
4961 return VOS_STATUS_SUCCESS;
4962}
4963
4964#endif
4965
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004966#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004967/**---------------------------------------------------------------------------
4968
4969 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
4970
4971 This function parses the SETCCKM IE command
4972 SETCCKMIE<space><ie data>
4973
4974 \param - pValue Pointer to input data
4975 \param - pCckmIe Pointer to output cckm Ie
4976 \param - pCckmIeLen Pointer to output cckm ie length
4977
4978 \return - 0 for success non-zero for failure
4979
4980 --------------------------------------------------------------------------*/
4981VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
4982 tANI_U8 *pCckmIeLen)
4983{
4984 tANI_U8 *inPtr = pValue;
4985 tANI_U8 *dataEnd;
4986 int j = 0;
4987 int i = 0;
4988 tANI_U8 tempByte = 0;
4989
4990 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4991 /*no argument after the command*/
4992 if (NULL == inPtr)
4993 {
4994 return -EINVAL;
4995 }
4996
4997 /*no space after the command*/
4998 else if (SPACE_ASCII_VALUE != *inPtr)
4999 {
5000 return -EINVAL;
5001 }
5002
5003 /*removing empty spaces*/
5004 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5005
5006 /*no argument followed by spaces*/
5007 if ('\0' == *inPtr)
5008 {
5009 return -EINVAL;
5010 }
5011
5012 /* find the length of data */
5013 dataEnd = inPtr;
5014 while(('\0' != *dataEnd) )
5015 {
5016 dataEnd++;
5017 ++(*pCckmIeLen);
5018 }
5019 if ( *pCckmIeLen <= 0) return -EINVAL;
5020
5021 /* Allocate the number of bytes based on the number of input characters
5022 whether it is even or odd.
5023 if the number of input characters are even, then we need N/2 byte.
5024 if the number of input characters are odd, then we need do (N+1)/2 to
5025 compensate rounding off.
5026 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5027 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5028 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5029 if (NULL == *pCckmIe)
5030 {
5031 hddLog(VOS_TRACE_LEVEL_FATAL,
5032 "%s: vos_mem_alloc failed ", __func__);
5033 return -EINVAL;
5034 }
5035 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5036 /* the buffer received from the upper layer is character buffer,
5037 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5038 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5039 and f0 in 3rd location */
5040 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5041 {
5042 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5043 (*pCckmIe)[i++] = tempByte;
5044 }
5045 *pCckmIeLen = i;
5046
5047 return VOS_STATUS_SUCCESS;
5048}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005049#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005050
Jeff Johnson295189b2012-06-20 16:38:30 -07005051/**---------------------------------------------------------------------------
5052
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005053 \brief hdd_is_valid_mac_address() - Validate MAC address
5054
5055 This function validates whether the given MAC address is valid or not
5056 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5057 where X is the hexa decimal digit character and separated by ':'
5058 This algorithm works even if MAC address is not separated by ':'
5059
5060 This code checks given input string mac contains exactly 12 hexadecimal digits.
5061 and a separator colon : appears in the input string only after
5062 an even number of hex digits.
5063
5064 \param - pMacAddr pointer to the input MAC address
5065 \return - 1 for valid and 0 for invalid
5066
5067 --------------------------------------------------------------------------*/
5068
5069v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5070{
5071 int xdigit = 0;
5072 int separator = 0;
5073 while (*pMacAddr)
5074 {
5075 if (isxdigit(*pMacAddr))
5076 {
5077 xdigit++;
5078 }
5079 else if (':' == *pMacAddr)
5080 {
5081 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5082 break;
5083
5084 ++separator;
5085 }
5086 else
5087 {
5088 separator = -1;
5089 /* Invalid MAC found */
5090 return 0;
5091 }
5092 ++pMacAddr;
5093 }
5094 return (xdigit == 12 && (separator == 5 || separator == 0));
5095}
5096
5097/**---------------------------------------------------------------------------
5098
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305099 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005100
5101 \param - dev Pointer to net_device structure
5102
5103 \return - 0 for success non-zero for failure
5104
5105 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305106int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005107{
5108 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5109 hdd_context_t *pHddCtx;
5110 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5111 VOS_STATUS status;
5112 v_BOOL_t in_standby = TRUE;
5113
5114 if (NULL == pAdapter)
5115 {
5116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305117 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005118 return -ENODEV;
5119 }
5120
5121 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305122 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5123 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005124 if (NULL == pHddCtx)
5125 {
5126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005127 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005128 return -ENODEV;
5129 }
5130
5131 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5132 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5133 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005134 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5135 {
5136 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305137 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005138 in_standby = FALSE;
5139 break;
5140 }
5141 else
5142 {
5143 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5144 pAdapterNode = pNext;
5145 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005146 }
5147
5148 if (TRUE == in_standby)
5149 {
5150 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5151 {
5152 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5153 "wlan out of power save", __func__);
5154 return -EINVAL;
5155 }
5156 }
5157
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005158 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005159 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5160 {
5161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005162 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005163 /* Enable TX queues only when we are connected */
5164 netif_tx_start_all_queues(dev);
5165 }
5166
5167 return 0;
5168}
5169
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305170/**---------------------------------------------------------------------------
5171
5172 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5173
5174 This is called in response to ifconfig up
5175
5176 \param - dev Pointer to net_device structure
5177
5178 \return - 0 for success non-zero for failure
5179
5180 --------------------------------------------------------------------------*/
5181int hdd_open(struct net_device *dev)
5182{
5183 int ret;
5184
5185 vos_ssr_protect(__func__);
5186 ret = __hdd_open(dev);
5187 vos_ssr_unprotect(__func__);
5188
5189 return ret;
5190}
5191
Jeff Johnson295189b2012-06-20 16:38:30 -07005192int hdd_mon_open (struct net_device *dev)
5193{
5194 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5195
5196 if(pAdapter == NULL) {
5197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005198 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005199 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005200 }
5201
5202 netif_start_queue(dev);
5203
5204 return 0;
5205}
5206/**---------------------------------------------------------------------------
5207
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305208 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005209
5210 \param - dev Pointer to net_device structure
5211
5212 \return - 0 for success non-zero for failure
5213
5214 --------------------------------------------------------------------------*/
5215
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305216int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005217{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305218 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005219 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5220 hdd_context_t *pHddCtx;
5221 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5222 VOS_STATUS status;
5223 v_BOOL_t enter_standby = TRUE;
5224
5225 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005226 if (NULL == pAdapter)
5227 {
5228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305229 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005230 return -ENODEV;
5231 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305232 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5233 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305234
5235 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5236 ret = wlan_hdd_validate_context(pHddCtx);
5237 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005238 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5240 "%s: HDD context is not valid!", __func__);
5241 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005242 }
5243
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305244 /* Nothing to be done if the interface is not opened */
5245 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5246 {
5247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5248 "%s: NETDEV Interface is not OPENED", __func__);
5249 return -ENODEV;
5250 }
5251
5252 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005253 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305255
5256 /* Disable TX on the interface, after this hard_start_xmit() will not
5257 * be called on that interface
5258 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005259 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305260
5261 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005262 netif_carrier_off(pAdapter->dev);
5263
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305264 /* The interface is marked as down for outside world (aka kernel)
5265 * But the driver is pretty much alive inside. The driver needs to
5266 * tear down the existing connection on the netdev (session)
5267 * cleanup the data pipes and wait until the control plane is stabilized
5268 * for this interface. The call also needs to wait until the above
5269 * mentioned actions are completed before returning to the caller.
5270 * Notice that the hdd_stop_adapter is requested not to close the session
5271 * That is intentional to be able to scan if it is a STA/P2P interface
5272 */
5273 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07005274
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305275 /* DeInit the adapter. This ensures datapath cleanup as well */
5276 hdd_deinit_adapter(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005277 /* SoftAP ifaces should never go in power save mode
5278 making sure same here. */
5279 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5280 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005281 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005282 )
5283 {
5284 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5286 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005287 EXIT();
5288 return 0;
5289 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305290 /* Find if any iface is up. If any iface is up then can't put device to
5291 * sleep/power save mode
5292 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005293 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5294 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5295 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005296 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5297 {
5298 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305299 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005300 enter_standby = FALSE;
5301 break;
5302 }
5303 else
5304 {
5305 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5306 pAdapterNode = pNext;
5307 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005308 }
5309
5310 if (TRUE == enter_standby)
5311 {
5312 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5313 "entering standby", __func__);
5314 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5315 {
5316 /*log and return success*/
5317 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5318 "wlan in power save", __func__);
5319 }
5320 }
5321
5322 EXIT();
5323 return 0;
5324}
5325
5326/**---------------------------------------------------------------------------
5327
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305328 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005329
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305330 This is called in response to ifconfig down
5331
5332 \param - dev Pointer to net_device structure
5333
5334 \return - 0 for success non-zero for failure
5335-----------------------------------------------------------------------------*/
5336int hdd_stop (struct net_device *dev)
5337{
5338 int ret;
5339
5340 vos_ssr_protect(__func__);
5341 ret = __hdd_stop(dev);
5342 vos_ssr_unprotect(__func__);
5343
5344 return ret;
5345}
5346
5347/**---------------------------------------------------------------------------
5348
5349 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005350
5351 \param - dev Pointer to net_device structure
5352
5353 \return - void
5354
5355 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305356static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005357{
5358 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5359
5360 ENTER();
5361
5362 do
5363 {
5364 if (NULL == pAdapter)
5365 {
5366 hddLog(VOS_TRACE_LEVEL_FATAL,
5367 "%s: NULL pAdapter", __func__);
5368 break;
5369 }
5370
5371 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5372 {
5373 hddLog(VOS_TRACE_LEVEL_FATAL,
5374 "%s: Invalid magic", __func__);
5375 break;
5376 }
5377
5378 if (NULL == pAdapter->pHddCtx)
5379 {
5380 hddLog(VOS_TRACE_LEVEL_FATAL,
5381 "%s: NULL pHddCtx", __func__);
5382 break;
5383 }
5384
5385 if (dev != pAdapter->dev)
5386 {
5387 hddLog(VOS_TRACE_LEVEL_FATAL,
5388 "%s: Invalid device reference", __func__);
5389 /* we haven't validated all cases so let this go for now */
5390 }
5391
5392 hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter);
5393
5394 /* after uninit our adapter structure will no longer be valid */
5395 pAdapter->dev = NULL;
5396 pAdapter->magic = 0;
5397 } while (0);
5398
5399 EXIT();
5400}
5401
5402/**---------------------------------------------------------------------------
5403
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305404 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5405
5406 This is called during the netdev unregister to uninitialize all data
5407associated with the device
5408
5409 \param - dev Pointer to net_device structure
5410
5411 \return - void
5412
5413 --------------------------------------------------------------------------*/
5414static void hdd_uninit (struct net_device *dev)
5415{
5416 vos_ssr_protect(__func__);
5417 __hdd_uninit(dev);
5418 vos_ssr_unprotect(__func__);
5419}
5420
5421/**---------------------------------------------------------------------------
5422
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 \brief hdd_release_firmware() -
5424
5425 This function calls the release firmware API to free the firmware buffer.
5426
5427 \param - pFileName Pointer to the File Name.
5428 pCtx - Pointer to the adapter .
5429
5430
5431 \return - 0 for success, non zero for failure
5432
5433 --------------------------------------------------------------------------*/
5434
5435VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5436{
5437 VOS_STATUS status = VOS_STATUS_SUCCESS;
5438 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5439 ENTER();
5440
5441
5442 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5443
5444 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5445
5446 if(pHddCtx->fw) {
5447 release_firmware(pHddCtx->fw);
5448 pHddCtx->fw = NULL;
5449 }
5450 else
5451 status = VOS_STATUS_E_FAILURE;
5452 }
5453 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5454 if(pHddCtx->nv) {
5455 release_firmware(pHddCtx->nv);
5456 pHddCtx->nv = NULL;
5457 }
5458 else
5459 status = VOS_STATUS_E_FAILURE;
5460
5461 }
5462
5463 EXIT();
5464 return status;
5465}
5466
5467/**---------------------------------------------------------------------------
5468
5469 \brief hdd_request_firmware() -
5470
5471 This function reads the firmware file using the request firmware
5472 API and returns the the firmware data and the firmware file size.
5473
5474 \param - pfileName - Pointer to the file name.
5475 - pCtx - Pointer to the adapter .
5476 - ppfw_data - Pointer to the pointer of the firmware data.
5477 - pSize - Pointer to the file size.
5478
5479 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5480
5481 --------------------------------------------------------------------------*/
5482
5483
5484VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5485{
5486 int status;
5487 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5488 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5489 ENTER();
5490
5491 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5492
5493 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5494
5495 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5496 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5497 __func__, pfileName);
5498 retval = VOS_STATUS_E_FAILURE;
5499 }
5500
5501 else {
5502 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5503 *pSize = pHddCtx->fw->size;
5504 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5505 __func__, *pSize);
5506 }
5507 }
5508 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5509
5510 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5511
5512 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5513 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5514 __func__, pfileName);
5515 retval = VOS_STATUS_E_FAILURE;
5516 }
5517
5518 else {
5519 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5520 *pSize = pHddCtx->nv->size;
5521 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5522 __func__, *pSize);
5523 }
5524 }
5525
5526 EXIT();
5527 return retval;
5528}
5529/**---------------------------------------------------------------------------
5530 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5531
5532 This is the function invoked by SME to inform the result of a full power
5533 request issued by HDD
5534
5535 \param - callbackcontext - Pointer to cookie
5536 status - result of request
5537
5538 \return - None
5539
5540--------------------------------------------------------------------------*/
5541void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5542{
5543 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5544
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005545 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005546 if(&pHddCtx->full_pwr_comp_var)
5547 {
5548 complete(&pHddCtx->full_pwr_comp_var);
5549 }
5550}
5551
5552/**---------------------------------------------------------------------------
5553
5554 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5555
5556 This is the function invoked by SME to inform the result of BMPS
5557 request issued by HDD
5558
5559 \param - callbackcontext - Pointer to cookie
5560 status - result of request
5561
5562 \return - None
5563
5564--------------------------------------------------------------------------*/
5565void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5566{
5567
5568 struct completion *completion_var = (struct completion*) callbackContext;
5569
Arif Hussain6d2a3322013-11-17 19:50:10 -08005570 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005571 if(completion_var != NULL)
5572 {
5573 complete(completion_var);
5574 }
5575}
5576
5577/**---------------------------------------------------------------------------
5578
5579 \brief hdd_get_cfg_file_size() -
5580
5581 This function reads the configuration file using the request firmware
5582 API and returns the configuration file size.
5583
5584 \param - pCtx - Pointer to the adapter .
5585 - pFileName - Pointer to the file name.
5586 - pBufSize - Pointer to the buffer size.
5587
5588 \return - 0 for success, non zero for failure
5589
5590 --------------------------------------------------------------------------*/
5591
5592VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5593{
5594 int status;
5595 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5596
5597 ENTER();
5598
5599 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5600
5601 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5602 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5603 status = VOS_STATUS_E_FAILURE;
5604 }
5605 else {
5606 *pBufSize = pHddCtx->fw->size;
5607 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5608 release_firmware(pHddCtx->fw);
5609 pHddCtx->fw = NULL;
5610 }
5611
5612 EXIT();
5613 return VOS_STATUS_SUCCESS;
5614}
5615
5616/**---------------------------------------------------------------------------
5617
5618 \brief hdd_read_cfg_file() -
5619
5620 This function reads the configuration file using the request firmware
5621 API and returns the cfg data and the buffer size of the configuration file.
5622
5623 \param - pCtx - Pointer to the adapter .
5624 - pFileName - Pointer to the file name.
5625 - pBuffer - Pointer to the data buffer.
5626 - pBufSize - Pointer to the buffer size.
5627
5628 \return - 0 for success, non zero for failure
5629
5630 --------------------------------------------------------------------------*/
5631
5632VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5633 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5634{
5635 int status;
5636 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5637
5638 ENTER();
5639
5640 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5641
5642 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5643 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5644 return VOS_STATUS_E_FAILURE;
5645 }
5646 else {
5647 if(*pBufSize != pHddCtx->fw->size) {
5648 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5649 "file size", __func__);
5650 release_firmware(pHddCtx->fw);
5651 pHddCtx->fw = NULL;
5652 return VOS_STATUS_E_FAILURE;
5653 }
5654 else {
5655 if(pBuffer) {
5656 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5657 }
5658 release_firmware(pHddCtx->fw);
5659 pHddCtx->fw = NULL;
5660 }
5661 }
5662
5663 EXIT();
5664
5665 return VOS_STATUS_SUCCESS;
5666}
5667
5668/**---------------------------------------------------------------------------
5669
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305670 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005671
5672 This function sets the user specified mac address using
5673 the command ifconfig wlanX hw ether <mac adress>.
5674
5675 \param - dev - Pointer to the net device.
5676 - addr - Pointer to the sockaddr.
5677 \return - 0 for success, non zero for failure
5678
5679 --------------------------------------------------------------------------*/
5680
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305681static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005682{
5683 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5684 struct sockaddr *psta_mac_addr = addr;
5685 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5686
5687 ENTER();
5688
5689 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005690 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5691
5692 EXIT();
5693 return halStatus;
5694}
5695
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305696/**---------------------------------------------------------------------------
5697
5698 \brief hdd_set_mac_address() -
5699
5700 Wrapper function to protect __hdd_set_mac_address() function from ssr
5701
5702 \param - dev - Pointer to the net device.
5703 - addr - Pointer to the sockaddr.
5704 \return - 0 for success, non zero for failure
5705
5706 --------------------------------------------------------------------------*/
5707static int hdd_set_mac_address(struct net_device *dev, void *addr)
5708{
5709 int ret;
5710
5711 vos_ssr_protect(__func__);
5712 ret = __hdd_set_mac_address(dev, addr);
5713 vos_ssr_unprotect(__func__);
5714
5715 return ret;
5716}
5717
Jeff Johnson295189b2012-06-20 16:38:30 -07005718tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5719{
5720 int i;
5721 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5722 {
Abhishek Singheb183782014-02-06 13:37:21 +05305723 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 break;
5725 }
5726
5727 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5728 return NULL;
5729
5730 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5731 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5732}
5733
5734void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5735{
5736 int i;
5737 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5738 {
5739 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5740 {
5741 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5742 break;
5743 }
5744 }
5745 return;
5746}
5747
5748#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5749 static struct net_device_ops wlan_drv_ops = {
5750 .ndo_open = hdd_open,
5751 .ndo_stop = hdd_stop,
5752 .ndo_uninit = hdd_uninit,
5753 .ndo_start_xmit = hdd_hard_start_xmit,
5754 .ndo_tx_timeout = hdd_tx_timeout,
5755 .ndo_get_stats = hdd_stats,
5756 .ndo_do_ioctl = hdd_ioctl,
5757 .ndo_set_mac_address = hdd_set_mac_address,
5758 .ndo_select_queue = hdd_select_queue,
5759#ifdef WLAN_FEATURE_PACKET_FILTERING
5760#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5761 .ndo_set_rx_mode = hdd_set_multicast_list,
5762#else
5763 .ndo_set_multicast_list = hdd_set_multicast_list,
5764#endif //LINUX_VERSION_CODE
5765#endif
5766 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005767 static struct net_device_ops wlan_mon_drv_ops = {
5768 .ndo_open = hdd_mon_open,
5769 .ndo_stop = hdd_stop,
5770 .ndo_uninit = hdd_uninit,
5771 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5772 .ndo_tx_timeout = hdd_tx_timeout,
5773 .ndo_get_stats = hdd_stats,
5774 .ndo_do_ioctl = hdd_ioctl,
5775 .ndo_set_mac_address = hdd_set_mac_address,
5776 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005777
5778#endif
5779
5780void hdd_set_station_ops( struct net_device *pWlanDev )
5781{
5782#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07005783 pWlanDev->netdev_ops = &wlan_drv_ops;
5784#else
5785 pWlanDev->open = hdd_open;
5786 pWlanDev->stop = hdd_stop;
5787 pWlanDev->uninit = hdd_uninit;
5788 pWlanDev->hard_start_xmit = NULL;
5789 pWlanDev->tx_timeout = hdd_tx_timeout;
5790 pWlanDev->get_stats = hdd_stats;
5791 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 pWlanDev->set_mac_address = hdd_set_mac_address;
5793#endif
5794}
5795
Jeff Johnsoneed415b2013-01-18 16:11:20 -08005796static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07005797{
5798 struct net_device *pWlanDev = NULL;
5799 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005800 /*
5801 * cfg80211 initialization and registration....
5802 */
5803 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
5804
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 if(pWlanDev != NULL)
5806 {
5807
5808 //Save the pointer to the net_device in the HDD adapter
5809 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
5810
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
5812
5813 pAdapter->dev = pWlanDev;
5814 pAdapter->pHddCtx = pHddCtx;
5815 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05305816 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07005817
5818 init_completion(&pAdapter->session_open_comp_var);
5819 init_completion(&pAdapter->session_close_comp_var);
5820 init_completion(&pAdapter->disconnect_comp_var);
5821 init_completion(&pAdapter->linkup_event_var);
5822 init_completion(&pAdapter->cancel_rem_on_chan_var);
5823 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05305824 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005825#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
5826 init_completion(&pAdapter->offchannel_tx_event);
5827#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005828 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005829#ifdef FEATURE_WLAN_TDLS
5830 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07005831 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08005832 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05305833 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005834#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 init_completion(&pHddCtx->mc_sus_event_var);
5836 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05305837 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07005838 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07005839 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07005840
Rajeev79dbe4c2013-10-05 11:03:42 +05305841#ifdef FEATURE_WLAN_BATCH_SCAN
5842 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
5843 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
5844 pAdapter->pBatchScanRsp = NULL;
5845 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07005846 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005847 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05305848 mutex_init(&pAdapter->hdd_batch_scan_lock);
5849#endif
5850
Jeff Johnson295189b2012-06-20 16:38:30 -07005851 pAdapter->isLinkUpSvcNeeded = FALSE;
5852 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
5853 //Init the net_device structure
5854 strlcpy(pWlanDev->name, name, IFNAMSIZ);
5855
5856 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
5857 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
5858 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
5859 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
5860
5861 hdd_set_station_ops( pAdapter->dev );
5862
5863 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
5865 pAdapter->wdev.wiphy = pHddCtx->wiphy;
5866 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07005867 /* set pWlanDev's parent to underlying device */
5868 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07005869
5870 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07005871 }
5872
5873 return pAdapter;
5874}
5875
5876VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
5877{
5878 struct net_device *pWlanDev = pAdapter->dev;
5879 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5880 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5881 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5882
5883 if( rtnl_lock_held )
5884 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08005885 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
5887 {
5888 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
5889 return VOS_STATUS_E_FAILURE;
5890 }
5891 }
5892 if (register_netdevice(pWlanDev))
5893 {
5894 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
5895 return VOS_STATUS_E_FAILURE;
5896 }
5897 }
5898 else
5899 {
5900 if(register_netdev(pWlanDev))
5901 {
5902 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
5903 return VOS_STATUS_E_FAILURE;
5904 }
5905 }
5906 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
5907
5908 return VOS_STATUS_SUCCESS;
5909}
5910
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005911static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07005912{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005913 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07005914
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005915 if (NULL == pAdapter)
5916 {
5917 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
5918 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07005919 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005920
5921 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5922 {
5923 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
5924 return eHAL_STATUS_NOT_INITIALIZED;
5925 }
5926
5927 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
5928
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005929#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005930 /* need to make sure all of our scheduled work has completed.
5931 * This callback is called from MC thread context, so it is safe to
5932 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005933 *
5934 * Even though this is called from MC thread context, if there is a faulty
5935 * work item in the system, that can hang this call forever. So flushing
5936 * this global work queue is not safe; and now we make sure that
5937 * individual work queues are stopped correctly. But the cancel work queue
5938 * is a GPL only API, so the proprietary version of the driver would still
5939 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005940 */
5941 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07005942#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07005943
5944 /* We can be blocked while waiting for scheduled work to be
5945 * flushed, and the adapter structure can potentially be freed, in
5946 * which case the magic will have been reset. So make sure the
5947 * magic is still good, and hence the adapter structure is still
5948 * valid, before signaling completion */
5949 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
5950 {
5951 complete(&pAdapter->session_close_comp_var);
5952 }
5953
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 return eHAL_STATUS_SUCCESS;
5955}
5956
5957VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
5958{
5959 struct net_device *pWlanDev = pAdapter->dev;
5960 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
5961 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5962 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5963 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305964 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005965
5966 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005967 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005968 //Open a SME session for future operation
5969 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07005970 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005971 if ( !HAL_STATUS_SUCCESS( halStatus ) )
5972 {
5973 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005974 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 halStatus, halStatus );
5976 status = VOS_STATUS_E_FAILURE;
5977 goto error_sme_open;
5978 }
5979
5980 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05305981 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 &pAdapter->session_open_comp_var,
5983 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305984 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 {
5986 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305987 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 status = VOS_STATUS_E_FAILURE;
5989 goto error_sme_open;
5990 }
5991
5992 // Register wireless extensions
5993 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
5994 {
5995 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07005996 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005997 halStatus, halStatus );
5998 status = VOS_STATUS_E_FAILURE;
5999 goto error_register_wext;
6000 }
6001 //Safe to register the hard_start_xmit function again
6002#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6003 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6004#else
6005 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6006#endif
6007
6008 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306009 hddLog(VOS_TRACE_LEVEL_INFO,
6010 "%s: Set HDD connState to eConnectionState_NotConnected",
6011 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6013
6014 //Set the default operation channel
6015 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6016
6017 /* Make the default Auth Type as OPEN*/
6018 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6019
6020 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6021 {
6022 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006023 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 status, status );
6025 goto error_init_txrx;
6026 }
6027
6028 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6029
6030 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6031 {
6032 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006033 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 status, status );
6035 goto error_wmm_init;
6036 }
6037
6038 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6039
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006040#ifdef FEATURE_WLAN_TDLS
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306041 if(0 != wlan_hdd_sta_tdls_init(pAdapter))
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006042 {
6043 status = VOS_STATUS_E_FAILURE;
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306044 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006045 goto error_tdls_init;
6046 }
6047 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
6048#endif
6049
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 return VOS_STATUS_SUCCESS;
6051
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006052#ifdef FEATURE_WLAN_TDLS
6053error_tdls_init:
6054 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6055 hdd_wmm_adapter_close(pAdapter);
6056#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006057error_wmm_init:
6058 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6059 hdd_deinit_tx_rx(pAdapter);
6060error_init_txrx:
6061 hdd_UnregisterWext(pWlanDev);
6062error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006063 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006064 {
6065 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006066 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006068 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006069 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306070 unsigned long rc;
6071
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306073 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006075 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306076 if (rc <= 0)
6077 hddLog(VOS_TRACE_LEVEL_ERROR,
6078 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 }
6080}
6081error_sme_open:
6082 return status;
6083}
6084
Jeff Johnson295189b2012-06-20 16:38:30 -07006085void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6086{
6087 hdd_cfg80211_state_t *cfgState;
6088
6089 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6090
6091 if( NULL != cfgState->buf )
6092 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306093 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6095 rc = wait_for_completion_interruptible_timeout(
6096 &pAdapter->tx_action_cnf_event,
6097 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306098 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306101 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6102 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006103 }
6104 }
6105 return;
6106}
Jeff Johnson295189b2012-06-20 16:38:30 -07006107
6108void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6109{
6110 ENTER();
6111 switch ( pAdapter->device_mode )
6112 {
6113 case WLAN_HDD_INFRA_STATION:
6114 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006115 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006116 {
6117 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6118 {
6119 hdd_deinit_tx_rx( pAdapter );
6120 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6121 }
6122
6123 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6124 {
6125 hdd_wmm_adapter_close( pAdapter );
6126 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6127 }
6128
Jeff Johnson295189b2012-06-20 16:38:30 -07006129 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006130#ifdef FEATURE_WLAN_TDLS
6131 if(test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
6132 {
6133 wlan_hdd_tdls_exit(pAdapter);
6134 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
6135 }
6136#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006137
6138 break;
6139 }
6140
6141 case WLAN_HDD_SOFTAP:
6142 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006143 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306144
6145 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6146 {
6147 hdd_wmm_adapter_close( pAdapter );
6148 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6149 }
6150
Jeff Johnson295189b2012-06-20 16:38:30 -07006151 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006152
6153 hdd_unregister_hostapd(pAdapter);
6154 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006155 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006156 break;
6157 }
6158
6159 case WLAN_HDD_MONITOR:
6160 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006161 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006162 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6163 {
6164 hdd_deinit_tx_rx( pAdapter );
6165 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6166 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 if(NULL != pAdapterforTx)
6168 {
6169 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6170 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006171 break;
6172 }
6173
6174
6175 default:
6176 break;
6177 }
6178
6179 EXIT();
6180}
6181
6182void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6183{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006184 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306185
6186 ENTER();
6187 if (NULL == pAdapter)
6188 {
6189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6190 "%s: HDD adapter is Null", __func__);
6191 return;
6192 }
6193
6194 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006195
Rajeev79dbe4c2013-10-05 11:03:42 +05306196#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306197 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6198 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006199 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306200 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6201 )
6202 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006203 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306204 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006205 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6206 {
6207 hdd_deinit_batch_scan(pAdapter);
6208 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306209 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006210 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306211#endif
6212
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6214 if( rtnl_held )
6215 {
6216 unregister_netdevice(pWlanDev);
6217 }
6218 else
6219 {
6220 unregister_netdev(pWlanDev);
6221 }
6222 // note that the pAdapter is no longer valid at this point
6223 // since the memory has been reclaimed
6224 }
6225
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306226 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006227}
6228
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006229void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6230{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306231 VOS_STATUS status;
6232 hdd_adapter_t *pAdapter = NULL;
6233 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006234
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306235 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006236
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306237 /*loop through all adapters.*/
6238 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006239 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306240 pAdapter = pAdapterNode->pAdapter;
6241 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6242 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006243
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306244 { // we skip this registration for modes other than STA and P2P client modes.
6245 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6246 pAdapterNode = pNext;
6247 continue;
6248 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006249
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306250 //Apply Dynamic DTIM For P2P
6251 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6252 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6253 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6254 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6255 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6256 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6257 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6258 (eConnectionState_Associated ==
6259 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6260 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6261 {
6262 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006263
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306264 powerRequest.uIgnoreDTIM = 1;
6265 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6266
6267 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6268 {
6269 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6270 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6271 }
6272 else
6273 {
6274 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6275 }
6276
6277 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6278 * specified during Enter/Exit BMPS when LCD off*/
6279 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6280 NULL, eANI_BOOLEAN_FALSE);
6281 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6282 NULL, eANI_BOOLEAN_FALSE);
6283
6284 /* switch to the DTIM specified in cfg.ini */
6285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6286 "Switch to DTIM %d", powerRequest.uListenInterval);
6287 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6288 break;
6289
6290 }
6291
6292 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6293 pAdapterNode = pNext;
6294 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006295}
6296
6297void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6298{
6299 /*Switch back to DTIM 1*/
6300 tSirSetPowerParamsReq powerRequest = { 0 };
6301
6302 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6303 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006304 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006305
6306 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6307 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6308 NULL, eANI_BOOLEAN_FALSE);
6309 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6310 NULL, eANI_BOOLEAN_FALSE);
6311
6312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6313 "Switch to DTIM%d",powerRequest.uListenInterval);
6314 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6315
6316}
6317
Jeff Johnson295189b2012-06-20 16:38:30 -07006318VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6319{
6320 VOS_STATUS status = VOS_STATUS_SUCCESS;
6321
6322 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6323 {
6324 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6325 }
6326
6327 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6328 {
6329 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6330 }
6331
6332 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6333 {
6334 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6335 }
6336
6337 return status;
6338}
6339
6340VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6341{
6342 hdd_adapter_t *pAdapter = NULL;
6343 eHalStatus halStatus;
6344 VOS_STATUS status = VOS_STATUS_E_INVAL;
6345 v_BOOL_t disableBmps = FALSE;
6346 v_BOOL_t disableImps = FALSE;
6347
6348 switch(session_type)
6349 {
6350 case WLAN_HDD_INFRA_STATION:
6351 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 case WLAN_HDD_P2P_CLIENT:
6353 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 //Exit BMPS -> Is Sta/P2P Client is already connected
6355 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6356 if((NULL != pAdapter)&&
6357 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6358 {
6359 disableBmps = TRUE;
6360 }
6361
6362 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6363 if((NULL != pAdapter)&&
6364 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6365 {
6366 disableBmps = TRUE;
6367 }
6368
6369 //Exit both Bmps and Imps incase of Go/SAP Mode
6370 if((WLAN_HDD_SOFTAP == session_type) ||
6371 (WLAN_HDD_P2P_GO == session_type))
6372 {
6373 disableBmps = TRUE;
6374 disableImps = TRUE;
6375 }
6376
6377 if(TRUE == disableImps)
6378 {
6379 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6380 {
6381 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6382 }
6383 }
6384
6385 if(TRUE == disableBmps)
6386 {
6387 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6388 {
6389 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6390
6391 if(eHAL_STATUS_SUCCESS != halStatus)
6392 {
6393 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006394 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 VOS_ASSERT(0);
6396 return status;
6397 }
6398 }
6399
6400 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6401 {
6402 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6403
6404 if(eHAL_STATUS_SUCCESS != halStatus)
6405 {
6406 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006407 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 VOS_ASSERT(0);
6409 return status;
6410 }
6411 }
6412 }
6413
6414 if((TRUE == disableBmps) ||
6415 (TRUE == disableImps))
6416 {
6417 /* Now, get the chip into Full Power now */
6418 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6419 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6420 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6421
6422 if(halStatus != eHAL_STATUS_SUCCESS)
6423 {
6424 if(halStatus == eHAL_STATUS_PMC_PENDING)
6425 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306426 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306428 ret = wait_for_completion_interruptible_timeout(
6429 &pHddCtx->full_pwr_comp_var,
6430 msecs_to_jiffies(1000));
6431 if (ret <= 0)
6432 {
6433 hddLog(VOS_TRACE_LEVEL_ERROR,
6434 "%s: wait on full_pwr_comp_var failed %ld",
6435 __func__, ret);
6436 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006437 }
6438 else
6439 {
6440 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006441 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 VOS_ASSERT(0);
6443 return status;
6444 }
6445 }
6446
6447 status = VOS_STATUS_SUCCESS;
6448 }
6449
6450 break;
6451 }
6452 return status;
6453}
6454
6455hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006456 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 tANI_U8 rtnl_held )
6458{
6459 hdd_adapter_t *pAdapter = NULL;
6460 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6461 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6462 VOS_STATUS exitbmpsStatus;
6463
Arif Hussain6d2a3322013-11-17 19:50:10 -08006464 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006465
Nirav Shah436658f2014-02-28 17:05:45 +05306466 if(macAddr == NULL)
6467 {
6468 /* Not received valid macAddr */
6469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6470 "%s:Unable to add virtual intf: Not able to get"
6471 "valid mac address",__func__);
6472 return NULL;
6473 }
6474
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 //Disable BMPS incase of Concurrency
6476 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6477
6478 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6479 {
6480 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306481 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 VOS_ASSERT(0);
6483 return NULL;
6484 }
6485
6486 switch(session_type)
6487 {
6488 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006489 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006490 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 {
6492 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6493
6494 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306495 {
6496 hddLog(VOS_TRACE_LEVEL_FATAL,
6497 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006498 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006500
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306501#ifdef FEATURE_WLAN_TDLS
6502 /* A Mutex Lock is introduced while changing/initializing the mode to
6503 * protect the concurrent access for the Adapters by TDLS module.
6504 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306505 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306506#endif
6507
Jeff Johnsone7245742012-09-05 17:12:55 -07006508 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6509 NL80211_IFTYPE_P2P_CLIENT:
6510 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006511
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306513#ifdef FEATURE_WLAN_TDLS
6514 mutex_unlock(&pHddCtx->tdls_lock);
6515#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306516
6517 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 if( VOS_STATUS_SUCCESS != status )
6519 goto err_free_netdev;
6520
6521 status = hdd_register_interface( pAdapter, rtnl_held );
6522 if( VOS_STATUS_SUCCESS != status )
6523 {
6524 hdd_deinit_adapter(pHddCtx, pAdapter);
6525 goto err_free_netdev;
6526 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306527
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306528 // Workqueue which gets scheduled in IPv4 notification callback.
6529 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6530
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306531#ifdef WLAN_NS_OFFLOAD
6532 // Workqueue which gets scheduled in IPv6 notification callback.
6533 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6534#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006535 //Stop the Interface TX queue.
6536 netif_tx_disable(pAdapter->dev);
6537 //netif_tx_disable(pWlanDev);
6538 netif_carrier_off(pAdapter->dev);
6539
6540 break;
6541 }
6542
Jeff Johnson295189b2012-06-20 16:38:30 -07006543 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006544 case WLAN_HDD_SOFTAP:
6545 {
6546 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6547 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306548 {
6549 hddLog(VOS_TRACE_LEVEL_FATAL,
6550 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006551 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306552 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006553
Jeff Johnson295189b2012-06-20 16:38:30 -07006554 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6555 NL80211_IFTYPE_AP:
6556 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006557 pAdapter->device_mode = session_type;
6558
6559 status = hdd_init_ap_mode(pAdapter);
6560 if( VOS_STATUS_SUCCESS != status )
6561 goto err_free_netdev;
6562
6563 status = hdd_register_hostapd( pAdapter, rtnl_held );
6564 if( VOS_STATUS_SUCCESS != status )
6565 {
6566 hdd_deinit_adapter(pHddCtx, pAdapter);
6567 goto err_free_netdev;
6568 }
6569
6570 netif_tx_disable(pAdapter->dev);
6571 netif_carrier_off(pAdapter->dev);
6572
6573 hdd_set_conparam( 1 );
6574 break;
6575 }
6576 case WLAN_HDD_MONITOR:
6577 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006578 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6579 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306580 {
6581 hddLog(VOS_TRACE_LEVEL_FATAL,
6582 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006583 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006585
6586 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6587 pAdapter->device_mode = session_type;
6588 status = hdd_register_interface( pAdapter, rtnl_held );
6589#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6590 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6591#else
6592 pAdapter->dev->open = hdd_mon_open;
6593 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6594#endif
6595 hdd_init_tx_rx( pAdapter );
6596 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6597 //Set adapter to be used for data tx. It will use either GO or softap.
6598 pAdapter->sessionCtx.monitor.pAdapterForTx =
6599 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006600 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6601 {
6602 pAdapter->sessionCtx.monitor.pAdapterForTx =
6603 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6604 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006605 /* This workqueue will be used to transmit management packet over
6606 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006607 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6608 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6609 return NULL;
6610 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006611
Jeff Johnson295189b2012-06-20 16:38:30 -07006612 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6613 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 }
6615 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006616 case WLAN_HDD_FTM:
6617 {
6618 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6619
6620 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306621 {
6622 hddLog(VOS_TRACE_LEVEL_FATAL,
6623 FL("failed to allocate adapter for session %d"), session_type);
6624 return NULL;
6625 }
6626
Jeff Johnson295189b2012-06-20 16:38:30 -07006627 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6628 * message while loading driver in FTM mode. */
6629 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6630 pAdapter->device_mode = session_type;
6631 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306632
6633 hdd_init_tx_rx( pAdapter );
6634
6635 //Stop the Interface TX queue.
6636 netif_tx_disable(pAdapter->dev);
6637 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006638 }
6639 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006640 default:
6641 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306642 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6643 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006644 VOS_ASSERT(0);
6645 return NULL;
6646 }
6647 }
6648
Jeff Johnson295189b2012-06-20 16:38:30 -07006649 if( VOS_STATUS_SUCCESS == status )
6650 {
6651 //Add it to the hdd's session list.
6652 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6653 if( NULL == pHddAdapterNode )
6654 {
6655 status = VOS_STATUS_E_NOMEM;
6656 }
6657 else
6658 {
6659 pHddAdapterNode->pAdapter = pAdapter;
6660 status = hdd_add_adapter_back ( pHddCtx,
6661 pHddAdapterNode );
6662 }
6663 }
6664
6665 if( VOS_STATUS_SUCCESS != status )
6666 {
6667 if( NULL != pAdapter )
6668 {
6669 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6670 pAdapter = NULL;
6671 }
6672 if( NULL != pHddAdapterNode )
6673 {
6674 vos_mem_free( pHddAdapterNode );
6675 }
6676
6677 goto resume_bmps;
6678 }
6679
6680 if(VOS_STATUS_SUCCESS == status)
6681 {
6682 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6683
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006684 //Initialize the WoWL service
6685 if(!hdd_init_wowl(pAdapter))
6686 {
6687 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6688 goto err_free_netdev;
6689 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006690 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006691 return pAdapter;
6692
6693err_free_netdev:
6694 free_netdev(pAdapter->dev);
6695 wlan_hdd_release_intf_addr( pHddCtx,
6696 pAdapter->macAddressCurrent.bytes );
6697
6698resume_bmps:
6699 //If bmps disabled enable it
6700 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6701 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306702 if (pHddCtx->hdd_wlan_suspended)
6703 {
6704 hdd_set_pwrparams(pHddCtx);
6705 }
6706 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006707 }
6708 return NULL;
6709}
6710
6711VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6712 tANI_U8 rtnl_held )
6713{
6714 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6715 VOS_STATUS status;
6716
6717 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6718 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306719 {
6720 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6721 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306723 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006724
6725 while ( pCurrent->pAdapter != pAdapter )
6726 {
6727 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6728 if( VOS_STATUS_SUCCESS != status )
6729 break;
6730
6731 pCurrent = pNext;
6732 }
6733 pAdapterNode = pCurrent;
6734 if( VOS_STATUS_SUCCESS == status )
6735 {
6736 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6737 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306738
6739#ifdef FEATURE_WLAN_TDLS
6740
6741 /* A Mutex Lock is introduced while changing/initializing the mode to
6742 * protect the concurrent access for the Adapters by TDLS module.
6743 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306744 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306745#endif
6746
Jeff Johnson295189b2012-06-20 16:38:30 -07006747 hdd_remove_adapter( pHddCtx, pAdapterNode );
6748 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006749 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006750
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306751#ifdef FEATURE_WLAN_TDLS
6752 mutex_unlock(&pHddCtx->tdls_lock);
6753#endif
6754
Jeff Johnson295189b2012-06-20 16:38:30 -07006755
6756 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306757 if ((!vos_concurrent_open_sessions_running()) &&
6758 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6759 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306761 if (pHddCtx->hdd_wlan_suspended)
6762 {
6763 hdd_set_pwrparams(pHddCtx);
6764 }
6765 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006766 }
6767
6768 return VOS_STATUS_SUCCESS;
6769 }
6770
6771 return VOS_STATUS_E_FAILURE;
6772}
6773
6774VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
6775{
6776 hdd_adapter_list_node_t *pHddAdapterNode;
6777 VOS_STATUS status;
6778
6779 ENTER();
6780
6781 do
6782 {
6783 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
6784 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
6785 {
6786 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
6787 vos_mem_free( pHddAdapterNode );
6788 }
6789 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
6790
6791 EXIT();
6792
6793 return VOS_STATUS_SUCCESS;
6794}
6795
6796void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
6797{
6798 v_U8_t addIE[1] = {0};
6799
6800 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6801 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
6802 eANI_BOOLEAN_FALSE) )
6803 {
6804 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006805 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 }
6807
6808 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6809 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6810 eANI_BOOLEAN_FALSE) )
6811 {
6812 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006813 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006814 }
6815
6816 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6817 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6818 eANI_BOOLEAN_FALSE) )
6819 {
6820 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006821 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 }
6823}
6824
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306825VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6826 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07006827{
6828 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6829 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05306830 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306832 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306833 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006834
6835 ENTER();
Kaushik, Sushant4975a572014-10-21 16:07:48 +05306836 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07006837 switch(pAdapter->device_mode)
6838 {
6839 case WLAN_HDD_INFRA_STATION:
6840 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006841 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306842 {
6843 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6844 if( hdd_connIsConnected(pstation) ||
6845 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 {
6847 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
6848 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6849 pAdapter->sessionId,
6850 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6851 else
6852 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
6853 pAdapter->sessionId,
6854 eCSR_DISCONNECT_REASON_UNSPECIFIED);
6855 //success implies disconnect command got queued up successfully
6856 if(halStatus == eHAL_STATUS_SUCCESS)
6857 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306858 ret = wait_for_completion_interruptible_timeout(
6859 &pAdapter->disconnect_comp_var,
6860 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6861 if (ret <= 0)
6862 {
6863 hddLog(VOS_TRACE_LEVEL_ERROR,
6864 "%s: wait on disconnect_comp_var failed %ld",
6865 __func__, ret);
6866 }
6867 }
6868 else
6869 {
6870 hddLog(LOGE, "%s: failed to post disconnect event to SME",
6871 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 }
6873 memset(&wrqu, '\0', sizeof(wrqu));
6874 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6875 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
6876 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
6877 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306878 else if(pstation->conn_info.connState ==
6879 eConnectionState_Disconnecting)
6880 {
6881 ret = wait_for_completion_interruptible_timeout(
6882 &pAdapter->disconnect_comp_var,
6883 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6884 if (ret <= 0)
6885 {
6886 hddLog(VOS_TRACE_LEVEL_ERROR,
6887 FL("wait on disconnect_comp_var failed %ld"), ret);
6888 }
6889 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05306890 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07006891 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05306892 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306893 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306895 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
6896 {
6897 while (pAdapter->is_roc_inprogress)
6898 {
6899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6900 "%s: ROC in progress for session %d!!!",
6901 __func__, pAdapter->sessionId);
6902 // waiting for ROC to expire
6903 msleep(500);
6904 /* In GO present case , if retry exceeds 3,
6905 it means something went wrong. */
6906 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
6907 {
6908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6909 "%s: ROC completion is not received.!!!", __func__);
6910 sme_CancelRemainOnChannel(WLAN_HDD_GET_HAL_CTX(pAdapter),
6911 pAdapter->sessionId);
6912 wait_for_completion_interruptible_timeout(
6913 &pAdapter->cancel_rem_on_chan_var,
6914 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6915 break;
6916 }
6917 }
6918 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306919#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306920#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306921 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
6922#endif
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05306923 if (pAdapter->ipv6_notifier_registered)
6924 {
6925 hddLog(LOG1, FL("Unregistered IPv6 notifier"));
6926 unregister_inet6addr_notifier(&pAdapter->ipv6_notifier);
6927 pAdapter->ipv6_notifier_registered = false;
6928 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306929#endif
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +05306930 if (pAdapter->ipv4_notifier_registered)
6931 {
6932 hddLog(LOG1, FL("Unregistered IPv4 notifier"));
6933 unregister_inetaddr_notifier(&pAdapter->ipv4_notifier);
6934 pAdapter->ipv4_notifier_registered = false;
6935 }
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306936#ifdef WLAN_OPEN_SOURCE
6937 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
6938#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306939 /* It is possible that the caller of this function does not
6940 * wish to close the session
6941 */
6942 if (VOS_TRUE == bCloseSession &&
6943 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 {
6945 INIT_COMPLETION(pAdapter->session_close_comp_var);
6946 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306947 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
6948 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306950 unsigned long ret;
6951
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306953 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306954 &pAdapter->session_close_comp_var,
6955 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306956 if ( 0 >= ret)
6957 {
6958 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306959 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 }
6962 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306963 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 break;
6965
6966 case WLAN_HDD_SOFTAP:
6967 case WLAN_HDD_P2P_GO:
6968 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05306969 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
6970 while (pAdapter->is_roc_inprogress) {
6971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6972 "%s: ROC in progress for session %d!!!",
6973 __func__, pAdapter->sessionId);
6974 msleep(500);
6975 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
6976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6977 "%s: ROC completion is not received.!!!", __func__);
6978 WLANSAP_CancelRemainOnChannel(
6979 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
6980 wait_for_completion_interruptible_timeout(
6981 &pAdapter->cancel_rem_on_chan_var,
6982 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
6983 break;
6984 }
6985 }
6986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 mutex_lock(&pHddCtx->sap_lock);
6988 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6989 {
6990 VOS_STATUS status;
6991 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6992
6993 //Stop Bss.
6994 status = WLANSAP_StopBss(pHddCtx->pvosContext);
6995 if (VOS_IS_STATUS_SUCCESS(status))
6996 {
6997 hdd_hostapd_state_t *pHostapdState =
6998 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6999
7000 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7001
7002 if (!VOS_IS_STATUS_SUCCESS(status))
7003 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307004 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7005 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 }
7007 }
7008 else
7009 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007010 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 }
7012 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307013 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007014
7015 if (eHAL_STATUS_FAILURE ==
7016 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7017 0, NULL, eANI_BOOLEAN_FALSE))
7018 {
7019 hddLog(LOGE,
7020 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007021 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007022 }
7023
7024 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7025 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7026 eANI_BOOLEAN_FALSE) )
7027 {
7028 hddLog(LOGE,
7029 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7030 }
7031
7032 // Reset WNI_CFG_PROBE_RSP Flags
7033 wlan_hdd_reset_prob_rspies(pAdapter);
7034 kfree(pAdapter->sessionCtx.ap.beacon);
7035 pAdapter->sessionCtx.ap.beacon = NULL;
7036 }
7037 mutex_unlock(&pHddCtx->sap_lock);
7038 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007039
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007041#ifdef WLAN_OPEN_SOURCE
7042 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7043#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007045
Jeff Johnson295189b2012-06-20 16:38:30 -07007046 default:
7047 break;
7048 }
7049
7050 EXIT();
7051 return VOS_STATUS_SUCCESS;
7052}
7053
7054VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7055{
7056 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7057 VOS_STATUS status;
7058 hdd_adapter_t *pAdapter;
7059
7060 ENTER();
7061
7062 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7063
7064 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7065 {
7066 pAdapter = pAdapterNode->pAdapter;
7067 netif_tx_disable(pAdapter->dev);
7068 netif_carrier_off(pAdapter->dev);
7069
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307070 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007071
7072 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7073 pAdapterNode = pNext;
7074 }
7075
7076 EXIT();
7077
7078 return VOS_STATUS_SUCCESS;
7079}
7080
Rajeev Kumarf999e582014-01-09 17:33:29 -08007081
7082#ifdef FEATURE_WLAN_BATCH_SCAN
7083/**---------------------------------------------------------------------------
7084
7085 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7086 structures
7087
7088 \param - pAdapter Pointer to HDD adapter
7089
7090 \return - None
7091
7092 --------------------------------------------------------------------------*/
7093void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7094{
7095 tHddBatchScanRsp *pNode;
7096 tHddBatchScanRsp *pPrev;
7097
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307098 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007099 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307100 hddLog(VOS_TRACE_LEVEL_ERROR,
7101 "%s: Adapter context is Null", __func__);
7102 return;
7103 }
7104
7105 pNode = pAdapter->pBatchScanRsp;
7106 while (pNode)
7107 {
7108 pPrev = pNode;
7109 pNode = pNode->pNext;
7110 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007111 }
7112
7113 pAdapter->pBatchScanRsp = NULL;
7114 pAdapter->numScanList = 0;
7115 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7116 pAdapter->prev_batch_id = 0;
7117
7118 return;
7119}
7120#endif
7121
7122
Jeff Johnson295189b2012-06-20 16:38:30 -07007123VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7124{
7125 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7126 VOS_STATUS status;
7127 hdd_adapter_t *pAdapter;
7128
7129 ENTER();
7130
7131 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7132
7133 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7134 {
7135 pAdapter = pAdapterNode->pAdapter;
7136 netif_tx_disable(pAdapter->dev);
7137 netif_carrier_off(pAdapter->dev);
7138
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007139 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7140
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307142
7143 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7144
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307145 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7146 {
7147 hdd_wmm_adapter_close( pAdapter );
7148 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007150
Rajeev Kumarf999e582014-01-09 17:33:29 -08007151#ifdef FEATURE_WLAN_BATCH_SCAN
7152 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7153 {
7154 hdd_deinit_batch_scan(pAdapter);
7155 }
7156#endif
7157
Jeff Johnson295189b2012-06-20 16:38:30 -07007158 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7159 pAdapterNode = pNext;
7160 }
7161
7162 EXIT();
7163
7164 return VOS_STATUS_SUCCESS;
7165}
7166
7167VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7168{
7169 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7170 VOS_STATUS status;
7171 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307172 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007173
7174 ENTER();
7175
7176 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7177
7178 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7179 {
7180 pAdapter = pAdapterNode->pAdapter;
7181
Kumar Anand82c009f2014-05-29 00:29:42 -07007182 hdd_wmm_init( pAdapter );
7183
Jeff Johnson295189b2012-06-20 16:38:30 -07007184 switch(pAdapter->device_mode)
7185 {
7186 case WLAN_HDD_INFRA_STATION:
7187 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007188 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307189
7190 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7191
Jeff Johnson295189b2012-06-20 16:38:30 -07007192 hdd_init_station_mode(pAdapter);
7193 /* Open the gates for HDD to receive Wext commands */
7194 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007195 pHddCtx->scan_info.mScanPending = FALSE;
7196 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007197
7198 //Trigger the initial scan
7199 hdd_wlan_initial_scan(pAdapter);
7200
7201 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307202 if (eConnectionState_Associated == connState ||
7203 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007204 {
7205 union iwreq_data wrqu;
7206 memset(&wrqu, '\0', sizeof(wrqu));
7207 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7208 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7209 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007210 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007211
Jeff Johnson295189b2012-06-20 16:38:30 -07007212 /* indicate disconnected event to nl80211 */
7213 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7214 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007215 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307216 else if (eConnectionState_Connecting == connState)
7217 {
7218 /*
7219 * Indicate connect failure to supplicant if we were in the
7220 * process of connecting
7221 */
7222 cfg80211_connect_result(pAdapter->dev, NULL,
7223 NULL, 0, NULL, 0,
7224 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7225 GFP_KERNEL);
7226 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 break;
7228
7229 case WLAN_HDD_SOFTAP:
7230 /* softAP can handle SSR */
7231 break;
7232
7233 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007235 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007236 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 break;
7238
7239 case WLAN_HDD_MONITOR:
7240 /* monitor interface start */
7241 break;
7242 default:
7243 break;
7244 }
7245
7246 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7247 pAdapterNode = pNext;
7248 }
7249
7250 EXIT();
7251
7252 return VOS_STATUS_SUCCESS;
7253}
7254
7255VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7256{
7257 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7258 hdd_adapter_t *pAdapter;
7259 VOS_STATUS status;
7260 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307261 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007262
7263 ENTER();
7264
7265 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7266
7267 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7268 {
7269 pAdapter = pAdapterNode->pAdapter;
7270
7271 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7272 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7273 {
7274 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7275 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7276
Abhishek Singhf4669da2014-05-26 15:07:49 +05307277 hddLog(VOS_TRACE_LEVEL_INFO,
7278 "%s: Set HDD connState to eConnectionState_NotConnected",
7279 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7281 init_completion(&pAdapter->disconnect_comp_var);
7282 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7283 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7284
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307285 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007286 &pAdapter->disconnect_comp_var,
7287 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307288 if (0 >= ret)
7289 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7290 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007291
7292 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7293 pHddCtx->isAmpAllowed = VOS_FALSE;
7294 sme_RoamConnect(pHddCtx->hHal,
7295 pAdapter->sessionId, &(pWextState->roamProfile),
7296 &roamId);
7297 }
7298
7299 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7300 pAdapterNode = pNext;
7301 }
7302
7303 EXIT();
7304
7305 return VOS_STATUS_SUCCESS;
7306}
7307
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007308void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7309{
7310 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7311 VOS_STATUS status;
7312 hdd_adapter_t *pAdapter;
7313 hdd_station_ctx_t *pHddStaCtx;
7314 hdd_ap_ctx_t *pHddApCtx;
7315 hdd_hostapd_state_t * pHostapdState;
7316 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7317 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7318 const char *p2pMode = "DEV";
7319 const char *ccMode = "Standalone";
7320 int n;
7321
7322 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7323 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7324 {
7325 pAdapter = pAdapterNode->pAdapter;
7326 switch (pAdapter->device_mode) {
7327 case WLAN_HDD_INFRA_STATION:
7328 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7329 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7330 staChannel = pHddStaCtx->conn_info.operationChannel;
7331 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7332 }
7333 break;
7334 case WLAN_HDD_P2P_CLIENT:
7335 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7336 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7337 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7338 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7339 p2pMode = "CLI";
7340 }
7341 break;
7342 case WLAN_HDD_P2P_GO:
7343 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7344 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7345 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7346 p2pChannel = pHddApCtx->operatingChannel;
7347 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7348 }
7349 p2pMode = "GO";
7350 break;
7351 case WLAN_HDD_SOFTAP:
7352 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7353 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7354 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7355 apChannel = pHddApCtx->operatingChannel;
7356 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7357 }
7358 break;
7359 default:
7360 break;
7361 }
7362 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7363 pAdapterNode = pNext;
7364 }
7365 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7366 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7367 }
7368 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7369 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7370 if (p2pChannel > 0) {
7371 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7372 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7373 }
7374 if (apChannel > 0) {
7375 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7376 apChannel, MAC_ADDR_ARRAY(apBssid));
7377 }
7378
7379 if (p2pChannel > 0 && apChannel > 0) {
7380 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7381 }
7382}
7383
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007384bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007385{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007386 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007387}
7388
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007389/* Once SSR is disabled then it cannot be set. */
7390void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007391{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007392 if (HDD_SSR_DISABLED == isSsrRequired)
7393 return;
7394
Jeff Johnson295189b2012-06-20 16:38:30 -07007395 isSsrRequired = value;
7396}
7397
7398VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7399 hdd_adapter_list_node_t** ppAdapterNode)
7400{
7401 VOS_STATUS status;
7402 spin_lock(&pHddCtx->hddAdapters.lock);
7403 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7404 (hdd_list_node_t**) ppAdapterNode );
7405 spin_unlock(&pHddCtx->hddAdapters.lock);
7406 return status;
7407}
7408
7409VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7410 hdd_adapter_list_node_t* pAdapterNode,
7411 hdd_adapter_list_node_t** pNextAdapterNode)
7412{
7413 VOS_STATUS status;
7414 spin_lock(&pHddCtx->hddAdapters.lock);
7415 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7416 (hdd_list_node_t*) pAdapterNode,
7417 (hdd_list_node_t**)pNextAdapterNode );
7418
7419 spin_unlock(&pHddCtx->hddAdapters.lock);
7420 return status;
7421}
7422
7423VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7424 hdd_adapter_list_node_t* pAdapterNode)
7425{
7426 VOS_STATUS status;
7427 spin_lock(&pHddCtx->hddAdapters.lock);
7428 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7429 &pAdapterNode->node );
7430 spin_unlock(&pHddCtx->hddAdapters.lock);
7431 return status;
7432}
7433
7434VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7435 hdd_adapter_list_node_t** ppAdapterNode)
7436{
7437 VOS_STATUS status;
7438 spin_lock(&pHddCtx->hddAdapters.lock);
7439 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7440 (hdd_list_node_t**) ppAdapterNode );
7441 spin_unlock(&pHddCtx->hddAdapters.lock);
7442 return status;
7443}
7444
7445VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7446 hdd_adapter_list_node_t* pAdapterNode)
7447{
7448 VOS_STATUS status;
7449 spin_lock(&pHddCtx->hddAdapters.lock);
7450 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7451 (hdd_list_node_t*) pAdapterNode );
7452 spin_unlock(&pHddCtx->hddAdapters.lock);
7453 return status;
7454}
7455
7456VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7457 hdd_adapter_list_node_t* pAdapterNode)
7458{
7459 VOS_STATUS status;
7460 spin_lock(&pHddCtx->hddAdapters.lock);
7461 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7462 (hdd_list_node_t*) pAdapterNode );
7463 spin_unlock(&pHddCtx->hddAdapters.lock);
7464 return status;
7465}
7466
7467hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7468 tSirMacAddr macAddr )
7469{
7470 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7471 hdd_adapter_t *pAdapter;
7472 VOS_STATUS status;
7473
7474 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7475
7476 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7477 {
7478 pAdapter = pAdapterNode->pAdapter;
7479
7480 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7481 macAddr, sizeof(tSirMacAddr) ) )
7482 {
7483 return pAdapter;
7484 }
7485 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7486 pAdapterNode = pNext;
7487 }
7488
7489 return NULL;
7490
7491}
7492
7493hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7494{
7495 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7496 hdd_adapter_t *pAdapter;
7497 VOS_STATUS status;
7498
7499 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7500
7501 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7502 {
7503 pAdapter = pAdapterNode->pAdapter;
7504
7505 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7506 IFNAMSIZ ) )
7507 {
7508 return pAdapter;
7509 }
7510 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7511 pAdapterNode = pNext;
7512 }
7513
7514 return NULL;
7515
7516}
7517
7518hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7519{
7520 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7521 hdd_adapter_t *pAdapter;
7522 VOS_STATUS status;
7523
7524 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7525
7526 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7527 {
7528 pAdapter = pAdapterNode->pAdapter;
7529
7530 if( pAdapter && (mode == pAdapter->device_mode) )
7531 {
7532 return pAdapter;
7533 }
7534 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7535 pAdapterNode = pNext;
7536 }
7537
7538 return NULL;
7539
7540}
7541
7542//Remove this function later
7543hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7544{
7545 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7546 hdd_adapter_t *pAdapter;
7547 VOS_STATUS status;
7548
7549 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7550
7551 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7552 {
7553 pAdapter = pAdapterNode->pAdapter;
7554
7555 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7556 {
7557 return pAdapter;
7558 }
7559
7560 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7561 pAdapterNode = pNext;
7562 }
7563
7564 return NULL;
7565
7566}
7567
Jeff Johnson295189b2012-06-20 16:38:30 -07007568/**---------------------------------------------------------------------------
7569
7570 \brief hdd_set_monitor_tx_adapter() -
7571
7572 This API initializes the adapter to be used while transmitting on monitor
7573 adapter.
7574
7575 \param - pHddCtx - Pointer to the HDD context.
7576 pAdapter - Adapter that will used for TX. This can be NULL.
7577 \return - None.
7578 --------------------------------------------------------------------------*/
7579void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7580{
7581 hdd_adapter_t *pMonAdapter;
7582
7583 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7584
7585 if( NULL != pMonAdapter )
7586 {
7587 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7588 }
7589}
Jeff Johnson295189b2012-06-20 16:38:30 -07007590/**---------------------------------------------------------------------------
7591
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307592 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007593
7594 This API returns the operating channel of the requested device mode
7595
7596 \param - pHddCtx - Pointer to the HDD context.
7597 - mode - Device mode for which operating channel is required
7598 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7599 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7600 \return - channel number. "0" id the requested device is not found OR it is not connected.
7601 --------------------------------------------------------------------------*/
7602v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7603{
7604 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7605 VOS_STATUS status;
7606 hdd_adapter_t *pAdapter;
7607 v_U8_t operatingChannel = 0;
7608
7609 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7610
7611 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7612 {
7613 pAdapter = pAdapterNode->pAdapter;
7614
7615 if( mode == pAdapter->device_mode )
7616 {
7617 switch(pAdapter->device_mode)
7618 {
7619 case WLAN_HDD_INFRA_STATION:
7620 case WLAN_HDD_P2P_CLIENT:
7621 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7622 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7623 break;
7624 case WLAN_HDD_SOFTAP:
7625 case WLAN_HDD_P2P_GO:
7626 /*softap connection info */
7627 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7628 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7629 break;
7630 default:
7631 break;
7632 }
7633
7634 break; //Found the device of interest. break the loop
7635 }
7636
7637 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7638 pAdapterNode = pNext;
7639 }
7640 return operatingChannel;
7641}
7642
7643#ifdef WLAN_FEATURE_PACKET_FILTERING
7644/**---------------------------------------------------------------------------
7645
7646 \brief hdd_set_multicast_list() -
7647
7648 This used to set the multicast address list.
7649
7650 \param - dev - Pointer to the WLAN device.
7651 - skb - Pointer to OS packet (sk_buff).
7652 \return - success/fail
7653
7654 --------------------------------------------------------------------------*/
7655static void hdd_set_multicast_list(struct net_device *dev)
7656{
7657 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007658 int mc_count;
7659 int i = 0;
7660 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307661
7662 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007663 {
7664 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307665 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007666 return;
7667 }
7668
7669 if (dev->flags & IFF_ALLMULTI)
7670 {
7671 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007672 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307673 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007674 }
7675 else
7676 {
7677 mc_count = netdev_mc_count(dev);
7678 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007679 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007680 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7681 {
7682 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007683 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307684 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007685 return;
7686 }
7687
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307688 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007689
7690 netdev_for_each_mc_addr(ha, dev) {
7691 if (i == mc_count)
7692 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307693 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7694 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007695 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007696 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307697 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007698 i++;
7699 }
7700 }
7701 return;
7702}
7703#endif
7704
7705/**---------------------------------------------------------------------------
7706
7707 \brief hdd_select_queue() -
7708
7709 This function is registered with the Linux OS for network
7710 core to decide which queue to use first.
7711
7712 \param - dev - Pointer to the WLAN device.
7713 - skb - Pointer to OS packet (sk_buff).
7714 \return - ac, Queue Index/access category corresponding to UP in IP header
7715
7716 --------------------------------------------------------------------------*/
7717v_U16_t hdd_select_queue(struct net_device *dev,
7718 struct sk_buff *skb)
7719{
7720 return hdd_wmm_select_queue(dev, skb);
7721}
7722
7723
7724/**---------------------------------------------------------------------------
7725
7726 \brief hdd_wlan_initial_scan() -
7727
7728 This function triggers the initial scan
7729
7730 \param - pAdapter - Pointer to the HDD adapter.
7731
7732 --------------------------------------------------------------------------*/
7733void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7734{
7735 tCsrScanRequest scanReq;
7736 tCsrChannelInfo channelInfo;
7737 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007738 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007739 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7740
7741 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
7742 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
7743 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
7744
7745 if(sme_Is11dSupported(pHddCtx->hHal))
7746 {
7747 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
7748 if ( HAL_STATUS_SUCCESS( halStatus ) )
7749 {
7750 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
7751 if( !scanReq.ChannelInfo.ChannelList )
7752 {
7753 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
7754 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007755 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 return;
7757 }
7758 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
7759 channelInfo.numOfChannels);
7760 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
7761 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007762 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007763 }
7764
7765 scanReq.scanType = eSIR_PASSIVE_SCAN;
7766 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
7767 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
7768 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
7769 }
7770 else
7771 {
7772 scanReq.scanType = eSIR_ACTIVE_SCAN;
7773 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
7774 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
7775 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
7776 }
7777
7778 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
7779 if ( !HAL_STATUS_SUCCESS( halStatus ) )
7780 {
7781 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
7782 __func__, halStatus );
7783 }
7784
7785 if(sme_Is11dSupported(pHddCtx->hHal))
7786 vos_mem_free(scanReq.ChannelInfo.ChannelList);
7787}
7788
Jeff Johnson295189b2012-06-20 16:38:30 -07007789/**---------------------------------------------------------------------------
7790
7791 \brief hdd_full_power_callback() - HDD full power callback function
7792
7793 This is the function invoked by SME to inform the result of a full power
7794 request issued by HDD
7795
7796 \param - callbackcontext - Pointer to cookie
7797 \param - status - result of request
7798
7799 \return - None
7800
7801 --------------------------------------------------------------------------*/
7802static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
7803{
Jeff Johnson72a40512013-12-19 10:14:15 -08007804 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007805
7806 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307807 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007808
7809 if (NULL == callbackContext)
7810 {
7811 hddLog(VOS_TRACE_LEVEL_ERROR,
7812 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007813 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07007814 return;
7815 }
7816
Jeff Johnson72a40512013-12-19 10:14:15 -08007817 /* there is a race condition that exists between this callback
7818 function and the caller since the caller could time out either
7819 before or while this code is executing. we use a spinlock to
7820 serialize these actions */
7821 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007822
7823 if (POWER_CONTEXT_MAGIC != pContext->magic)
7824 {
7825 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08007826 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007827 hddLog(VOS_TRACE_LEVEL_WARN,
7828 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007829 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 return;
7831 }
7832
Jeff Johnson72a40512013-12-19 10:14:15 -08007833 /* context is valid so caller is still waiting */
7834
7835 /* paranoia: invalidate the magic */
7836 pContext->magic = 0;
7837
7838 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07007839 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08007840
7841 /* serialization is complete */
7842 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07007843}
7844
7845/**---------------------------------------------------------------------------
7846
7847 \brief hdd_wlan_exit() - HDD WLAN exit function
7848
7849 This is the driver exit point (invoked during rmmod)
7850
7851 \param - pHddCtx - Pointer to the HDD Context
7852
7853 \return - None
7854
7855 --------------------------------------------------------------------------*/
7856void hdd_wlan_exit(hdd_context_t *pHddCtx)
7857{
7858 eHalStatus halStatus;
7859 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
7860 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05307861 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08007862 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08007863 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007864 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05307865 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007866
7867 ENTER();
7868
Jeff Johnson88ba7742013-02-27 14:36:02 -08007869 if (VOS_FTM_MODE != hdd_get_conparam())
7870 {
7871 // Unloading, restart logic is no more required.
7872 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07007873
c_hpothu5ab05e92014-06-13 17:34:05 +05307874 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7875 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307877 pAdapter = pAdapterNode->pAdapter;
7878 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007879 {
c_hpothu5ab05e92014-06-13 17:34:05 +05307880 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
7881 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
7882 {
7883 wlan_hdd_cfg80211_deregister_frames(pAdapter);
7884 hdd_UnregisterWext(pAdapter->dev);
7885 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307886
Jeff Johnson295189b2012-06-20 16:38:30 -07007887 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307888 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7889 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307891 // Cancel any outstanding scan requests. We are about to close all
7892 // of our adapters, but an adapter structure is what SME passes back
7893 // to our callback function. Hence if there are any outstanding scan
7894 // requests then there is a race condition between when the adapter
7895 // is closed and when the callback is invoked.We try to resolve that
7896 // race condition here by canceling any outstanding scans before we
7897 // close the adapters.
7898 // Note that the scans may be cancelled in an asynchronous manner,
7899 // so ideally there needs to be some kind of synchronization. Rather
7900 // than introduce a new synchronization here, we will utilize the
7901 // fact that we are about to Request Full Power, and since that is
7902 // synchronized, the expectation is that by the time Request Full
7903 // Power has completed all scans will be cancelled.
7904 if (pHddCtx->scan_info.mScanPending)
7905 {
7906 hddLog(VOS_TRACE_LEVEL_INFO,
7907 FL("abort scan mode: %d sessionId: %d"),
7908 pAdapter->device_mode,
7909 pAdapter->sessionId);
7910 hdd_abort_mac_scan(pHddCtx,
7911 pHddCtx->scan_info.sessionId,
7912 eCSR_SCAN_ABORT_DEFAULT);
7913 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007914 }
c_hpothu5ab05e92014-06-13 17:34:05 +05307915 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08007916 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307917 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08007918 wlan_hdd_ftm_close(pHddCtx);
7919 goto free_hdd_ctx;
7920 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307921
Jeff Johnson295189b2012-06-20 16:38:30 -07007922 /* DeRegister with platform driver as client for Suspend/Resume */
7923 vosStatus = hddDeregisterPmOps(pHddCtx);
7924 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7925 {
7926 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
7927 VOS_ASSERT(0);
7928 }
7929
7930 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
7931 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
7932 {
7933 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
7934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007935
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07007936 //Stop the traffic monitor timer
7937 if ( VOS_TIMER_STATE_RUNNING ==
7938 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
7939 {
7940 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
7941 }
7942
7943 // Destroy the traffic monitor timer
7944 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
7945 &pHddCtx->tx_rx_trafficTmr)))
7946 {
7947 hddLog(VOS_TRACE_LEVEL_ERROR,
7948 "%s: Cannot deallocate Traffic monitor timer", __func__);
7949 }
7950
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 //Disable IMPS/BMPS as we do not want the device to enter any power
7952 //save mode during shutdown
7953 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
7954 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
7955 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
7956
7957 //Ensure that device is in full power as we will touch H/W during vos_Stop
7958 init_completion(&powerContext.completion);
7959 powerContext.magic = POWER_CONTEXT_MAGIC;
7960
7961 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
7962 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
7963
7964 if (eHAL_STATUS_SUCCESS != halStatus)
7965 {
7966 if (eHAL_STATUS_PMC_PENDING == halStatus)
7967 {
7968 /* request was sent -- wait for the response */
7969 lrc = wait_for_completion_interruptible_timeout(
7970 &powerContext.completion,
7971 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 if (lrc <= 0)
7973 {
7974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007975 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07007976 }
7977 }
7978 else
7979 {
7980 hddLog(VOS_TRACE_LEVEL_ERROR,
7981 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007982 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 /* continue -- need to clean up as much as possible */
7984 }
7985 }
7986
Jeff Johnson72a40512013-12-19 10:14:15 -08007987 /* either we never sent a request, we sent a request and received a
7988 response or we sent a request and timed out. if we never sent a
7989 request or if we sent a request and got a response, we want to
7990 clear the magic out of paranoia. if we timed out there is a
7991 race condition such that the callback function could be
7992 executing at the same time we are. of primary concern is if the
7993 callback function had already verified the "magic" but had not
7994 yet set the completion variable when a timeout occurred. we
7995 serialize these activities by invalidating the magic while
7996 holding a shared spinlock which will cause us to block if the
7997 callback is currently executing */
7998 spin_lock(&hdd_context_lock);
7999 powerContext.magic = 0;
8000 spin_unlock(&hdd_context_lock);
8001
Yue Ma0d4891e2013-08-06 17:01:45 -07008002 hdd_debugfs_exit(pHddCtx);
8003
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 // Unregister the Net Device Notifier
8005 unregister_netdevice_notifier(&hdd_netdev_notifier);
8006
Jeff Johnson295189b2012-06-20 16:38:30 -07008007 hdd_stop_all_adapters( pHddCtx );
8008
Jeff Johnson295189b2012-06-20 16:38:30 -07008009#ifdef WLAN_BTAMP_FEATURE
8010 vosStatus = WLANBAP_Stop(pVosContext);
8011 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8012 {
8013 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8014 "%s: Failed to stop BAP",__func__);
8015 }
8016#endif //WLAN_BTAMP_FEATURE
8017
8018 //Stop all the modules
8019 vosStatus = vos_stop( pVosContext );
8020 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8021 {
8022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8023 "%s: Failed to stop VOSS",__func__);
8024 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8025 }
8026
Jeff Johnson295189b2012-06-20 16:38:30 -07008027 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008028 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008029
8030 //Close the scheduler before calling vos_close to make sure no thread is
8031 // scheduled after the each module close is called i.e after all the data
8032 // structures are freed.
8033 vosStatus = vos_sched_close( pVosContext );
8034 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8035 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8036 "%s: Failed to close VOSS Scheduler",__func__);
8037 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8038 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008039#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008040#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8041 /* Destroy the wake lock */
8042 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8043#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008044 /* Destroy the wake lock */
8045 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008046#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008047
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308048#ifdef CONFIG_ENABLE_LINUX_REG
8049 vosStatus = vos_nv_close();
8050 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8051 {
8052 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8053 "%s: Failed to close NV", __func__);
8054 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8055 }
8056#endif
8057
Jeff Johnson295189b2012-06-20 16:38:30 -07008058 //Close VOSS
8059 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8060 vos_close(pVosContext);
8061
Jeff Johnson295189b2012-06-20 16:38:30 -07008062 //Close Watchdog
8063 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8064 vos_watchdog_close(pVosContext);
8065
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308066 //Clean up HDD Nlink Service
8067 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308068
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308069#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308070 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308071 {
8072 wlan_logging_sock_deactivate_svc();
8073 }
8074#endif
8075
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308076#ifdef WLAN_KD_READY_NOTIFIER
8077 nl_srv_exit(pHddCtx->ptt_pid);
8078#else
8079 nl_srv_exit();
8080#endif /* WLAN_KD_READY_NOTIFIER */
8081
8082
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 hdd_close_all_adapters( pHddCtx );
8084
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 /* free the power on lock from platform driver */
8086 if (free_riva_power_on_lock("wlan"))
8087 {
8088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8089 __func__);
8090 }
8091
Jeff Johnson88ba7742013-02-27 14:36:02 -08008092free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308093
8094 //Free up dynamically allocated members inside HDD Adapter
8095 if (pHddCtx->cfg_ini)
8096 {
8097 kfree(pHddCtx->cfg_ini);
8098 pHddCtx->cfg_ini= NULL;
8099 }
8100
Leo Changf04ddad2013-09-18 13:46:38 -07008101 /* FTM mode, WIPHY did not registered
8102 If un-register here, system crash will happen */
8103 if (VOS_FTM_MODE != hdd_get_conparam())
8104 {
8105 wiphy_unregister(wiphy) ;
8106 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008108 if (hdd_is_ssr_required())
8109 {
8110 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008111 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008112 msleep(5000);
8113 }
8114 hdd_set_ssr_required (VOS_FALSE);
8115}
8116
8117
8118/**---------------------------------------------------------------------------
8119
8120 \brief hdd_update_config_from_nv() - Function to update the contents of
8121 the running configuration with parameters taken from NV storage
8122
8123 \param - pHddCtx - Pointer to the HDD global context
8124
8125 \return - VOS_STATUS_SUCCESS if successful
8126
8127 --------------------------------------------------------------------------*/
8128static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8129{
Jeff Johnson295189b2012-06-20 16:38:30 -07008130 v_BOOL_t itemIsValid = VOS_FALSE;
8131 VOS_STATUS status;
8132 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8133 v_U8_t macLoop;
8134
8135 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8136 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8137 if(status != VOS_STATUS_SUCCESS)
8138 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008139 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008140 return VOS_STATUS_E_FAILURE;
8141 }
8142
8143 if (itemIsValid == VOS_TRUE)
8144 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008145 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8147 VOS_MAX_CONCURRENCY_PERSONA);
8148 if(status != VOS_STATUS_SUCCESS)
8149 {
8150 /* Get MAC from NV fail, not update CFG info
8151 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008152 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 return VOS_STATUS_E_FAILURE;
8154 }
8155
8156 /* If first MAC is not valid, treat all others are not valid
8157 * Then all MACs will be got from ini file */
8158 if(vos_is_macaddr_zero(&macFromNV[0]))
8159 {
8160 /* MAC address in NV file is not configured yet */
8161 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8162 return VOS_STATUS_E_INVAL;
8163 }
8164
8165 /* Get MAC address from NV, update CFG info */
8166 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8167 {
8168 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8169 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308170 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008171 /* This MAC is not valid, skip it
8172 * This MAC will be got from ini file */
8173 }
8174 else
8175 {
8176 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8177 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8178 VOS_MAC_ADDR_SIZE);
8179 }
8180 }
8181 }
8182 else
8183 {
8184 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8185 return VOS_STATUS_E_FAILURE;
8186 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008187
Jeff Johnson295189b2012-06-20 16:38:30 -07008188
8189 return VOS_STATUS_SUCCESS;
8190}
8191
8192/**---------------------------------------------------------------------------
8193
8194 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8195
8196 \param - pAdapter - Pointer to the HDD
8197
8198 \return - None
8199
8200 --------------------------------------------------------------------------*/
8201VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8202{
8203 eHalStatus halStatus;
8204 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308205 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008206
Jeff Johnson295189b2012-06-20 16:38:30 -07008207
8208 // Send ready indication to the HDD. This will kick off the MAC
8209 // into a 'running' state and should kick off an initial scan.
8210 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8211 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8212 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308213 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008214 "code %08d [x%08x]",__func__, halStatus, halStatus );
8215 return VOS_STATUS_E_FAILURE;
8216 }
8217
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308218 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8220 // And RIVA will crash
8221 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8222 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308223 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8224 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8225
8226
Jeff Johnson295189b2012-06-20 16:38:30 -07008227 return VOS_STATUS_SUCCESS;
8228}
8229
Jeff Johnson295189b2012-06-20 16:38:30 -07008230/* wake lock APIs for HDD */
8231void hdd_prevent_suspend(void)
8232{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008233#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008235#else
8236 wcnss_prevent_suspend();
8237#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008238}
8239
8240void hdd_allow_suspend(void)
8241{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008242#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008243 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008244#else
8245 wcnss_allow_suspend();
8246#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008247}
8248
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308249void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008250{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008251#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008252 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008253#else
8254 /* Do nothing as there is no API in wcnss for timeout*/
8255#endif
8256}
8257
Jeff Johnson295189b2012-06-20 16:38:30 -07008258/**---------------------------------------------------------------------------
8259
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008260 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8261 information between Host and Riva
8262
8263 This function gets reported version of FW
8264 It also finds the version of Riva headers used to compile the host
8265 It compares the above two and prints a warning if they are different
8266 It gets the SW and HW version string
8267 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8268 indicating the features they support through a bitmap
8269
8270 \param - pHddCtx - Pointer to HDD context
8271
8272 \return - void
8273
8274 --------------------------------------------------------------------------*/
8275
8276void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8277{
8278
8279 tSirVersionType versionCompiled;
8280 tSirVersionType versionReported;
8281 tSirVersionString versionString;
8282 tANI_U8 fwFeatCapsMsgSupported = 0;
8283 VOS_STATUS vstatus;
8284
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008285 memset(&versionCompiled, 0, sizeof(versionCompiled));
8286 memset(&versionReported, 0, sizeof(versionReported));
8287
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008288 /* retrieve and display WCNSS version information */
8289 do {
8290
8291 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8292 &versionCompiled);
8293 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8294 {
8295 hddLog(VOS_TRACE_LEVEL_FATAL,
8296 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008297 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008298 break;
8299 }
8300
8301 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8302 &versionReported);
8303 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8304 {
8305 hddLog(VOS_TRACE_LEVEL_FATAL,
8306 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008307 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008308 break;
8309 }
8310
8311 if ((versionCompiled.major != versionReported.major) ||
8312 (versionCompiled.minor != versionReported.minor) ||
8313 (versionCompiled.version != versionReported.version) ||
8314 (versionCompiled.revision != versionReported.revision))
8315 {
8316 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8317 "Host expected %u.%u.%u.%u\n",
8318 WLAN_MODULE_NAME,
8319 (int)versionReported.major,
8320 (int)versionReported.minor,
8321 (int)versionReported.version,
8322 (int)versionReported.revision,
8323 (int)versionCompiled.major,
8324 (int)versionCompiled.minor,
8325 (int)versionCompiled.version,
8326 (int)versionCompiled.revision);
8327 }
8328 else
8329 {
8330 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8331 WLAN_MODULE_NAME,
8332 (int)versionReported.major,
8333 (int)versionReported.minor,
8334 (int)versionReported.version,
8335 (int)versionReported.revision);
8336 }
8337
8338 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8339 versionString,
8340 sizeof(versionString));
8341 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8342 {
8343 hddLog(VOS_TRACE_LEVEL_FATAL,
8344 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008345 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008346 break;
8347 }
8348
8349 pr_info("%s: WCNSS software version %s\n",
8350 WLAN_MODULE_NAME, versionString);
8351
8352 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8353 versionString,
8354 sizeof(versionString));
8355 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8356 {
8357 hddLog(VOS_TRACE_LEVEL_FATAL,
8358 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008359 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008360 break;
8361 }
8362
8363 pr_info("%s: WCNSS hardware version %s\n",
8364 WLAN_MODULE_NAME, versionString);
8365
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008366 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8367 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008368 send the message only if it the riva is 1.1
8369 minor numbers for different riva branches:
8370 0 -> (1.0)Mainline Build
8371 1 -> (1.1)Mainline Build
8372 2->(1.04) Stability Build
8373 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008374 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008375 ((versionReported.minor>=1) && (versionReported.version>=1)))
8376 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8377 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008378
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008379 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008380 {
8381#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8382 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8383 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8384#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008385 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8386 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8387 {
8388 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8389 }
8390
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008391 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008392 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008393
8394 } while (0);
8395
8396}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308397void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8398{
8399 struct sk_buff *skb;
8400 struct nlmsghdr *nlh;
8401 tAniMsgHdr *ani_hdr;
8402
8403 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8404
8405 if(skb == NULL) {
8406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8407 "%s: alloc_skb failed", __func__);
8408 return;
8409 }
8410
8411 nlh = (struct nlmsghdr *)skb->data;
8412 nlh->nlmsg_pid = 0; /* from kernel */
8413 nlh->nlmsg_flags = 0;
8414 nlh->nlmsg_seq = 0;
8415 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8416
8417 ani_hdr = NLMSG_DATA(nlh);
8418 ani_hdr->type = type;
8419
8420 switch(type) {
8421 case WLAN_SVC_SAP_RESTART_IND:
8422 ani_hdr->length = 0;
8423 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8424 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8425 break;
8426 default:
8427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8428 "Attempt to send unknown nlink message %d", type);
8429 kfree_skb(skb);
8430 return;
8431 }
8432
8433 nl_srv_bcast(skb);
8434
8435 return;
8436}
8437
8438
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008439
8440/**---------------------------------------------------------------------------
8441
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308442 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8443
8444 \param - pHddCtx - Pointer to the hdd context
8445
8446 \return - true if hardware supports 5GHz
8447
8448 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308449boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308450{
8451 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8452 * then hardware support 5Ghz.
8453 */
8454 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8455 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308456 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308457 return true;
8458 }
8459 else
8460 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308461 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308462 __func__);
8463 return false;
8464 }
8465}
8466
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308467/**---------------------------------------------------------------------------
8468
8469 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8470 generate function
8471
8472 This is generate the random mac address for WLAN interface
8473
8474 \param - pHddCtx - Pointer to HDD context
8475 idx - Start interface index to get auto
8476 generated mac addr.
8477 mac_addr - Mac address
8478
8479 \return - 0 for success, < 0 for failure
8480
8481 --------------------------------------------------------------------------*/
8482
8483static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8484 int idx, v_MACADDR_t mac_addr)
8485{
8486 int i;
8487 unsigned int serialno;
8488 serialno = wcnss_get_serial_number();
8489
8490 if (0 != serialno)
8491 {
8492 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8493 bytes of the serial number that can be used to generate
8494 the other 3 bytes of the MAC address. Mask off all but
8495 the lower 3 bytes (this will also make sure we don't
8496 overflow in the next step) */
8497 serialno &= 0x00FFFFFF;
8498
8499 /* we need a unique address for each session */
8500 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8501
8502 /* autogen other Mac addresses */
8503 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8504 {
8505 /* start with the entire default address */
8506 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8507 /* then replace the lower 3 bytes */
8508 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8509 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8510 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8511
8512 serialno++;
8513 hddLog(VOS_TRACE_LEVEL_ERROR,
8514 "%s: Derived Mac Addr: "
8515 MAC_ADDRESS_STR, __func__,
8516 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8517 }
8518
8519 }
8520 else
8521 {
8522 hddLog(LOGE, FL("Failed to Get Serial NO"));
8523 return -1;
8524 }
8525 return 0;
8526}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308527
8528/**---------------------------------------------------------------------------
8529
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308530 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8531 completed to flush out the scan results
8532
8533 11d scan is done during driver load and is a passive scan on all
8534 channels supported by the device, 11d scans may find some APs on
8535 frequencies which are forbidden to be used in the regulatory domain
8536 the device is operating in. If these APs are notified to the supplicant
8537 it may try to connect to these APs, thus flush out all the scan results
8538 which are present in SME after 11d scan is done.
8539
8540 \return - eHalStatus
8541
8542 --------------------------------------------------------------------------*/
8543static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8544 tANI_U32 scanId, eCsrScanStatus status)
8545{
8546 ENTER();
8547
8548 sme_ScanFlushResult(halHandle, 0);
8549
8550 EXIT();
8551
8552 return eHAL_STATUS_SUCCESS;
8553}
8554
8555/**---------------------------------------------------------------------------
8556
Jeff Johnson295189b2012-06-20 16:38:30 -07008557 \brief hdd_wlan_startup() - HDD init function
8558
8559 This is the driver startup code executed once a WLAN device has been detected
8560
8561 \param - dev - Pointer to the underlying device
8562
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008563 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008564
8565 --------------------------------------------------------------------------*/
8566
8567int hdd_wlan_startup(struct device *dev )
8568{
8569 VOS_STATUS status;
8570 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008571 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008572 hdd_context_t *pHddCtx = NULL;
8573 v_CONTEXT_t pVosContext= NULL;
8574#ifdef WLAN_BTAMP_FEATURE
8575 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8576 WLANBAP_ConfigType btAmpConfig;
8577 hdd_config_t *pConfig;
8578#endif
8579 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308581 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008582
8583 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 /*
8585 * cfg80211: wiphy allocation
8586 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308587 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008588
8589 if(wiphy == NULL)
8590 {
8591 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008592 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008593 }
8594
8595 pHddCtx = wiphy_priv(wiphy);
8596
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 //Initialize the adapter context to zeros.
8598 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8599
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008601 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308602 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008603
8604 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8605
8606 /*Get vos context here bcoz vos_open requires it*/
8607 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8608
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008609 if(pVosContext == NULL)
8610 {
8611 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8612 goto err_free_hdd_context;
8613 }
8614
Jeff Johnson295189b2012-06-20 16:38:30 -07008615 //Save the Global VOSS context in adapter context for future.
8616 pHddCtx->pvosContext = pVosContext;
8617
8618 //Save the adapter context in global context for future.
8619 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8620
Jeff Johnson295189b2012-06-20 16:38:30 -07008621 pHddCtx->parent_dev = dev;
8622
8623 init_completion(&pHddCtx->full_pwr_comp_var);
8624 init_completion(&pHddCtx->standby_comp_var);
8625 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008626 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008627 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308628 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308629 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008630
8631#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008632 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008633#else
8634 init_completion(&pHddCtx->driver_crda_req);
8635#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008636
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308637 spin_lock_init(&pHddCtx->schedScan_lock);
8638
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8640
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308641#ifdef FEATURE_WLAN_TDLS
8642 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8643 * invoked by other instances also) to protect the concurrent
8644 * access for the Adapters by TDLS module.
8645 */
8646 mutex_init(&pHddCtx->tdls_lock);
8647#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05308648 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Agarwal Ashish1f422872014-07-22 00:11:55 +05308649 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308650
Agarwal Ashish1f422872014-07-22 00:11:55 +05308651 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 // Load all config first as TL config is needed during vos_open
8653 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8654 if(pHddCtx->cfg_ini == NULL)
8655 {
8656 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8657 goto err_free_hdd_context;
8658 }
8659
8660 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8661
8662 // Read and parse the qcom_cfg.ini file
8663 status = hdd_parse_config_ini( pHddCtx );
8664 if ( VOS_STATUS_SUCCESS != status )
8665 {
8666 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8667 __func__, WLAN_INI_FILE);
8668 goto err_config;
8669 }
Arif Hussaind5218912013-12-05 01:10:55 -08008670#ifdef MEMORY_DEBUG
8671 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8672 vos_mem_init();
8673
8674 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8675 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8676#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008677
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308678 /* INI has been read, initialise the configuredMcastBcastFilter with
8679 * INI value as this will serve as the default value
8680 */
8681 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8682 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8683 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308684
8685 if (false == hdd_is_5g_supported(pHddCtx))
8686 {
8687 //5Ghz is not supported.
8688 if (1 != pHddCtx->cfg_ini->nBandCapability)
8689 {
8690 hddLog(VOS_TRACE_LEVEL_INFO,
8691 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8692 pHddCtx->cfg_ini->nBandCapability = 1;
8693 }
8694 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308695
8696 /* If SNR Monitoring is enabled, FW has to parse all beacons
8697 * for calcaluting and storing the average SNR, so set Nth beacon
8698 * filter to 1 to enable FW to parse all the beaocons
8699 */
8700 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8701 {
8702 /* The log level is deliberately set to WARN as overriding
8703 * nthBeaconFilter to 1 will increase power cosumption and this
8704 * might just prove helpful to detect the power issue.
8705 */
8706 hddLog(VOS_TRACE_LEVEL_WARN,
8707 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
8708 pHddCtx->cfg_ini->nthBeaconFilter = 1;
8709 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008710 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308711 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07008712 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008713 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08008715 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
8716 {
8717 hddLog(VOS_TRACE_LEVEL_FATAL,
8718 "%s: wlan_hdd_cfg80211_init return failure", __func__);
8719 goto err_config;
8720 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008722
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008723 // Update VOS trace levels based upon the cfg.ini
8724 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
8725 pHddCtx->cfg_ini->vosTraceEnableBAP);
8726 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
8727 pHddCtx->cfg_ini->vosTraceEnableTL);
8728 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
8729 pHddCtx->cfg_ini->vosTraceEnableWDI);
8730 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
8731 pHddCtx->cfg_ini->vosTraceEnableHDD);
8732 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
8733 pHddCtx->cfg_ini->vosTraceEnableSME);
8734 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
8735 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05308736 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
8737 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008738 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
8739 pHddCtx->cfg_ini->vosTraceEnableWDA);
8740 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
8741 pHddCtx->cfg_ini->vosTraceEnableSYS);
8742 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
8743 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008744 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
8745 pHddCtx->cfg_ini->vosTraceEnableSAP);
8746 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
8747 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08008748
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 // Update WDI trace levels based upon the cfg.ini
8750 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
8751 pHddCtx->cfg_ini->wdiTraceEnableDAL);
8752 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
8753 pHddCtx->cfg_ini->wdiTraceEnableCTL);
8754 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
8755 pHddCtx->cfg_ini->wdiTraceEnableDAT);
8756 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
8757 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07008758
Jeff Johnson88ba7742013-02-27 14:36:02 -08008759 if (VOS_FTM_MODE == hdd_get_conparam())
8760 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008761 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
8762 {
8763 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
8764 goto err_free_hdd_context;
8765 }
8766 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05308767
8768 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008769 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08008770 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008771
Jeff Johnson88ba7742013-02-27 14:36:02 -08008772 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07008773 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8774 {
8775 status = vos_watchdog_open(pVosContext,
8776 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
8777
8778 if(!VOS_IS_STATUS_SUCCESS( status ))
8779 {
8780 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308781 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008782 }
8783 }
8784
8785 pHddCtx->isLogpInProgress = FALSE;
8786 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
8787
Amar Singhala49cbc52013-10-08 18:37:44 -07008788#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008789 /* initialize the NV module. This is required so that
8790 we can initialize the channel information in wiphy
8791 from the NV.bin data. The channel information in
8792 wiphy needs to be initialized before wiphy registration */
8793
8794 status = vos_nv_open();
8795 if (!VOS_IS_STATUS_SUCCESS(status))
8796 {
8797 /* NV module cannot be initialized */
8798 hddLog( VOS_TRACE_LEVEL_FATAL,
8799 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05308800 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07008801 }
8802
8803 status = vos_init_wiphy_from_nv_bin();
8804 if (!VOS_IS_STATUS_SUCCESS(status))
8805 {
8806 /* NV module cannot be initialized */
8807 hddLog( VOS_TRACE_LEVEL_FATAL,
8808 "%s: vos_init_wiphy failed", __func__);
8809 goto err_vos_nv_close;
8810 }
8811
Amar Singhala49cbc52013-10-08 18:37:44 -07008812#endif
8813
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05308814 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 if ( !VOS_IS_STATUS_SUCCESS( status ))
8816 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008817 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05308818 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 }
8820
Jeff Johnson295189b2012-06-20 16:38:30 -07008821 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
8822
8823 if ( NULL == pHddCtx->hHal )
8824 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008825 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008826 goto err_vosclose;
8827 }
8828
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008829 status = vos_preStart( pHddCtx->pvosContext );
8830 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8831 {
8832 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308833 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008834 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008835
Arif Hussaineaf68602013-12-30 23:10:44 -08008836 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
8837 {
8838 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
8839 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
8840 __func__, enable_dfs_chan_scan);
8841 }
8842 if (0 == enable_11d || 1 == enable_11d)
8843 {
8844 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
8845 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
8846 __func__, enable_11d);
8847 }
8848
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008849 /* Note that the vos_preStart() sequence triggers the cfg download.
8850 The cfg download must occur before we update the SME config
8851 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07008852 status = hdd_set_sme_config( pHddCtx );
8853
8854 if ( VOS_STATUS_SUCCESS != status )
8855 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008856 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308857 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008858 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008859
Jeff Johnson295189b2012-06-20 16:38:30 -07008860 /* In the integrated architecture we update the configuration from
8861 the INI file and from NV before vOSS has been started so that
8862 the final contents are available to send down to the cCPU */
8863
8864 // Apply the cfg.ini to cfg.dat
8865 if (FALSE == hdd_update_config_dat(pHddCtx))
8866 {
8867 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308868 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 }
8870
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308871 // Get mac addr from platform driver
8872 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
8873
8874 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308876 /* Store the mac addr for first interface */
8877 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
8878
8879 hddLog(VOS_TRACE_LEVEL_ERROR,
8880 "%s: WLAN Mac Addr: "
8881 MAC_ADDRESS_STR, __func__,
8882 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8883
8884 /* Here, passing Arg2 as 1 because we do not want to change the
8885 last 3 bytes (means non OUI bytes) of first interface mac
8886 addr.
8887 */
8888 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
8889 {
8890 hddLog(VOS_TRACE_LEVEL_ERROR,
8891 "%s: Failed to generate wlan interface mac addr "
8892 "using MAC from ini file ", __func__);
8893 }
8894 }
8895 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
8896 {
8897 // Apply the NV to cfg.dat
8898 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07008899#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
8900 /* There was not a valid set of MAC Addresses in NV. See if the
8901 default addresses were modified by the cfg.ini settings. If so,
8902 we'll use them, but if not, we'll autogenerate a set of MAC
8903 addresses based upon the device serial number */
8904
8905 static const v_MACADDR_t default_address =
8906 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07008907
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308908 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
8909 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 {
8911 /* cfg.ini has the default address, invoke autogen logic */
8912
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308913 /* Here, passing Arg2 as 0 because we want to change the
8914 last 3 bytes (means non OUI bytes) of all the interfaces
8915 mac addr.
8916 */
8917 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
8918 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07008919 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308920 hddLog(VOS_TRACE_LEVEL_ERROR,
8921 "%s: Failed to generate wlan interface mac addr "
8922 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
8923 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07008924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008925 }
8926 else
8927#endif //WLAN_AUTOGEN_MACADDR_FEATURE
8928 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08008929 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 "%s: Invalid MAC address in NV, using MAC from ini file "
8931 MAC_ADDRESS_STR, __func__,
8932 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
8933 }
8934 }
8935 {
8936 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308937
8938 /* Set the MAC Address Currently this is used by HAL to
8939 * add self sta. Remove this once self sta is added as
8940 * part of session open.
8941 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008942 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
8943 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
8944 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308945
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 if (!HAL_STATUS_SUCCESS( halStatus ))
8947 {
8948 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
8949 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308950 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008951 }
8952 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008953
8954 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
8955 Note: Firmware image will be read and downloaded inside vos_start API */
8956 status = vos_start( pHddCtx->pvosContext );
8957 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8958 {
8959 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05308960 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 }
8962
Leo Chang6cec3e22014-01-21 15:33:49 -08008963#ifdef FEATURE_WLAN_CH_AVOID
8964 /* Plug in avoid channel notification callback
8965 * This should happen before ADD_SELF_STA
8966 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05308967
8968 /* check the Channel Avoidance is enabled */
8969 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
8970 {
8971 sme_AddChAvoidCallback(pHddCtx->hHal,
8972 hdd_hostapd_ch_avoid_cb);
8973 }
Leo Chang6cec3e22014-01-21 15:33:49 -08008974#endif /* FEATURE_WLAN_CH_AVOID */
8975
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008976 /* Exchange capability info between Host and FW and also get versioning info from FW */
8977 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008978
Agarwal Ashishad9281b2014-06-10 14:57:30 +05308979#ifdef CONFIG_ENABLE_LINUX_REG
8980 status = wlan_hdd_init_channels(pHddCtx);
8981 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8982 {
8983 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
8984 __func__);
8985 goto err_vosstop;
8986 }
8987#endif
8988
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 status = hdd_post_voss_start_config( pHddCtx );
8990 if ( !VOS_IS_STATUS_SUCCESS( status ) )
8991 {
8992 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
8993 __func__);
8994 goto err_vosstop;
8995 }
Amar Singhala49cbc52013-10-08 18:37:44 -07008996
8997#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308998 wlan_hdd_cfg80211_update_reg_info( wiphy );
8999
9000 /* registration of wiphy dev with cfg80211 */
9001 if (0 > wlan_hdd_cfg80211_register(wiphy))
9002 {
9003 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9004 goto err_vosstop;
9005 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009006#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009007
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309008#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309009 /* registration of wiphy dev with cfg80211 */
9010 if (0 > wlan_hdd_cfg80211_register(wiphy))
9011 {
9012 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9013 goto err_vosstop;
9014 }
9015
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309016 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309017 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9018 {
9019 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9020 __func__);
9021 goto err_unregister_wiphy;
9022 }
9023#endif
9024
Jeff Johnson295189b2012-06-20 16:38:30 -07009025 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9026 {
9027 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9028 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9029 }
9030 else
9031 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9033 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9034 if (pAdapter != NULL)
9035 {
kaidde69982014-06-18 13:23:21 +08009036 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] &= 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309038 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9039 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9040 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009041
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309042 /* Generate the P2P Device Address. This consists of the device's
9043 * primary MAC address with the locally administered bit set.
9044 */
9045 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009046 }
9047 else
9048 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309049 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9050 if (p2p_dev_addr != NULL)
9051 {
9052 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9053 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9054 }
9055 else
9056 {
9057 hddLog(VOS_TRACE_LEVEL_FATAL,
9058 "%s: Failed to allocate mac_address for p2p_device",
9059 __func__);
9060 goto err_close_adapter;
9061 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009062 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009063
9064 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9065 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9066 if ( NULL == pP2pAdapter )
9067 {
9068 hddLog(VOS_TRACE_LEVEL_FATAL,
9069 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009070 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009071 goto err_close_adapter;
9072 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009073 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009074 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009075
9076 if( pAdapter == NULL )
9077 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9079 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009080 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009081
Arif Hussain66559122013-11-21 10:11:40 -08009082 if (country_code)
9083 {
9084 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009085 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009086 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9087#ifndef CONFIG_ENABLE_LINUX_REG
9088 hdd_checkandupdate_phymode(pAdapter, country_code);
9089#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009090 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9091 (void *)(tSmeChangeCountryCallback)
9092 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009093 country_code,
9094 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309095 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009096 if (eHAL_STATUS_SUCCESS == ret)
9097 {
Arif Hussaincb607082013-12-20 11:57:42 -08009098 ret = wait_for_completion_interruptible_timeout(
9099 &pAdapter->change_country_code,
9100 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9101
9102 if (0 >= ret)
9103 {
9104 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9105 "%s: SME while setting country code timed out", __func__);
9106 }
Arif Hussain66559122013-11-21 10:11:40 -08009107 }
9108 else
9109 {
Arif Hussaincb607082013-12-20 11:57:42 -08009110 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9111 "%s: SME Change Country code from module param fail ret=%d",
9112 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009113 }
9114 }
9115
Jeff Johnson295189b2012-06-20 16:38:30 -07009116#ifdef WLAN_BTAMP_FEATURE
9117 vStatus = WLANBAP_Open(pVosContext);
9118 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9119 {
9120 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9121 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009122 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009123 }
9124
9125 vStatus = BSL_Init(pVosContext);
9126 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9127 {
9128 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9129 "%s: Failed to Init BSL",__func__);
9130 goto err_bap_close;
9131 }
9132 vStatus = WLANBAP_Start(pVosContext);
9133 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9134 {
9135 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9136 "%s: Failed to start TL",__func__);
9137 goto err_bap_close;
9138 }
9139
9140 pConfig = pHddCtx->cfg_ini;
9141 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9142 status = WLANBAP_SetConfig(&btAmpConfig);
9143
9144#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009145
Mihir Shete9c238772014-10-15 14:35:16 +05309146 /*
9147 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9148 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9149 * which is greater than 0xf. So the below check is safe to make
9150 * sure that there is no entry for UapsdMask in the ini
9151 */
9152 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9153 {
9154 if(IS_DYNAMIC_WMM_PS_ENABLED)
9155 {
9156 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9157 __func__);
9158 pHddCtx->cfg_ini->UapsdMask =
9159 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9160 }
9161 else
9162 {
9163 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9164 __func__);
9165 pHddCtx->cfg_ini->UapsdMask =
9166 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9167 }
9168 }
9169
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009170#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9171 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9172 {
9173 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9174 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9175 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9176 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9177 }
9178#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009179
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309180 wlan_hdd_tdls_init(pHddCtx);
9181
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309182 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9183
Jeff Johnson295189b2012-06-20 16:38:30 -07009184 /* Register with platform driver as client for Suspend/Resume */
9185 status = hddRegisterPmOps(pHddCtx);
9186 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9187 {
9188 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9189#ifdef WLAN_BTAMP_FEATURE
9190 goto err_bap_stop;
9191#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009192 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009193#endif //WLAN_BTAMP_FEATURE
9194 }
9195
Yue Ma0d4891e2013-08-06 17:01:45 -07009196 /* Open debugfs interface */
9197 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9198 {
9199 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9200 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009201 }
9202
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 /* Register TM level change handler function to the platform */
9204 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9205 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9206 {
9207 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9208 goto err_unregister_pmops;
9209 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009210
9211 /* register for riva power on lock to platform driver */
9212 if (req_riva_power_on_lock("wlan"))
9213 {
9214 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9215 __func__);
9216 goto err_unregister_pmops;
9217 }
9218
Jeff Johnson295189b2012-06-20 16:38:30 -07009219 // register net device notifier for device change notification
9220 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9221
9222 if(ret < 0)
9223 {
9224 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9225 goto err_free_power_on_lock;
9226 }
9227
9228 //Initialize the nlink service
9229 if(nl_srv_init() != 0)
9230 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309231 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009232 goto err_reg_netdev;
9233 }
9234
Leo Chang4ce1cc52013-10-21 18:27:15 -07009235#ifdef WLAN_KD_READY_NOTIFIER
9236 pHddCtx->kd_nl_init = 1;
9237#endif /* WLAN_KD_READY_NOTIFIER */
9238
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 //Initialize the BTC service
9240 if(btc_activate_service(pHddCtx) != 0)
9241 {
9242 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9243 goto err_nl_srv;
9244 }
9245
9246#ifdef PTT_SOCK_SVC_ENABLE
9247 //Initialize the PTT service
9248 if(ptt_sock_activate_svc(pHddCtx) != 0)
9249 {
9250 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9251 goto err_nl_srv;
9252 }
9253#endif
9254
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309255#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9256 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9257 {
9258 if(wlan_logging_sock_activate_svc(
9259 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9260 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9261 {
9262 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9263 " failed", __func__);
9264 goto err_nl_srv;
9265 }
9266 }
9267#endif
9268
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009272 /* Action frame registered in one adapter which will
9273 * applicable to all interfaces
9274 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309275 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009277
9278 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309279 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009280
Jeff Johnson295189b2012-06-20 16:38:30 -07009281
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009282#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009283#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9284 /* Initialize the wake lcok */
9285 wake_lock_init(&pHddCtx->rx_wake_lock,
9286 WAKE_LOCK_SUSPEND,
9287 "qcom_rx_wakelock");
9288#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009289 /* Initialize the wake lcok */
9290 wake_lock_init(&pHddCtx->sap_wake_lock,
9291 WAKE_LOCK_SUSPEND,
9292 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009293#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009294
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009295 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9296 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009297
Katya Nigam5c306ea2014-06-19 15:39:54 +05309298 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9300 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309301
9302#ifdef FEATURE_WLAN_SCAN_PNO
9303 /*SME must send channel update configuration to RIVA*/
9304 sme_UpdateChannelConfig(pHddCtx->hHal);
9305#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309306 /* Send the update default channel list to the FW*/
9307 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309308#ifndef CONFIG_ENABLE_LINUX_REG
9309 /*updating wiphy so that regulatory user hints can be processed*/
9310 if (wiphy)
9311 {
9312 regulatory_hint(wiphy, "00");
9313 }
9314#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009315 // Initialize the restart logic
9316 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309317
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009318 //Register the traffic monitor timer now
9319 if ( pHddCtx->cfg_ini->dynSplitscan)
9320 {
9321 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9322 VOS_TIMER_TYPE_SW,
9323 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9324 (void *)pHddCtx);
9325 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309326#ifdef WLAN_FEATURE_EXTSCAN
9327 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9328 wlan_hdd_cfg80211_extscan_callback,
9329 pHddCtx);
9330#endif /* WLAN_FEATURE_EXTSCAN */
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 goto success;
9332
9333err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009334#ifdef WLAN_KD_READY_NOTIFIER
9335 nl_srv_exit(pHddCtx->ptt_pid);
9336#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009337 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009338#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009339err_reg_netdev:
9340 unregister_netdevice_notifier(&hdd_netdev_notifier);
9341
9342err_free_power_on_lock:
9343 free_riva_power_on_lock("wlan");
9344
9345err_unregister_pmops:
9346 hddDevTmUnregisterNotifyCallback(pHddCtx);
9347 hddDeregisterPmOps(pHddCtx);
9348
Yue Ma0d4891e2013-08-06 17:01:45 -07009349 hdd_debugfs_exit(pHddCtx);
9350
Jeff Johnson295189b2012-06-20 16:38:30 -07009351#ifdef WLAN_BTAMP_FEATURE
9352err_bap_stop:
9353 WLANBAP_Stop(pVosContext);
9354#endif
9355
9356#ifdef WLAN_BTAMP_FEATURE
9357err_bap_close:
9358 WLANBAP_Close(pVosContext);
9359#endif
9360
Jeff Johnson295189b2012-06-20 16:38:30 -07009361err_close_adapter:
9362 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309363#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309364err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309365#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309366 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009367err_vosstop:
9368 vos_stop(pVosContext);
9369
Amar Singhala49cbc52013-10-08 18:37:44 -07009370err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009371 status = vos_sched_close( pVosContext );
9372 if (!VOS_IS_STATUS_SUCCESS(status)) {
9373 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9374 "%s: Failed to close VOSS Scheduler", __func__);
9375 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9376 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009377 vos_close(pVosContext );
9378
Amar Singhal0a402232013-10-11 20:57:16 -07009379err_vos_nv_close:
9380
c_hpothue6a36282014-03-19 12:27:38 +05309381#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009382 vos_nv_close();
9383
c_hpothu70f8d812014-03-22 22:59:23 +05309384#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009385
9386err_wdclose:
9387 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9388 vos_watchdog_close(pVosContext);
9389
Jeff Johnson295189b2012-06-20 16:38:30 -07009390err_config:
9391 kfree(pHddCtx->cfg_ini);
9392 pHddCtx->cfg_ini= NULL;
9393
9394err_free_hdd_context:
9395 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 wiphy_free(wiphy) ;
9397 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 VOS_BUG(1);
9399
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009400 if (hdd_is_ssr_required())
9401 {
9402 /* WDI timeout had happened during load, so SSR is needed here */
9403 subsystem_restart("wcnss");
9404 msleep(5000);
9405 }
9406 hdd_set_ssr_required (VOS_FALSE);
9407
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009408 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009409
9410success:
9411 EXIT();
9412 return 0;
9413}
9414
9415/**---------------------------------------------------------------------------
9416
Jeff Johnson32d95a32012-09-10 13:15:23 -07009417 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009418
Jeff Johnson32d95a32012-09-10 13:15:23 -07009419 This is the driver entry point - called in different timeline depending
9420 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009421
9422 \param - None
9423
9424 \return - 0 for success, non zero for failure
9425
9426 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009427static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009428{
9429 VOS_STATUS status;
9430 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009431 struct device *dev = NULL;
9432 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009433#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9434 int max_retries = 0;
9435#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009436
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309437#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9438 wlan_logging_sock_init_svc();
9439#endif
9440
Jeff Johnson295189b2012-06-20 16:38:30 -07009441 ENTER();
9442
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009443#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009445#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009446
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309447 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9449 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9450
Jeff Johnson295189b2012-06-20 16:38:30 -07009451#ifdef ANI_BUS_TYPE_PCI
9452
9453 dev = wcnss_wlan_get_device();
9454
9455#endif // ANI_BUS_TYPE_PCI
9456
9457#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009458
9459#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9460 /* wait until WCNSS driver downloads NV */
9461 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9462 msleep(1000);
9463 }
9464 if (max_retries >= 5) {
9465 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309466#ifdef WLAN_OPEN_SOURCE
9467 wake_lock_destroy(&wlan_wake_lock);
9468#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309469
9470#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9471 wlan_logging_sock_deinit_svc();
9472#endif
9473
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009474 return -ENODEV;
9475 }
9476#endif
9477
Jeff Johnson295189b2012-06-20 16:38:30 -07009478 dev = wcnss_wlan_get_device();
9479#endif // ANI_BUS_TYPE_PLATFORM
9480
9481
9482 do {
9483 if (NULL == dev) {
9484 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9485 ret_status = -1;
9486 break;
9487 }
9488
Jeff Johnson295189b2012-06-20 16:38:30 -07009489#ifdef TIMER_MANAGER
9490 vos_timer_manager_init();
9491#endif
9492
9493 /* Preopen VOSS so that it is ready to start at least SAL */
9494 status = vos_preOpen(&pVosContext);
9495
9496 if (!VOS_IS_STATUS_SUCCESS(status))
9497 {
9498 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9499 ret_status = -1;
9500 break;
9501 }
9502
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009503#ifndef MODULE
9504 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9505 */
9506 hdd_set_conparam((v_UINT_t)con_mode);
9507#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009508
9509 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009510 if (hdd_wlan_startup(dev))
9511 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009512 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009513 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 vos_preClose( &pVosContext );
9515 ret_status = -1;
9516 break;
9517 }
9518
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 } while (0);
9520
9521 if (0 != ret_status)
9522 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009523#ifdef TIMER_MANAGER
9524 vos_timer_exit();
9525#endif
9526#ifdef MEMORY_DEBUG
9527 vos_mem_exit();
9528#endif
9529
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009530#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009532#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309533
9534#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9535 wlan_logging_sock_deinit_svc();
9536#endif
9537
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9539 }
9540 else
9541 {
9542 //Send WLAN UP indication to Nlink Service
9543 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9544
9545 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009546 }
9547
9548 EXIT();
9549
9550 return ret_status;
9551}
9552
Jeff Johnson32d95a32012-09-10 13:15:23 -07009553/**---------------------------------------------------------------------------
9554
9555 \brief hdd_module_init() - Init Function
9556
9557 This is the driver entry point (invoked when module is loaded using insmod)
9558
9559 \param - None
9560
9561 \return - 0 for success, non zero for failure
9562
9563 --------------------------------------------------------------------------*/
9564#ifdef MODULE
9565static int __init hdd_module_init ( void)
9566{
9567 return hdd_driver_init();
9568}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009569#else /* #ifdef MODULE */
9570static int __init hdd_module_init ( void)
9571{
9572 /* Driver initialization is delayed to fwpath_changed_handler */
9573 return 0;
9574}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009575#endif /* #ifdef MODULE */
9576
Jeff Johnson295189b2012-06-20 16:38:30 -07009577
9578/**---------------------------------------------------------------------------
9579
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009580 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009581
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009582 This is the driver exit point (invoked when module is unloaded using rmmod
9583 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009584
9585 \param - None
9586
9587 \return - None
9588
9589 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009590static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009591{
9592 hdd_context_t *pHddCtx = NULL;
9593 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309594 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309595 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009596
9597 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9598
9599 //Get the global vos context
9600 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9601
9602 if(!pVosContext)
9603 {
9604 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9605 goto done;
9606 }
9607
9608 //Get the HDD context.
9609 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9610
9611 if(!pHddCtx)
9612 {
9613 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9614 }
9615 else
9616 {
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309617 INIT_COMPLETION(pHddCtx->ssr_comp_var);
9618
9619 if (pHddCtx->isLogpInProgress)
9620 {
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309622 "%s:SSR in Progress; block rmmod !!!", __func__);
9623 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9624 msecs_to_jiffies(30000));
9625 if(!rc)
9626 {
9627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9628 "%s:SSR timedout, fatal error", __func__);
9629 VOS_BUG(0);
Sameer Thalappil451ebb92013-06-28 15:49:58 -07009630 }
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309631 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009632
Vinay Krishna Erannae362b452014-09-23 13:09:46 +05309633 rtnl_lock();
Mihir Shete18156292014-03-11 15:38:30 +05309634 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Vinay Krishna Erannae362b452014-09-23 13:09:46 +05309636 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -07009637
Agarwal Ashish8db39882014-07-30 21:56:07 +05309638 /* Driver Need to send country code 00 in below condition
9639 * 1) If gCountryCodePriority is set to 1; and last country
9640 * code set is through 11d. This needs to be done in case
9641 * when NV country code is 00.
9642 * This Needs to be done as when kernel store last country
9643 * code and if stored country code is not through 11d,
9644 * in sme_HandleChangeCountryCodeByUser we will disable 11d
9645 * in next load/unload as soon as we get any country through
9646 * 11d. In sme_HandleChangeCountryCodeByUser
9647 * pMsg->countryCode will be last countryCode and
9648 * pMac->scan.countryCode11d will be country through 11d so
9649 * due to mismatch driver will disable 11d.
9650 *
Agarwal Ashish8db39882014-07-30 21:56:07 +05309651 */
9652
9653 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309654 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +05309655 sme_Is11dSupported(pHddCtx->hHal)))
Agarwal Ashish5e414792014-06-08 15:25:23 +05309656 {
Agarwal Ashish8dcd2862014-07-25 11:58:52 +05309657 hddLog(VOS_TRACE_LEVEL_INFO,
9658 FL("CountryCode 00 is being set while unloading driver"));
Agarwal Ashish5e414792014-06-08 15:25:23 +05309659 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
9660 }
9661
Jeff Johnson295189b2012-06-20 16:38:30 -07009662 //Do all the cleanup before deregistering the driver
9663 hdd_wlan_exit(pHddCtx);
9664 }
9665
Jeff Johnson295189b2012-06-20 16:38:30 -07009666 vos_preClose( &pVosContext );
9667
9668#ifdef TIMER_MANAGER
9669 vos_timer_exit();
9670#endif
9671#ifdef MEMORY_DEBUG
9672 vos_mem_exit();
9673#endif
9674
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309675#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9676 wlan_logging_sock_deinit_svc();
9677#endif
9678
Jeff Johnson295189b2012-06-20 16:38:30 -07009679done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009680#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009682#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309683
Jeff Johnson295189b2012-06-20 16:38:30 -07009684 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
9685}
9686
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009687/**---------------------------------------------------------------------------
9688
9689 \brief hdd_module_exit() - Exit function
9690
9691 This is the driver exit point (invoked when module is unloaded using rmmod)
9692
9693 \param - None
9694
9695 \return - None
9696
9697 --------------------------------------------------------------------------*/
9698static void __exit hdd_module_exit(void)
9699{
9700 hdd_driver_exit();
9701}
9702
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009703#ifdef MODULE
9704static int fwpath_changed_handler(const char *kmessage,
9705 struct kernel_param *kp)
9706{
Jeff Johnson76052702013-04-16 13:55:05 -07009707 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009708}
9709
9710static int con_mode_handler(const char *kmessage,
9711 struct kernel_param *kp)
9712{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -07009713 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009714}
9715#else /* #ifdef MODULE */
9716/**---------------------------------------------------------------------------
9717
Jeff Johnson76052702013-04-16 13:55:05 -07009718 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009719
Jeff Johnson76052702013-04-16 13:55:05 -07009720 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009721 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -07009722 - invoked when module parameter fwpath is modified from userspace to signal
9723 initializing the WLAN driver or when con_mode is modified from userspace
9724 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009725
9726 \return - 0 for success, non zero for failure
9727
9728 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009729static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009730{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009731 int ret_status;
9732
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009733 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009734 ret_status = hdd_driver_init();
9735 wlan_hdd_inited = ret_status ? 0 : 1;
9736 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009737 }
9738
9739 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -07009740
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009741 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -07009742
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -07009743 ret_status = hdd_driver_init();
9744 wlan_hdd_inited = ret_status ? 0 : 1;
9745 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -07009746}
9747
Jeff Johnson295189b2012-06-20 16:38:30 -07009748/**---------------------------------------------------------------------------
9749
Jeff Johnson76052702013-04-16 13:55:05 -07009750 \brief fwpath_changed_handler() - Handler Function
9751
9752 Handle changes to the fwpath parameter
9753
9754 \return - 0 for success, non zero for failure
9755
9756 --------------------------------------------------------------------------*/
9757static int fwpath_changed_handler(const char *kmessage,
9758 struct kernel_param *kp)
9759{
9760 int ret;
9761
9762 ret = param_set_copystring(kmessage, kp);
9763 if (0 == ret)
9764 ret = kickstart_driver();
9765 return ret;
9766}
9767
9768/**---------------------------------------------------------------------------
9769
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009770 \brief con_mode_handler() -
9771
9772 Handler function for module param con_mode when it is changed by userspace
9773 Dynamically linked - do nothing
9774 Statically linked - exit and init driver, as in rmmod and insmod
9775
Jeff Johnson76052702013-04-16 13:55:05 -07009776 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009777
Jeff Johnson76052702013-04-16 13:55:05 -07009778 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009779
9780 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -07009781static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009782{
Jeff Johnson76052702013-04-16 13:55:05 -07009783 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009784
Jeff Johnson76052702013-04-16 13:55:05 -07009785 ret = param_set_int(kmessage, kp);
9786 if (0 == ret)
9787 ret = kickstart_driver();
9788 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009789}
9790#endif /* #ifdef MODULE */
9791
9792/**---------------------------------------------------------------------------
9793
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 \brief hdd_get_conparam() -
9795
9796 This is the driver exit point (invoked when module is unloaded using rmmod)
9797
9798 \param - None
9799
9800 \return - tVOS_CON_MODE
9801
9802 --------------------------------------------------------------------------*/
9803tVOS_CON_MODE hdd_get_conparam ( void )
9804{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009805#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009807#else
9808 return (tVOS_CON_MODE)curr_con_mode;
9809#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009810}
9811void hdd_set_conparam ( v_UINT_t newParam )
9812{
9813 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009814#ifndef MODULE
9815 curr_con_mode = con_mode;
9816#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009817}
9818/**---------------------------------------------------------------------------
9819
9820 \brief hdd_softap_sta_deauth() - function
9821
9822 This to take counter measure to handle deauth req from HDD
9823
9824 \param - pAdapter - Pointer to the HDD
9825
9826 \param - enable - boolean value
9827
9828 \return - None
9829
9830 --------------------------------------------------------------------------*/
9831
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009832VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, v_U8_t *pDestMacAddress)
Jeff Johnson295189b2012-06-20 16:38:30 -07009833{
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009835 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -07009836
9837 ENTER();
9838
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07009839 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
9840 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009841
9842 //Ignore request to deauth bcmc station
9843 if( pDestMacAddress[0] & 0x1 )
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009844 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009845
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009846 vosStatus = WLANSAP_DeauthSta(pVosContext,pDestMacAddress);
Jeff Johnson295189b2012-06-20 16:38:30 -07009847
9848 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08009849 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07009850}
9851
9852/**---------------------------------------------------------------------------
9853
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309854 \brief hdd_del_all_sta() - function
9855
9856 This function removes all the stations associated on stopping AP/P2P GO.
9857
9858 \param - pAdapter - Pointer to the HDD
9859
9860 \return - None
9861
9862 --------------------------------------------------------------------------*/
9863
9864int hdd_del_all_sta(hdd_adapter_t *pAdapter)
9865{
9866 v_U16_t i;
9867 VOS_STATUS vos_status;
9868
9869 ENTER();
9870
9871 hddLog(VOS_TRACE_LEVEL_INFO,
9872 "%s: Delete all STAs associated.",__func__);
9873 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9874 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
9875 )
9876 {
9877 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
9878 {
9879 if ((pAdapter->aStaInfo[i].isUsed) &&
9880 (!pAdapter->aStaInfo[i].isDeauthInProgress))
9881 {
9882 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
9883 hddLog(VOS_TRACE_LEVEL_ERROR,
9884 "%s: Delete STA with staid = %d and MAC::"
9885 MAC_ADDRESS_STR,
9886 __func__, i, MAC_ADDR_ARRAY(macAddr));
9887 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
9888 if (VOS_IS_STATUS_SUCCESS(vos_status))
9889 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
9890 }
9891 }
9892 }
9893
9894 EXIT();
9895 return 0;
9896}
9897
9898/**---------------------------------------------------------------------------
9899
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 \brief hdd_softap_sta_disassoc() - function
9901
9902 This to take counter measure to handle deauth req from HDD
9903
9904 \param - pAdapter - Pointer to the HDD
9905
9906 \param - enable - boolean value
9907
9908 \return - None
9909
9910 --------------------------------------------------------------------------*/
9911
9912void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
9913{
9914 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9915
9916 ENTER();
9917
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309918 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009919
9920 //Ignore request to disassoc bcmc station
9921 if( pDestMacAddress[0] & 0x1 )
9922 return;
9923
9924 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
9925}
9926
9927void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
9928{
9929 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
9930
9931 ENTER();
9932
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309933 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07009934
9935 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
9936}
9937
Jeff Johnson295189b2012-06-20 16:38:30 -07009938/**---------------------------------------------------------------------------
9939 *
9940 * \brief hdd_get__concurrency_mode() -
9941 *
9942 *
9943 * \param - None
9944 *
9945 * \return - CONCURRENCY MODE
9946 *
9947 * --------------------------------------------------------------------------*/
9948tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
9949{
9950 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
9951 hdd_context_t *pHddCtx;
9952
9953 if (NULL != pVosContext)
9954 {
9955 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
9956 if (NULL != pHddCtx)
9957 {
9958 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
9959 }
9960 }
9961
9962 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009963 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 return VOS_STA;
9965}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309966v_BOOL_t
9967wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
9968{
9969 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009970
Sushant Kaushikabb7ee62014-07-18 16:20:12 +05309971 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
9972 if (pAdapter == NULL)
9973 {
9974 hddLog(VOS_TRACE_LEVEL_INFO,
9975 FL("GO doesn't exist"));
9976 return TRUE;
9977 }
9978 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9979 {
9980 hddLog(VOS_TRACE_LEVEL_INFO,
9981 FL("GO started"));
9982 return TRUE;
9983 }
9984 else
9985 /* wait till GO changes its interface to p2p device */
9986 hddLog(VOS_TRACE_LEVEL_INFO,
9987 FL("Del_bss called, avoid apps suspend"));
9988 return FALSE;
9989
9990}
Jeff Johnson295189b2012-06-20 16:38:30 -07009991/* Decide whether to allow/not the apps power collapse.
9992 * Allow apps power collapse if we are in connected state.
9993 * if not, allow only if we are in IMPS */
9994v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
9995{
9996 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -08009997 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -08009998 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009999 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10000 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10001 hdd_adapter_t *pAdapter = NULL;
10002 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010003 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010004
Jeff Johnson295189b2012-06-20 16:38:30 -070010005 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10006 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010007
Yathish9f22e662012-12-10 14:21:35 -080010008 concurrent_state = hdd_get_concurrency_mode();
10009
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010010 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10011 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10012 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010013#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010014
Yathish9f22e662012-12-10 14:21:35 -080010015 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010016 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010017 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10018 return TRUE;
10019#endif
10020
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 /*loop through all adapters. TBD fix for Concurrency */
10022 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10023 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10024 {
10025 pAdapter = pAdapterNode->pAdapter;
10026 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10027 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10028 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010029 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010030 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
Srikant Kuppafef66a72013-01-30 17:32:44 -080010031 && pmcState != STOPPED && pmcState != STANDBY)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010032 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10033 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010035 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010036 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10037 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 return FALSE;
10039 }
10040 }
10041 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10042 pAdapterNode = pNext;
10043 }
10044 return TRUE;
10045}
10046
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010047/* Decides whether to send suspend notification to Riva
10048 * if any adapter is in BMPS; then it is required */
10049v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10050{
10051 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10052 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10053
10054 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10055 {
10056 return TRUE;
10057 }
10058 return FALSE;
10059}
10060
Jeff Johnson295189b2012-06-20 16:38:30 -070010061void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10062{
10063 switch(mode)
10064 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010065 case VOS_STA_MODE:
10066 case VOS_P2P_CLIENT_MODE:
10067 case VOS_P2P_GO_MODE:
10068 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010069 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010070 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 break;
10072 default:
10073 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010075 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10076 "Number of open sessions for mode %d = %d"),
10077 pHddCtx->concurrency_mode, mode,
10078 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010079}
10080
10081
10082void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10083{
10084 switch(mode)
10085 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010086 case VOS_STA_MODE:
10087 case VOS_P2P_CLIENT_MODE:
10088 case VOS_P2P_GO_MODE:
10089 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010090 pHddCtx->no_of_open_sessions[mode]--;
10091 if (!(pHddCtx->no_of_open_sessions[mode]))
10092 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010093 break;
10094 default:
10095 break;
10096 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010097 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10098 "Number of open sessions for mode %d = %d"),
10099 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10100
10101}
10102/**---------------------------------------------------------------------------
10103 *
10104 * \brief wlan_hdd_incr_active_session()
10105 *
10106 * This function increments the number of active sessions
10107 * maintained per device mode
10108 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10109 * Incase of SAP/P2P GO upon bss start it is incremented
10110 *
10111 * \param pHddCtx - HDD Context
10112 * \param mode - device mode
10113 *
10114 * \return - None
10115 *
10116 * --------------------------------------------------------------------------*/
10117void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10118{
10119 switch (mode) {
10120 case VOS_STA_MODE:
10121 case VOS_P2P_CLIENT_MODE:
10122 case VOS_P2P_GO_MODE:
10123 case VOS_STA_SAP_MODE:
10124 pHddCtx->no_of_active_sessions[mode]++;
10125 break;
10126 default:
10127 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10128 break;
10129 }
10130 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10131 mode,
10132 pHddCtx->no_of_active_sessions[mode]);
10133}
10134
10135/**---------------------------------------------------------------------------
10136 *
10137 * \brief wlan_hdd_decr_active_session()
10138 *
10139 * This function decrements the number of active sessions
10140 * maintained per device mode
10141 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10142 * Incase of SAP/P2P GO upon bss stop it is decremented
10143 *
10144 * \param pHddCtx - HDD Context
10145 * \param mode - device mode
10146 *
10147 * \return - None
10148 *
10149 * --------------------------------------------------------------------------*/
10150void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10151{
10152 switch (mode) {
10153 case VOS_STA_MODE:
10154 case VOS_P2P_CLIENT_MODE:
10155 case VOS_P2P_GO_MODE:
10156 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010157 if (pHddCtx->no_of_active_sessions[mode] > 0)
10158 pHddCtx->no_of_active_sessions[mode]--;
10159 else
10160 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10161 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010162 break;
10163 default:
10164 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10165 break;
10166 }
10167 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10168 mode,
10169 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010170}
10171
Jeff Johnsone7245742012-09-05 17:12:55 -070010172/**---------------------------------------------------------------------------
10173 *
10174 * \brief wlan_hdd_restart_init
10175 *
10176 * This function initalizes restart timer/flag. An internal function.
10177 *
10178 * \param - pHddCtx
10179 *
10180 * \return - None
10181 *
10182 * --------------------------------------------------------------------------*/
10183
10184static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10185{
10186 /* Initialize */
10187 pHddCtx->hdd_restart_retries = 0;
10188 atomic_set(&pHddCtx->isRestartInProgress, 0);
10189 vos_timer_init(&pHddCtx->hdd_restart_timer,
10190 VOS_TIMER_TYPE_SW,
10191 wlan_hdd_restart_timer_cb,
10192 pHddCtx);
10193}
10194/**---------------------------------------------------------------------------
10195 *
10196 * \brief wlan_hdd_restart_deinit
10197 *
10198 * This function cleans up the resources used. An internal function.
10199 *
10200 * \param - pHddCtx
10201 *
10202 * \return - None
10203 *
10204 * --------------------------------------------------------------------------*/
10205
10206static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10207{
10208
10209 VOS_STATUS vos_status;
10210 /* Block any further calls */
10211 atomic_set(&pHddCtx->isRestartInProgress, 1);
10212 /* Cleanup */
10213 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10214 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010215 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010216 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10217 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010218 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010219
10220}
10221
10222/**---------------------------------------------------------------------------
10223 *
10224 * \brief wlan_hdd_framework_restart
10225 *
10226 * This function uses a cfg80211 API to start a framework initiated WLAN
10227 * driver module unload/load.
10228 *
10229 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10230 *
10231 *
10232 * \param - pHddCtx
10233 *
10234 * \return - VOS_STATUS_SUCCESS: Success
10235 * VOS_STATUS_E_EMPTY: Adapter is Empty
10236 * VOS_STATUS_E_NOMEM: No memory
10237
10238 * --------------------------------------------------------------------------*/
10239
10240static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10241{
10242 VOS_STATUS status = VOS_STATUS_SUCCESS;
10243 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010244 int len = (sizeof (struct ieee80211_mgmt));
10245 struct ieee80211_mgmt *mgmt = NULL;
10246
10247 /* Prepare the DEAUTH managment frame with reason code */
10248 mgmt = kzalloc(len, GFP_KERNEL);
10249 if(mgmt == NULL)
10250 {
10251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10252 "%s: memory allocation failed (%d bytes)", __func__, len);
10253 return VOS_STATUS_E_NOMEM;
10254 }
10255 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010256
10257 /* Iterate over all adapters/devices */
10258 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10259 do
10260 {
10261 if( (status == VOS_STATUS_SUCCESS) &&
10262 pAdapterNode &&
10263 pAdapterNode->pAdapter)
10264 {
10265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10266 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10267 pAdapterNode->pAdapter->dev->name,
10268 pAdapterNode->pAdapter->device_mode,
10269 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010270 /*
10271 * CFG80211 event to restart the driver
10272 *
10273 * 'cfg80211_send_unprot_deauth' sends a
10274 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10275 * of SME(Linux Kernel) state machine.
10276 *
10277 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10278 * the driver.
10279 *
10280 */
10281
10282 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010283 }
10284 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10285 pAdapterNode = pNext;
10286 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10287
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010288
10289 /* Free the allocated management frame */
10290 kfree(mgmt);
10291
Jeff Johnsone7245742012-09-05 17:12:55 -070010292 /* Retry until we unload or reach max count */
10293 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10294 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10295
10296 return status;
10297
10298}
10299/**---------------------------------------------------------------------------
10300 *
10301 * \brief wlan_hdd_restart_timer_cb
10302 *
10303 * Restart timer callback. An internal function.
10304 *
10305 * \param - User data:
10306 *
10307 * \return - None
10308 *
10309 * --------------------------------------------------------------------------*/
10310
10311void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10312{
10313 hdd_context_t *pHddCtx = usrDataForCallback;
10314 wlan_hdd_framework_restart(pHddCtx);
10315 return;
10316
10317}
10318
10319
10320/**---------------------------------------------------------------------------
10321 *
10322 * \brief wlan_hdd_restart_driver
10323 *
10324 * This function sends an event to supplicant to restart the WLAN driver.
10325 *
10326 * This function is called from vos_wlanRestart.
10327 *
10328 * \param - pHddCtx
10329 *
10330 * \return - VOS_STATUS_SUCCESS: Success
10331 * VOS_STATUS_E_EMPTY: Adapter is Empty
10332 * VOS_STATUS_E_ALREADY: Request already in progress
10333
10334 * --------------------------------------------------------------------------*/
10335VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10336{
10337 VOS_STATUS status = VOS_STATUS_SUCCESS;
10338
10339 /* A tight check to make sure reentrancy */
10340 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10341 {
Mihir Shetefd528652014-06-23 19:07:50 +053010342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010343 "%s: WLAN restart is already in progress", __func__);
10344
10345 return VOS_STATUS_E_ALREADY;
10346 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010347 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010348#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010349 wcnss_reset_intr();
10350#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010351
Jeff Johnsone7245742012-09-05 17:12:55 -070010352 return status;
10353}
10354
Mihir Shetee1093ba2014-01-21 20:13:32 +053010355/**---------------------------------------------------------------------------
10356 *
10357 * \brief wlan_hdd_init_channels
10358 *
10359 * This function is used to initialize the channel list in CSR
10360 *
10361 * This function is called from hdd_wlan_startup
10362 *
10363 * \param - pHddCtx: HDD context
10364 *
10365 * \return - VOS_STATUS_SUCCESS: Success
10366 * VOS_STATUS_E_FAULT: Failure reported by SME
10367
10368 * --------------------------------------------------------------------------*/
10369static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10370{
10371 eHalStatus status;
10372
10373 status = sme_InitChannels(pHddCtx->hHal);
10374 if (HAL_STATUS_SUCCESS(status))
10375 {
10376 return VOS_STATUS_SUCCESS;
10377 }
10378 else
10379 {
10380 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10381 __func__, status);
10382 return VOS_STATUS_E_FAULT;
10383 }
10384}
10385
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010386VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010387{
10388 eHalStatus status;
10389
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010390 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010391 if (HAL_STATUS_SUCCESS(status))
10392 {
10393 return VOS_STATUS_SUCCESS;
10394 }
10395 else
10396 {
10397 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10398 __func__, status);
10399 return VOS_STATUS_E_FAULT;
10400 }
10401}
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010402/*
10403 * API to find if there is any STA or P2P-Client is connected
10404 */
10405VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10406{
10407 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10408}
Jeff Johnsone7245742012-09-05 17:12:55 -070010409
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010410int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10411{
10412 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10413 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010414 long status = 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010415
10416 pScanInfo = &pHddCtx->scan_info;
10417 if (pScanInfo->mScanPending)
10418 {
10419 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010420 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010421 eCSR_SCAN_ABORT_DEFAULT);
10422
10423 status = wait_for_completion_interruptible_timeout(
10424 &pScanInfo->abortscan_event_var,
10425 msecs_to_jiffies(5000));
Girish Gowli4bf7a632014-06-12 13:42:11 +053010426 if (0 >= status)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010427 {
10428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010429 "%s: Timeout or Interrupt occurred while waiting for abort"
10430 "scan, status- %ld", __func__, status);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010431 return -ETIMEDOUT;
10432 }
10433 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010434 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010435}
10436
c_hpothu225aa7c2014-10-22 17:45:13 +053010437VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10438{
10439 hdd_adapter_t *pAdapter;
10440 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10441 VOS_STATUS vosStatus;
10442
10443 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10444 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10445 {
10446 pAdapter = pAdapterNode->pAdapter;
10447 if (NULL != pAdapter)
10448 {
10449 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10450 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10451 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10452 {
10453 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10454 pAdapter->device_mode);
10455 if (VOS_STATUS_SUCCESS !=
10456 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10457 {
10458 hddLog(LOGE, FL("failed to abort ROC"));
10459 return VOS_STATUS_E_FAILURE;
10460 }
10461 }
10462 }
10463 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10464 pAdapterNode = pNext;
10465 }
10466 return VOS_STATUS_SUCCESS;
10467}
Jeff Johnson295189b2012-06-20 16:38:30 -070010468//Register the module init/exit functions
10469module_init(hdd_module_init);
10470module_exit(hdd_module_exit);
10471
10472MODULE_LICENSE("Dual BSD/GPL");
10473MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10474MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10475
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010476module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10477 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010478
Jeff Johnson76052702013-04-16 13:55:05 -070010479module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010480 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010481
10482module_param(enable_dfs_chan_scan, int,
10483 S_IRUSR | S_IRGRP | S_IROTH);
10484
10485module_param(enable_11d, int,
10486 S_IRUSR | S_IRGRP | S_IROTH);
10487
10488module_param(country_code, charp,
10489 S_IRUSR | S_IRGRP | S_IROTH);