blob: e8467708660ab2b32873b3c65b43a1777e373988 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
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
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800197#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700200/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700201static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700202
203//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700204static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
206static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
207void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800208void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700209
Jeff Johnson295189b2012-06-20 16:38:30 -0700210v_U16_t hdd_select_queue(struct net_device *dev,
211 struct sk_buff *skb);
212
213#ifdef WLAN_FEATURE_PACKET_FILTERING
214static void hdd_set_multicast_list(struct net_device *dev);
215#endif
216
217void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
218
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800219#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800220void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
221static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700222static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
223 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
224 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700225static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
226 tANI_U8 *pTargetApBssid,
227 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800228#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800229#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700230VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800231#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700232
Mihir Shetee1093ba2014-01-21 20:13:32 +0530233static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530234const char * hdd_device_modetoString(v_U8_t device_mode)
235{
236 switch(device_mode)
237 {
238 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
239 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
240 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
241 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
242 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
243 CASE_RETURN_STRING( WLAN_HDD_FTM );
244 CASE_RETURN_STRING( WLAN_HDD_IBSS );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
246 default:
247 return "device_mode Unknown";
248 }
249}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530250
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530251static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700252 unsigned long state,
253 void *ndev)
254{
255 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700256 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700257 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700258#ifdef WLAN_BTAMP_FEATURE
259 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700260#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530261 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262
263 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700264 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700265 (strncmp(dev->name, "p2p", 3)))
266 return NOTIFY_DONE;
267
Jeff Johnson295189b2012-06-20 16:38:30 -0700268 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700269 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700270
Jeff Johnson27cee452013-03-27 11:10:24 -0700271 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800273 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700274 VOS_ASSERT(0);
275 return NOTIFY_DONE;
276 }
277
Jeff Johnson27cee452013-03-27 11:10:24 -0700278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
279 if (NULL == pHddCtx)
280 {
281 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
282 VOS_ASSERT(0);
283 return NOTIFY_DONE;
284 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800285 if (pHddCtx->isLogpInProgress)
286 return NOTIFY_DONE;
287
Jeff Johnson27cee452013-03-27 11:10:24 -0700288
289 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
290 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700291
292 switch (state) {
293 case NETDEV_REGISTER:
294 break;
295
296 case NETDEV_UNREGISTER:
297 break;
298
299 case NETDEV_UP:
300 break;
301
302 case NETDEV_DOWN:
303 break;
304
305 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700306 if(TRUE == pAdapter->isLinkUpSvcNeeded)
307 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 break;
309
310 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530311 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530312 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530313 {
314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
315 "%s: Timeout occurred while waiting for abortscan %ld",
316 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700317 }
318 else
319 {
320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530321 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 }
323#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 status = WLANBAP_StopAmp();
326 if(VOS_STATUS_SUCCESS != status )
327 {
328 pHddCtx->isAmpAllowed = VOS_TRUE;
329 hddLog(VOS_TRACE_LEVEL_FATAL,
330 "%s: Failed to stop AMP", __func__);
331 }
332 else
333 {
334 //a state m/c implementation in PAL is TBD to avoid this delay
335 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700336 if ( pHddCtx->isAmpAllowed )
337 {
338 WLANBAP_DeregisterFromHCI();
339 pHddCtx->isAmpAllowed = VOS_FALSE;
340 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 }
342#endif //WLAN_BTAMP_FEATURE
343 break;
344
345 default:
346 break;
347 }
348
349 return NOTIFY_DONE;
350}
351
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530352static int hdd_netdev_notifier_call(struct notifier_block * nb,
353 unsigned long state,
354 void *ndev)
355{
356 int ret;
357 vos_ssr_protect(__func__);
358 ret = __hdd_netdev_notifier_call( nb, state, ndev);
359 vos_ssr_unprotect(__func__);
360 return ret;
361}
362
Jeff Johnson295189b2012-06-20 16:38:30 -0700363struct notifier_block hdd_netdev_notifier = {
364 .notifier_call = hdd_netdev_notifier_call,
365};
366
367/*---------------------------------------------------------------------------
368 * Function definitions
369 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700370void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
371void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700372//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700373static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700374#ifndef MODULE
375/* current con_mode - used only for statically linked driver
376 * con_mode is changed by userspace to indicate a mode change which will
377 * result in calling the module exit and init functions. The module
378 * exit function will clean up based on the value of con_mode prior to it
379 * being changed by userspace. So curr_con_mode records the current con_mode
380 * for exit when con_mode becomes the next mode for init
381 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700382static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700383#endif
384
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800385/**---------------------------------------------------------------------------
386
387 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
388
389 Called immediately after the cfg.ini is read in order to configure
390 the desired trace levels.
391
392 \param - moduleId - module whose trace level is being configured
393 \param - bitmask - bitmask of log levels to be enabled
394
395 \return - void
396
397 --------------------------------------------------------------------------*/
398static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
399{
400 wpt_tracelevel level;
401
402 /* if the bitmask is the default value, then a bitmask was not
403 specified in cfg.ini, so leave the logging level alone (it
404 will remain at the "compiled in" default value) */
405 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
406 {
407 return;
408 }
409
410 /* a mask was specified. start by disabling all logging */
411 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
412
413 /* now cycle through the bitmask until all "set" bits are serviced */
414 level = VOS_TRACE_LEVEL_FATAL;
415 while (0 != bitmask)
416 {
417 if (bitmask & 1)
418 {
419 vos_trace_setValue(moduleId, level, 1);
420 }
421 level++;
422 bitmask >>= 1;
423 }
424}
425
426
Jeff Johnson295189b2012-06-20 16:38:30 -0700427/**---------------------------------------------------------------------------
428
429 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
430
431 Called immediately after the cfg.ini is read in order to configure
432 the desired trace levels in the WDI.
433
434 \param - moduleId - module whose trace level is being configured
435 \param - bitmask - bitmask of log levels to be enabled
436
437 \return - void
438
439 --------------------------------------------------------------------------*/
440static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
441{
442 wpt_tracelevel level;
443
444 /* if the bitmask is the default value, then a bitmask was not
445 specified in cfg.ini, so leave the logging level alone (it
446 will remain at the "compiled in" default value) */
447 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
448 {
449 return;
450 }
451
452 /* a mask was specified. start by disabling all logging */
453 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
454
455 /* now cycle through the bitmask until all "set" bits are serviced */
456 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
457 while (0 != bitmask)
458 {
459 if (bitmask & 1)
460 {
461 wpalTraceSetLevel(moduleId, level, 1);
462 }
463 level++;
464 bitmask >>= 1;
465 }
466}
Jeff Johnson295189b2012-06-20 16:38:30 -0700467
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530468/*
469 * FUNCTION: wlan_hdd_validate_context
470 * This function is used to check the HDD context
471 */
472int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
473{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530474
475 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
476 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530478 "%s: HDD context is Null", __func__);
479 return -ENODEV;
480 }
481
482 if (pHddCtx->isLogpInProgress)
483 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530485 "%s: LOGP %s. Ignore!!", __func__,
486 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
487 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530488 return -EAGAIN;
489 }
490
Mihir Shete18156292014-03-11 15:38:30 +0530491 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530492 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530494 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
495 return -EAGAIN;
496 }
497 return 0;
498}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700499#ifdef CONFIG_ENABLE_LINUX_REG
500void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
501{
502 hdd_adapter_t *pAdapter = NULL;
503 hdd_station_ctx_t *pHddStaCtx = NULL;
504 eCsrPhyMode phyMode;
505 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530506
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700507 if (NULL == pHddCtx)
508 {
509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
510 "HDD Context is null !!");
511 return ;
512 }
513
514 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
515 if (NULL == pAdapter)
516 {
517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
518 "pAdapter is null !!");
519 return ;
520 }
521
522 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
523 if (NULL == pHddStaCtx)
524 {
525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
526 "pHddStaCtx is null !!");
527 return ;
528 }
529
530 cfg_param = pHddCtx->cfg_ini;
531 if (NULL == cfg_param)
532 {
533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
534 "cfg_params not available !!");
535 return ;
536 }
537
538 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
539
540 if (!pHddCtx->isVHT80Allowed)
541 {
542 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
543 (eCSR_DOT11_MODE_11ac == phyMode) ||
544 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
545 {
546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
547 "Setting phymode to 11n!!");
548 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
549 }
550 }
551 else
552 {
553 /*New country Supports 11ac as well resetting value back from .ini*/
554 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
555 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
556 return ;
557 }
558
559 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
560 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
561 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
562 {
563 VOS_STATUS vosStatus;
564
565 // need to issue a disconnect to CSR.
566 INIT_COMPLETION(pAdapter->disconnect_comp_var);
567 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
568 pAdapter->sessionId,
569 eCSR_DISCONNECT_REASON_UNSPECIFIED );
570
571 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530572 {
573 long ret;
574
575 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700576 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530577 if (0 >= ret)
578 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
579 ret);
580 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700581
582 }
583}
584#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530585void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
586{
587 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
588 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
589 hdd_config_t *cfg_param;
590 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530591 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530592
593 if (NULL == pHddCtx)
594 {
595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
596 "HDD Context is null !!");
597 return ;
598 }
599
600 cfg_param = pHddCtx->cfg_ini;
601
602 if (NULL == cfg_param)
603 {
604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
605 "cfg_params not available !!");
606 return ;
607 }
608
609 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
610
611 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
612 {
613 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
614 (eCSR_DOT11_MODE_11ac == phyMode) ||
615 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
618 "Setting phymode to 11n!!");
619 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
620 }
621 }
622 else
623 {
624 /*New country Supports 11ac as well resetting value back from .ini*/
625 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
626 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
627 return ;
628 }
629
630 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
631 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
632 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
633 {
634 VOS_STATUS vosStatus;
635
636 // need to issue a disconnect to CSR.
637 INIT_COMPLETION(pAdapter->disconnect_comp_var);
638 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
639 pAdapter->sessionId,
640 eCSR_DISCONNECT_REASON_UNSPECIFIED );
641
642 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530643 {
644 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530645 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530646 if (ret <= 0)
647 {
648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
649 "wait on disconnect_comp_var is failed %ld", ret);
650 }
651 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530652
653 }
654}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700655#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530656
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700657void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
658{
659 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
660 hdd_config_t *cfg_param;
661
662 if (NULL == pHddCtx)
663 {
664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
665 "HDD Context is null !!");
666 return ;
667 }
668
669 cfg_param = pHddCtx->cfg_ini;
670
671 if (NULL == cfg_param)
672 {
673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
674 "cfg_params not available !!");
675 return ;
676 }
677
Agarwal Ashish738843c2014-09-25 12:27:56 +0530678 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
679 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700680 {
681 /*New country doesn't support DFS */
682 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
683 }
684 else
685 {
686 /*New country Supports DFS as well resetting value back from .ini*/
687 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
688 }
689
690}
691
Rajeev79dbe4c2013-10-05 11:03:42 +0530692#ifdef FEATURE_WLAN_BATCH_SCAN
693
694/**---------------------------------------------------------------------------
695
696 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
697 input string
698
699 This function extracts assigned integer from string in below format:
700 "STRING=10" : extracts integer 10 from this string
701
702 \param - pInPtr Pointer to input string
703 \param - base Base for string to int conversion(10 for decimal 16 for hex)
704 \param - pOutPtr Pointer to variable in which extracted integer needs to be
705 assigned
706 \param - pLastArg to tell whether it is last arguement in input string or
707 not
708
709 \return - NULL for failure cases
710 pointer to next arguement in input string for success cases
711 --------------------------------------------------------------------------*/
712static tANI_U8 *
713hdd_extract_assigned_int_from_str
714(
715 tANI_U8 *pInPtr,
716 tANI_U8 base,
717 tANI_U32 *pOutPtr,
718 tANI_U8 *pLastArg
719)
720{
721 int tempInt;
722 int v = 0;
723 char buf[32];
724 int val = 0;
725 *pLastArg = FALSE;
726
727 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
728 if (NULL == pInPtr)
729 {
730 return NULL;
731 }
732
733 pInPtr++;
734
735 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
736
737 val = sscanf(pInPtr, "%32s ", buf);
738 if (val < 0 && val > strlen(pInPtr))
739 {
740 return NULL;
741 }
742 pInPtr += val;
743 v = kstrtos32(buf, base, &tempInt);
744 if (v < 0)
745 {
746 return NULL;
747 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800748 if (tempInt < 0)
749 {
750 tempInt = 0;
751 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530752 *pOutPtr = tempInt;
753
754 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
755 if (NULL == pInPtr)
756 {
757 *pLastArg = TRUE;
758 return NULL;
759 }
760 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
761
762 return pInPtr;
763}
764
765/**---------------------------------------------------------------------------
766
767 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
768 input string
769
770 This function extracts assigned character from string in below format:
771 "STRING=A" : extracts char 'A' from this string
772
773 \param - pInPtr Pointer to input string
774 \param - pOutPtr Pointer to variable in which extracted char needs to be
775 assigned
776 \param - pLastArg to tell whether it is last arguement in input string or
777 not
778
779 \return - NULL for failure cases
780 pointer to next arguement in input string for success cases
781 --------------------------------------------------------------------------*/
782static tANI_U8 *
783hdd_extract_assigned_char_from_str
784(
785 tANI_U8 *pInPtr,
786 tANI_U8 *pOutPtr,
787 tANI_U8 *pLastArg
788)
789{
790 *pLastArg = FALSE;
791
792 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
793 if (NULL == pInPtr)
794 {
795 return NULL;
796 }
797
798 pInPtr++;
799
800 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
801
802 *pOutPtr = *pInPtr;
803
804 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
805 if (NULL == pInPtr)
806 {
807 *pLastArg = TRUE;
808 return NULL;
809 }
810 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
811
812 return pInPtr;
813}
814
815
816/**---------------------------------------------------------------------------
817
818 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
819
820 This function parses set batch scan command in below format:
821 WLS_BATCHING_SET <space> followed by below arguements
822 "SCANFREQ=XX" : Optional defaults to 30 sec
823 "MSCAN=XX" : Required number of scans to attempt to batch
824 "BESTN=XX" : Best Network (RSSI) defaults to 16
825 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
826 A. implies only 5 GHz , B. implies only 2.4GHz
827 "RTT=X" : optional defaults to 0
828 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
829 error
830
831 For example input commands:
832 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
833 translated into set batch scan with following parameters:
834 a) Frequence 60 seconds
835 b) Batch 10 scans together
836 c) Best RSSI to be 20
837 d) 5GHz band only
838 e) RTT is equal to 0
839
840 \param - pValue Pointer to input channel list
841 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
842
843 \return - 0 for success non-zero for failure
844
845 --------------------------------------------------------------------------*/
846static int
847hdd_parse_set_batchscan_command
848(
849 tANI_U8 *pValue,
850 tSirSetBatchScanReq *pHddSetBatchScanReq
851)
852{
853 tANI_U8 *inPtr = pValue;
854 tANI_U8 val = 0;
855 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800856 tANI_U32 nScanFreq;
857 tANI_U32 nMscan;
858 tANI_U32 nBestN;
859 tANI_U8 ucRfBand;
860 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800861 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530862
863 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800864 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
865 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
866 nRtt = 0;
867 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530868
869 /*go to space after WLS_BATCHING_SET command*/
870 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
871 /*no argument after the command*/
872 if (NULL == inPtr)
873 {
874 return -EINVAL;
875 }
876
877 /*no space after the command*/
878 else if (SPACE_ASCII_VALUE != *inPtr)
879 {
880 return -EINVAL;
881 }
882
883 /*removing empty spaces*/
884 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
885
886 /*no argument followed by spaces*/
887 if ('\0' == *inPtr)
888 {
889 return -EINVAL;
890 }
891
892 /*check and parse SCANFREQ*/
893 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
894 {
895 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800896 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800897
Rajeev Kumarc933d982013-11-18 20:04:20 -0800898 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800899 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800900 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800901 }
902
Rajeev79dbe4c2013-10-05 11:03:42 +0530903 if ( (NULL == inPtr) || (TRUE == lastArg))
904 {
905 return -EINVAL;
906 }
907 }
908
909 /*check and parse MSCAN*/
910 if ((strncmp(inPtr, "MSCAN", 5) == 0))
911 {
912 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800913 &nMscan, &lastArg);
914
915 if (0 == nMscan)
916 {
917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
918 "invalid MSCAN=%d", nMscan);
919 return -EINVAL;
920 }
921
Rajeev79dbe4c2013-10-05 11:03:42 +0530922 if (TRUE == lastArg)
923 {
924 goto done;
925 }
926 else if (NULL == inPtr)
927 {
928 return -EINVAL;
929 }
930 }
931 else
932 {
933 return -EINVAL;
934 }
935
936 /*check and parse BESTN*/
937 if ((strncmp(inPtr, "BESTN", 5) == 0))
938 {
939 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800940 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800941
Rajeev Kumarc933d982013-11-18 20:04:20 -0800942 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800943 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800944 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800945 }
946
Rajeev79dbe4c2013-10-05 11:03:42 +0530947 if (TRUE == lastArg)
948 {
949 goto done;
950 }
951 else if (NULL == inPtr)
952 {
953 return -EINVAL;
954 }
955 }
956
957 /*check and parse CHANNEL*/
958 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
959 {
960 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800961
Rajeev79dbe4c2013-10-05 11:03:42 +0530962 if (('A' == val) || ('a' == val))
963 {
c_hpothuebf89732014-02-25 13:00:24 +0530964 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530965 }
966 else if (('B' == val) || ('b' == val))
967 {
c_hpothuebf89732014-02-25 13:00:24 +0530968 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530969 }
970 else
971 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800972 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
973 }
974
975 if (TRUE == lastArg)
976 {
977 goto done;
978 }
979 else if (NULL == inPtr)
980 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530981 return -EINVAL;
982 }
983 }
984
985 /*check and parse RTT*/
986 if ((strncmp(inPtr, "RTT", 3) == 0))
987 {
988 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800989 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530990 if (TRUE == lastArg)
991 {
992 goto done;
993 }
994 if (NULL == inPtr)
995 {
996 return -EINVAL;
997 }
998 }
999
1000
1001done:
1002
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001003 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1004 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1005 pHddSetBatchScanReq->bestNetwork = nBestN;
1006 pHddSetBatchScanReq->rfBand = ucRfBand;
1007 pHddSetBatchScanReq->rtt = nRtt;
1008
Rajeev79dbe4c2013-10-05 11:03:42 +05301009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1010 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1011 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1012 pHddSetBatchScanReq->scanFrequency,
1013 pHddSetBatchScanReq->numberOfScansToBatch,
1014 pHddSetBatchScanReq->bestNetwork,
1015 pHddSetBatchScanReq->rfBand,
1016 pHddSetBatchScanReq->rtt);
1017
1018 return 0;
1019}/*End of hdd_parse_set_batchscan_command*/
1020
1021/**---------------------------------------------------------------------------
1022
1023 \brief hdd_set_batch_scan_req_callback () - This function is called after
1024 receiving set batch scan response from FW and it saves set batch scan
1025 response data FW to HDD context and sets the completion event on
1026 which hdd_ioctl is waiting
1027
1028 \param - callbackContext Pointer to HDD adapter
1029 \param - pRsp Pointer to set batch scan response data received from FW
1030
1031 \return - nothing
1032
1033 --------------------------------------------------------------------------*/
1034static void hdd_set_batch_scan_req_callback
1035(
1036 void *callbackContext,
1037 tSirSetBatchScanRsp *pRsp
1038)
1039{
1040 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1041 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1042
1043 /*sanity check*/
1044 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1045 {
1046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1047 "%s: Invalid pAdapter magic", __func__);
1048 VOS_ASSERT(0);
1049 return;
1050 }
1051 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1052
1053 /*save set batch scan response*/
1054 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1055
1056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1057 "Received set batch scan rsp from FW with nScansToBatch=%d",
1058 pHddSetBatchScanRsp->nScansToBatch);
1059
1060 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1061 complete(&pAdapter->hdd_set_batch_scan_req_var);
1062
1063 return;
1064}/*End of hdd_set_batch_scan_req_callback*/
1065
1066
1067/**---------------------------------------------------------------------------
1068
1069 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1070 info in hdd batch scan response queue
1071
1072 \param - pAdapter Pointer to hdd adapter
1073 \param - pAPMetaInfo Pointer to access point meta info
1074 \param - scanId scan ID of batch scan response
1075 \param - isLastAp tells whether AP is last AP in batch scan response or not
1076
1077 \return - nothing
1078
1079 --------------------------------------------------------------------------*/
1080static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1081 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1082{
1083 tHddBatchScanRsp *pHead;
1084 tHddBatchScanRsp *pNode;
1085 tHddBatchScanRsp *pPrev;
1086 tHddBatchScanRsp *pTemp;
1087 tANI_U8 ssidLen;
1088
1089 /*head of hdd batch scan response queue*/
1090 pHead = pAdapter->pBatchScanRsp;
1091
1092 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1093 if (NULL == pNode)
1094 {
1095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1096 "%s: Could not allocate memory", __func__);
1097 VOS_ASSERT(0);
1098 return;
1099 }
1100
1101 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1102 sizeof(pNode->ApInfo.bssid));
1103 ssidLen = strlen(pApMetaInfo->ssid);
1104 if (SIR_MAX_SSID_SIZE < ssidLen)
1105 {
1106 /*invalid scan result*/
1107 vos_mem_free(pNode);
1108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1109 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1110 return;
1111 }
1112 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1113 /*null terminate ssid*/
1114 pNode->ApInfo.ssid[ssidLen] = '\0';
1115 pNode->ApInfo.ch = pApMetaInfo->ch;
1116 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1117 pNode->ApInfo.age = pApMetaInfo->timestamp;
1118 pNode->ApInfo.batchId = scanId;
1119 pNode->ApInfo.isLastAp = isLastAp;
1120
1121 pNode->pNext = NULL;
1122 if (NULL == pHead)
1123 {
1124 pAdapter->pBatchScanRsp = pNode;
1125 }
1126 else
1127 {
1128 pTemp = pHead;
1129 while (NULL != pTemp)
1130 {
1131 pPrev = pTemp;
1132 pTemp = pTemp->pNext;
1133 }
1134 pPrev->pNext = pNode;
1135 }
1136
1137 return;
1138}/*End of hdd_populate_batch_scan_rsp_queue*/
1139
1140/**---------------------------------------------------------------------------
1141
1142 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1143 receiving batch scan response indication from FW. It saves get batch scan
1144 response data in HDD batch scan response queue. This callback sets the
1145 completion event on which hdd_ioctl is waiting only after getting complete
1146 batch scan response data from FW
1147
1148 \param - callbackContext Pointer to HDD adapter
1149 \param - pRsp Pointer to get batch scan response data received from FW
1150
1151 \return - nothing
1152
1153 --------------------------------------------------------------------------*/
1154static void hdd_batch_scan_result_ind_callback
1155(
1156 void *callbackContext,
1157 void *pRsp
1158)
1159{
1160 v_BOOL_t isLastAp;
1161 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001162 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301163 tANI_U32 numberScanList;
1164 tANI_U32 nextScanListOffset;
1165 tANI_U32 nextApMetaInfoOffset;
1166 hdd_adapter_t* pAdapter;
1167 tpSirBatchScanList pScanList;
1168 tpSirBatchScanNetworkInfo pApMetaInfo;
1169 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1170 tSirSetBatchScanReq *pReq;
1171
1172 pAdapter = (hdd_adapter_t *)callbackContext;
1173 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001174 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301175 {
1176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1177 "%s: Invalid pAdapter magic", __func__);
1178 VOS_ASSERT(0);
1179 return;
1180 }
1181
1182 /*initialize locals*/
1183 pReq = &pAdapter->hddSetBatchScanReq;
1184 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1185 isLastAp = FALSE;
1186 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001187 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301188 numberScanList = 0;
1189 nextScanListOffset = 0;
1190 nextApMetaInfoOffset = 0;
1191 pScanList = NULL;
1192 pApMetaInfo = NULL;
1193
1194 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1195 {
1196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1197 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1198 isLastAp = TRUE;
1199 goto done;
1200 }
1201
1202 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1204 "Batch scan rsp: numberScalList %d", numberScanList);
1205
1206 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1207 {
1208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1209 "%s: numberScanList %d", __func__, numberScanList);
1210 isLastAp = TRUE;
1211 goto done;
1212 }
1213
1214 while (numberScanList)
1215 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001216 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301217 nextScanListOffset);
1218 if (NULL == pScanList)
1219 {
1220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1221 "%s: pScanList is %p", __func__, pScanList);
1222 isLastAp = TRUE;
1223 goto done;
1224 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001225 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001227 "Batch scan rsp: numApMetaInfo %d scanId %d",
1228 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301229
1230 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1231 {
1232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1233 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1234 isLastAp = TRUE;
1235 goto done;
1236 }
1237
Rajeev Kumarce651e42013-10-21 18:57:15 -07001238 /*Initialize next AP meta info offset for next scan list*/
1239 nextApMetaInfoOffset = 0;
1240
Rajeev79dbe4c2013-10-05 11:03:42 +05301241 while (numApMetaInfo)
1242 {
1243 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1244 nextApMetaInfoOffset);
1245 if (NULL == pApMetaInfo)
1246 {
1247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1248 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1249 isLastAp = TRUE;
1250 goto done;
1251 }
1252 /*calculate AP age*/
1253 pApMetaInfo->timestamp =
1254 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1255
1256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001257 "%s: bssId "MAC_ADDRESS_STR
1258 " ch %d rssi %d timestamp %d", __func__,
1259 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1260 pApMetaInfo->ch, pApMetaInfo->rssi,
1261 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301262
1263 /*mark last AP in batch scan response*/
1264 if ((TRUE == pBatchScanRsp->isLastResult) &&
1265 (1 == numberScanList) && (1 == numApMetaInfo))
1266 {
1267 isLastAp = TRUE;
1268 }
1269
1270 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1271 /*store batch scan repsonse in hdd queue*/
1272 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1273 pScanList->scanId, isLastAp);
1274 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1275
1276 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1277 numApMetaInfo--;
1278 }
1279
Rajeev Kumarce651e42013-10-21 18:57:15 -07001280 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1281 + (sizeof(tSirBatchScanNetworkInfo)
1282 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301283 numberScanList--;
1284 }
1285
1286done:
1287
1288 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1289 requested from hdd_ioctl*/
1290 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1291 (TRUE == isLastAp))
1292 {
1293 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1294 complete(&pAdapter->hdd_get_batch_scan_req_var);
1295 }
1296
1297 return;
1298}/*End of hdd_batch_scan_result_ind_callback*/
1299
1300/**---------------------------------------------------------------------------
1301
1302 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1303 response as per batch scan FR request format by putting proper markers
1304
1305 \param - pDest pointer to destination buffer
1306 \param - cur_len current length
1307 \param - tot_len total remaining size which can be written to user space
1308 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1309 \param - pAdapter Pointer to HDD adapter
1310
1311 \return - ret no of characters written
1312
1313 --------------------------------------------------------------------------*/
1314static tANI_U32
1315hdd_format_batch_scan_rsp
1316(
1317 tANI_U8 *pDest,
1318 tANI_U32 cur_len,
1319 tANI_U32 tot_len,
1320 tHddBatchScanRsp *pApMetaInfo,
1321 hdd_adapter_t* pAdapter
1322)
1323{
1324 tANI_U32 ret = 0;
1325 tANI_U32 rem_len = 0;
1326 tANI_U8 temp_len = 0;
1327 tANI_U8 temp_total_len = 0;
1328 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1329 tANI_U8 *pTemp = temp;
1330
1331 /*Batch scan reponse needs to be returned to user space in
1332 following format:
1333 "scancount=X\n" where X is the number of scans in current batch
1334 batch
1335 "trunc\n" optional present if current scan truncated
1336 "bssid=XX:XX:XX:XX:XX:XX\n"
1337 "ssid=XXXX\n"
1338 "freq=X\n" frequency in Mhz
1339 "level=XX\n"
1340 "age=X\n" ms
1341 "dist=X\n" cm (-1 if not available)
1342 "errror=X\n" (-1if not available)
1343 "====\n" (end of ap marker)
1344 "####\n" (end of scan marker)
1345 "----\n" (end of results)*/
1346 /*send scan result in above format to user space based on
1347 available length*/
1348 /*The GET response may have more data than the driver can return in its
1349 buffer. In that case the buffer should be filled to the nearest complete
1350 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1351 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1352 The final buffer should end with "----\n"*/
1353
1354 /*sanity*/
1355 if (cur_len > tot_len)
1356 {
1357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1358 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1359 return 0;
1360 }
1361 else
1362 {
1363 rem_len = (tot_len - cur_len);
1364 }
1365
1366 /*end scan marker*/
1367 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1368 {
1369 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1370 pTemp += temp_len;
1371 temp_total_len += temp_len;
1372 }
1373
1374 /*bssid*/
1375 temp_len = snprintf(pTemp, sizeof(temp),
1376 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1377 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1378 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1379 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1380 pTemp += temp_len;
1381 temp_total_len += temp_len;
1382
1383 /*ssid*/
1384 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1385 pApMetaInfo->ApInfo.ssid);
1386 pTemp += temp_len;
1387 temp_total_len += temp_len;
1388
1389 /*freq*/
1390 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001391 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301392 pTemp += temp_len;
1393 temp_total_len += temp_len;
1394
1395 /*level*/
1396 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1397 pApMetaInfo->ApInfo.rssi);
1398 pTemp += temp_len;
1399 temp_total_len += temp_len;
1400
1401 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001402 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301403 pApMetaInfo->ApInfo.age);
1404 pTemp += temp_len;
1405 temp_total_len += temp_len;
1406
1407 /*dist*/
1408 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1409 pTemp += temp_len;
1410 temp_total_len += temp_len;
1411
1412 /*error*/
1413 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1414 pTemp += temp_len;
1415 temp_total_len += temp_len;
1416
1417 /*end AP marker*/
1418 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1419 pTemp += temp_len;
1420 temp_total_len += temp_len;
1421
1422 /*last AP in batch scan response*/
1423 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1424 {
1425 /*end scan marker*/
1426 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1427 pTemp += temp_len;
1428 temp_total_len += temp_len;
1429
1430 /*end batch scan result marker*/
1431 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1432 pTemp += temp_len;
1433 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001434
Rajeev79dbe4c2013-10-05 11:03:42 +05301435 }
1436
1437 if (temp_total_len < rem_len)
1438 {
1439 ret = temp_total_len + 1;
1440 strlcpy(pDest, temp, ret);
1441 pAdapter->isTruncated = FALSE;
1442 }
1443 else
1444 {
1445 pAdapter->isTruncated = TRUE;
1446 if (rem_len >= strlen("%%%%"))
1447 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001448 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301449 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001450 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301451 {
1452 ret = 0;
1453 }
1454 }
1455
1456 return ret;
1457
1458}/*End of hdd_format_batch_scan_rsp*/
1459
1460/**---------------------------------------------------------------------------
1461
1462 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1463 buffer starting with head of hdd batch scan response queue
1464
1465 \param - pAdapter Pointer to HDD adapter
1466 \param - pDest Pointer to user data buffer
1467 \param - cur_len current offset in user buffer
1468 \param - rem_len remaining no of bytes in user buffer
1469
1470 \return - number of bytes written in user buffer
1471
1472 --------------------------------------------------------------------------*/
1473
1474tANI_U32 hdd_populate_user_batch_scan_rsp
1475(
1476 hdd_adapter_t* pAdapter,
1477 tANI_U8 *pDest,
1478 tANI_U32 cur_len,
1479 tANI_U32 rem_len
1480)
1481{
1482 tHddBatchScanRsp *pHead;
1483 tHddBatchScanRsp *pPrev;
1484 tANI_U32 len;
1485
Rajeev79dbe4c2013-10-05 11:03:42 +05301486 pAdapter->isTruncated = FALSE;
1487
1488 /*head of hdd batch scan response queue*/
1489 pHead = pAdapter->pBatchScanRsp;
1490 while (pHead)
1491 {
1492 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1493 pAdapter);
1494 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001495 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301496 cur_len += len;
1497 if(TRUE == pAdapter->isTruncated)
1498 {
1499 /*result is truncated return rest of scan rsp in next req*/
1500 cur_len = rem_len;
1501 break;
1502 }
1503 pPrev = pHead;
1504 pHead = pHead->pNext;
1505 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001506 if (TRUE == pPrev->ApInfo.isLastAp)
1507 {
1508 pAdapter->prev_batch_id = 0;
1509 }
1510 else
1511 {
1512 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1513 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301514 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001515 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301516 }
1517
1518 return cur_len;
1519}/*End of hdd_populate_user_batch_scan_rsp*/
1520
1521/**---------------------------------------------------------------------------
1522
1523 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1524 scan response data from HDD queue to user space
1525 It does following in detail:
1526 a) if HDD has enough data in its queue then it 1st copies data to user
1527 space and then send get batch scan indication message to FW. In this
1528 case it does not wait on any event and batch scan response data will
1529 be populated in HDD response queue in MC thread context after receiving
1530 indication from FW
1531 b) else send get batch scan indication message to FW and wait on an event
1532 which will be set once HDD receives complete batch scan response from
1533 FW and then this function returns batch scan response to user space
1534
1535 \param - pAdapter Pointer to HDD adapter
1536 \param - pPrivData Pointer to priv_data
1537
1538 \return - 0 for success -EFAULT for failure
1539
1540 --------------------------------------------------------------------------*/
1541
1542int hdd_return_batch_scan_rsp_to_user
1543(
1544 hdd_adapter_t* pAdapter,
1545 hdd_priv_data_t *pPrivData,
1546 tANI_U8 *command
1547)
1548{
1549 tANI_U8 *pDest;
1550 tANI_U32 count = 0;
1551 tANI_U32 len = 0;
1552 tANI_U32 cur_len = 0;
1553 tANI_U32 rem_len = 0;
1554 eHalStatus halStatus;
1555 unsigned long rc;
1556 tSirTriggerBatchScanResultInd *pReq;
1557
1558 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1559 pReq->param = 0;/*batch scan client*/
1560 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1561 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1562
1563 cur_len = pPrivData->used_len;
1564 if (pPrivData->total_len > pPrivData->used_len)
1565 {
1566 rem_len = pPrivData->total_len - pPrivData->used_len;
1567 }
1568 else
1569 {
1570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1571 "%s: Invalid user data buffer total_len %d used_len %d",
1572 __func__, pPrivData->total_len, pPrivData->used_len);
1573 return -EFAULT;
1574 }
1575
1576 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1577 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1578 cur_len, rem_len);
1579 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1580
1581 /*enough scan result available in cache to return to user space or
1582 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001583 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301584 {
1585 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1586 halStatus = sme_TriggerBatchScanResultInd(
1587 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1588 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1589 pAdapter);
1590 if ( eHAL_STATUS_SUCCESS == halStatus )
1591 {
1592 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1593 {
1594 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1595 rc = wait_for_completion_timeout(
1596 &pAdapter->hdd_get_batch_scan_req_var,
1597 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1598 if (0 == rc)
1599 {
1600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1601 "%s: Timeout waiting to fetch batch scan rsp from fw",
1602 __func__);
1603 return -EFAULT;
1604 }
1605 }
1606
1607 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001608 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301609 pDest += len;
1610 cur_len += len;
1611
1612 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1613 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1614 cur_len, rem_len);
1615 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1616
1617 count = 0;
1618 len = (len - pPrivData->used_len);
1619 pDest = (command + pPrivData->used_len);
1620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001621 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301622 while(count < len)
1623 {
1624 printk("%c", *(pDest + count));
1625 count++;
1626 }
1627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1628 "%s: copy %d data to user buffer", __func__, len);
1629 if (copy_to_user(pPrivData->buf, pDest, len))
1630 {
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1632 "%s: failed to copy data to user buffer", __func__);
1633 return -EFAULT;
1634 }
1635 }
1636 else
1637 {
1638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1639 "sme_GetBatchScanScan returned failure halStatus %d",
1640 halStatus);
1641 return -EINVAL;
1642 }
1643 }
1644 else
1645 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301646 count = 0;
1647 len = (len - pPrivData->used_len);
1648 pDest = (command + pPrivData->used_len);
1649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001650 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301651 while(count < len)
1652 {
1653 printk("%c", *(pDest + count));
1654 count++;
1655 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1657 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301658 if (copy_to_user(pPrivData->buf, pDest, len))
1659 {
1660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1661 "%s: failed to copy data to user buffer", __func__);
1662 return -EFAULT;
1663 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301664 }
1665
1666 return 0;
1667} /*End of hdd_return_batch_scan_rsp_to_user*/
1668
Rajeev Kumar8b373292014-01-08 20:36:55 -08001669
1670/**---------------------------------------------------------------------------
1671
1672 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1673 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1674 WLS_BATCHING VERSION
1675 WLS_BATCHING SET
1676 WLS_BATCHING GET
1677 WLS_BATCHING STOP
1678
1679 \param - pAdapter Pointer to HDD adapter
1680 \param - pPrivdata Pointer to priv_data
1681 \param - command Pointer to command
1682
1683 \return - 0 for success -EFAULT for failure
1684
1685 --------------------------------------------------------------------------*/
1686
1687int hdd_handle_batch_scan_ioctl
1688(
1689 hdd_adapter_t *pAdapter,
1690 hdd_priv_data_t *pPrivdata,
1691 tANI_U8 *command
1692)
1693{
1694 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001695 hdd_context_t *pHddCtx;
1696
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301697 ENTER();
1698
Yue Mae36e3552014-03-05 17:06:20 -08001699 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1700 ret = wlan_hdd_validate_context(pHddCtx);
1701 if (ret)
1702 {
Yue Mae36e3552014-03-05 17:06:20 -08001703 goto exit;
1704 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001705
1706 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1707 {
1708 char extra[32];
1709 tANI_U8 len = 0;
1710 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1711
1712 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1713 {
1714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1715 "%s: Batch scan feature is not supported by FW", __func__);
1716 ret = -EINVAL;
1717 goto exit;
1718 }
1719
1720 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1721 version);
1722 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1723 {
1724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1725 "%s: failed to copy data to user buffer", __func__);
1726 ret = -EFAULT;
1727 goto exit;
1728 }
1729 ret = HDD_BATCH_SCAN_VERSION;
1730 }
1731 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1732 {
1733 int status;
1734 tANI_U8 *value = (command + 16);
1735 eHalStatus halStatus;
1736 unsigned long rc;
1737 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1738 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1739
1740 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1741 {
1742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1743 "%s: Batch scan feature is not supported by FW", __func__);
1744 ret = -EINVAL;
1745 goto exit;
1746 }
1747
1748 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1749 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1750 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1751 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1752 {
1753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301754 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001755 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301756 hdd_device_modetoString(pAdapter->device_mode),
1757 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001758 ret = -EINVAL;
1759 goto exit;
1760 }
1761
1762 status = hdd_parse_set_batchscan_command(value, pReq);
1763 if (status)
1764 {
1765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1766 "Invalid WLS_BATCHING SET command");
1767 ret = -EINVAL;
1768 goto exit;
1769 }
1770
1771
1772 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1773 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1774 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1775 pAdapter);
1776
1777 if ( eHAL_STATUS_SUCCESS == halStatus )
1778 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301779 char extra[32];
1780 tANI_U8 len = 0;
1781 tANI_U8 mScan = 0;
1782
Rajeev Kumar8b373292014-01-08 20:36:55 -08001783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1784 "sme_SetBatchScanReq returned success halStatus %d",
1785 halStatus);
1786 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1787 {
1788 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1789 rc = wait_for_completion_timeout(
1790 &pAdapter->hdd_set_batch_scan_req_var,
1791 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1792 if (0 == rc)
1793 {
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1795 "%s: Timeout waiting for set batch scan to complete",
1796 __func__);
1797 ret = -EINVAL;
1798 goto exit;
1799 }
1800 }
1801 if ( !pRsp->nScansToBatch )
1802 {
1803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1804 "%s: Received set batch scan failure response from FW",
1805 __func__);
1806 ret = -EINVAL;
1807 goto exit;
1808 }
1809 /*As per the Batch Scan Framework API we should return the MIN of
1810 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301811 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001812
1813 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1814
1815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1816 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301817 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1818 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1819 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1820 {
1821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1822 "%s: failed to copy MSCAN value to user buffer", __func__);
1823 ret = -EFAULT;
1824 goto exit;
1825 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001826 }
1827 else
1828 {
1829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1830 "sme_SetBatchScanReq returned failure halStatus %d",
1831 halStatus);
1832 ret = -EINVAL;
1833 goto exit;
1834 }
1835 }
1836 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1837 {
1838 eHalStatus halStatus;
1839 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1840 pInd->param = 0;
1841
1842 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1843 {
1844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1845 "%s: Batch scan feature is not supported by FW", __func__);
1846 ret = -EINVAL;
1847 goto exit;
1848 }
1849
1850 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1851 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001853 "Batch scan is not yet enabled batch scan state %d",
1854 pAdapter->batchScanState);
1855 ret = -EINVAL;
1856 goto exit;
1857 }
1858
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001859 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1860 hdd_deinit_batch_scan(pAdapter);
1861 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1862
Rajeev Kumar8b373292014-01-08 20:36:55 -08001863 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1864
1865 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1866 pAdapter->sessionId);
1867 if ( eHAL_STATUS_SUCCESS == halStatus )
1868 {
1869 ret = 0;
1870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1871 "sme_StopBatchScanInd returned success halStatus %d",
1872 halStatus);
1873 }
1874 else
1875 {
1876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1877 "sme_StopBatchScanInd returned failure halStatus %d",
1878 halStatus);
1879 ret = -EINVAL;
1880 goto exit;
1881 }
1882 }
1883 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1884 {
1885 tANI_U32 remain_len;
1886
1887 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1888 {
1889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1890 "%s: Batch scan feature is not supported by FW", __func__);
1891 ret = -EINVAL;
1892 goto exit;
1893 }
1894
1895 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1896 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001898 "Batch scan is not yet enabled could not return results"
1899 "Batch Scan state %d",
1900 pAdapter->batchScanState);
1901 ret = -EINVAL;
1902 goto exit;
1903 }
1904
1905 pPrivdata->used_len = 16;
1906 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1907 if (remain_len < pPrivdata->total_len)
1908 {
1909 /*Clear previous batch scan response data if any*/
1910 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1911 }
1912 else
1913 {
1914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1915 "Invalid total length from user space can't fetch batch"
1916 " scan response total_len %d used_len %d remain len %d",
1917 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1918 ret = -EINVAL;
1919 goto exit;
1920 }
1921 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1922 }
1923
1924exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301925 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001926 return ret;
1927}
1928
1929
Rajeev79dbe4c2013-10-05 11:03:42 +05301930#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1931
c_hpothu92367912014-05-01 15:18:17 +05301932static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1933{
c_hpothu39eb1e32014-06-26 16:31:50 +05301934 bcnMissRateContext_t *pCBCtx;
1935
1936 if (NULL == data)
1937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1939 return;
1940 }
c_hpothu92367912014-05-01 15:18:17 +05301941
1942 /* there is a race condition that exists between this callback
1943 function and the caller since the caller could time out either
1944 before or while this code is executing. we use a spinlock to
1945 serialize these actions */
1946 spin_lock(&hdd_context_lock);
1947
c_hpothu39eb1e32014-06-26 16:31:50 +05301948 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301949 gbcnMissRate = -1;
1950
c_hpothu39eb1e32014-06-26 16:31:50 +05301951 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301952 {
1953 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301954 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301955 spin_unlock(&hdd_context_lock);
1956 return ;
1957 }
1958
1959 if (VOS_STATUS_SUCCESS == status)
1960 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301961 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301962 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301963 else
1964 {
1965 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1966 }
1967
c_hpothu92367912014-05-01 15:18:17 +05301968 complete(&(pCBCtx->completion));
1969 spin_unlock(&hdd_context_lock);
1970
1971 return;
1972}
1973
Abhishek Singh08aa7762014-12-16 13:59:03 +05301974void hdd_FWStatisCB( VOS_STATUS status,
1975 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301976{
1977 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301978 hdd_adapter_t *pAdapter;
1979
1980 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1981
Abhishek Singh08aa7762014-12-16 13:59:03 +05301982 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301983 {
1984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1985 return;
1986 }
1987 /* there is a race condition that exists between this callback
1988 function and the caller since the caller could time out either
1989 before or while this code is executing. we use a spinlock to
1990 serialize these actions */
1991 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301992 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301993 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR,
1996 FL("invalid context magic: %08x"), fwStatsCtx->magic);
1997 spin_unlock(&hdd_context_lock);
1998 return;
1999 }
2000 pAdapter = fwStatsCtx->pAdapter;
2001 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2002 {
2003 hddLog(VOS_TRACE_LEVEL_ERROR,
2004 FL("pAdapter returned is NULL or invalid"));
2005 spin_unlock(&hdd_context_lock);
2006 return;
2007 }
2008 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302009 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302010 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302011 switch( fwStatsResult->type )
2012 {
2013 case FW_UBSP_STATS:
2014 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302015 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302016 hddLog(VOS_TRACE_LEVEL_INFO,
2017 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302018 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2019 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302020 }
2021 break;
2022 default:
2023 {
2024 hddLog(VOS_TRACE_LEVEL_ERROR,
2025 FL(" No handling for stats type %d"),fwStatsResult->type);
2026 }
2027 }
2028 }
2029 complete(&(fwStatsCtx->completion));
2030 spin_unlock(&hdd_context_lock);
2031 return;
2032}
2033
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302034static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2035{
2036 int ret = 0;
2037
2038 if (!pCfg || !command || !extra || !len)
2039 {
2040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2041 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2042 ret = -EINVAL;
2043 return ret;
2044 }
2045
2046 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2047 {
2048 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2049 (int)pCfg->nActiveMaxChnTime);
2050 return ret;
2051 }
2052 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2053 {
2054 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2055 (int)pCfg->nActiveMinChnTime);
2056 return ret;
2057 }
2058 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2059 {
2060 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2061 (int)pCfg->nPassiveMaxChnTime);
2062 return ret;
2063 }
2064 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2065 {
2066 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2067 (int)pCfg->nPassiveMinChnTime);
2068 return ret;
2069 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302070 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2071 {
2072 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2073 (int)pCfg->nActiveMaxChnTime);
2074 return ret;
2075 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302076 else
2077 {
2078 ret = -EINVAL;
2079 }
2080
2081 return ret;
2082}
2083
2084static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2085{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302086 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302087 hdd_config_t *pCfg;
2088 tANI_U8 *value = command;
2089 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302090 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302091
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302092 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2093 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302094 {
2095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2096 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2097 ret = -EINVAL;
2098 return ret;
2099 }
2100
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302101 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2102 sme_GetConfigParam(hHal, &smeConfig);
2103
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302104 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2105 {
2106 value = value + 24;
2107 temp = kstrtou32(value, 10, &val);
2108 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2109 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2110 {
2111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2112 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2113 ret = -EFAULT;
2114 return ret;
2115 }
2116 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302117 smeConfig.csrConfig.nActiveMaxChnTime = val;
2118 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302119 }
2120 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2121 {
2122 value = value + 24;
2123 temp = kstrtou32(value, 10, &val);
2124 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2125 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2126 {
2127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2128 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2129 ret = -EFAULT;
2130 return ret;
2131 }
2132 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302133 smeConfig.csrConfig.nActiveMinChnTime = val;
2134 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302135 }
2136 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2137 {
2138 value = value + 25;
2139 temp = kstrtou32(value, 10, &val);
2140 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2141 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2142 {
2143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2144 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2145 ret = -EFAULT;
2146 return ret;
2147 }
2148 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302149 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2150 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302151 }
2152 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2153 {
2154 value = value + 25;
2155 temp = kstrtou32(value, 10, &val);
2156 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2157 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2158 {
2159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2160 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2161 ret = -EFAULT;
2162 return ret;
2163 }
2164 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302165 smeConfig.csrConfig.nPassiveMinChnTime = val;
2166 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302167 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302168 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2169 {
2170 value = value + 13;
2171 temp = kstrtou32(value, 10, &val);
2172 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2173 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2174 {
2175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2176 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2177 ret = -EFAULT;
2178 return ret;
2179 }
2180 pCfg->nActiveMaxChnTime = val;
2181 smeConfig.csrConfig.nActiveMaxChnTime = val;
2182 sme_UpdateConfig(hHal, &smeConfig);
2183 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302184 else
2185 {
2186 ret = -EINVAL;
2187 }
2188
2189 return ret;
2190}
2191
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002192static int hdd_driver_command(hdd_adapter_t *pAdapter,
2193 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002194{
Jeff Johnson295189b2012-06-20 16:38:30 -07002195 hdd_priv_data_t priv_data;
2196 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302197 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2198 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002199 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302200 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302201
2202 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002203 /*
2204 * Note that valid pointers are provided by caller
2205 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002206
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002207 /* copy to local struct to avoid numerous changes to legacy code */
2208 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002209
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002210 if (priv_data.total_len <= 0 ||
2211 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002212 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002213 hddLog(VOS_TRACE_LEVEL_WARN,
2214 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2215 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002216 ret = -EINVAL;
2217 goto exit;
2218 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302219 status = wlan_hdd_validate_context(pHddCtx);
2220 if (0 != status)
2221 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302222 ret = -EINVAL;
2223 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302224 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002225 /* Allocate +1 for '\0' */
2226 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002227 if (!command)
2228 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002229 hddLog(VOS_TRACE_LEVEL_ERROR,
2230 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 ret = -ENOMEM;
2232 goto exit;
2233 }
2234
2235 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2236 {
2237 ret = -EFAULT;
2238 goto exit;
2239 }
2240
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002241 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002242 command[priv_data.total_len] = '\0';
2243
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002244 /* at one time the following block of code was conditional. braces
2245 * have been retained to avoid re-indenting the legacy code
2246 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002247 {
2248 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2249
2250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002251 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002252
2253 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2254 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302255 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2256 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2257 pAdapter->sessionId, (unsigned)
2258 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2259 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2260 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2261 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002262 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2263 sizeof(tSirMacAddr)))
2264 {
2265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002266 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002267 ret = -EFAULT;
2268 }
2269 }
Amar Singhal0974e402013-02-12 14:27:46 -08002270 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002271 {
Amar Singhal0974e402013-02-12 14:27:46 -08002272 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002273
Jeff Johnson295189b2012-06-20 16:38:30 -07002274 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002275
2276 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002277 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002279 "%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 -07002280 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002281 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302282 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302283 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002284 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002285 }
Kiet Lamf040f472013-11-20 21:15:23 +05302286 else if(strncmp(command, "SETWMMPS", 8) == 0)
2287 {
2288 tANI_U8 *ptr = command;
2289 ret = hdd_wmmps_helper(pAdapter, ptr);
2290 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302291
2292 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2293 {
2294 tANI_U8 *ptr = command;
2295 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2296 }
2297
Jeff Johnson32d95a32012-09-10 13:15:23 -07002298 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2299 {
2300 char *country_code;
2301
2302 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002303
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002304 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002305 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002306#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302307 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002308#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002309 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2310 (void *)(tSmeChangeCountryCallback)
2311 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302312 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002313 if (eHAL_STATUS_SUCCESS == ret)
2314 {
2315 ret = wait_for_completion_interruptible_timeout(
2316 &pAdapter->change_country_code,
2317 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2318 if (0 >= ret)
2319 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302321 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002322 }
2323 }
2324 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002325 {
2326 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002327 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002328 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002329 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002330
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002331 }
2332 /*
2333 command should be a string having format
2334 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2335 */
Amar Singhal0974e402013-02-12 14:27:46 -08002336 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002337 {
Amar Singhal0974e402013-02-12 14:27:46 -08002338 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002339
2340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002341 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002342
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002343 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002344 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002345 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2346 {
2347 int suspend = 0;
2348 tANI_U8 *ptr = (tANI_U8*)command + 15;
2349
2350 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302351 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2352 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2353 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002354 hdd_set_wlan_suspend_mode(suspend);
2355 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002356#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2357 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2358 {
2359 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002360 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002361 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2362 eHalStatus status = eHAL_STATUS_SUCCESS;
2363
2364 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2365 value = value + 15;
2366
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002367 /* Convert the value from ascii to integer */
2368 ret = kstrtos8(value, 10, &rssi);
2369 if (ret < 0)
2370 {
2371 /* If the input value is greater than max value of datatype, then also
2372 kstrtou8 fails */
2373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2374 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002375 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002376 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2377 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2378 ret = -EINVAL;
2379 goto exit;
2380 }
2381
Srinivas Girigowdade697412013-02-14 16:31:48 -08002382 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002383
Srinivas Girigowdade697412013-02-14 16:31:48 -08002384 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2385 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2386 {
2387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2388 "Neighbor lookup threshold value %d is out of range"
2389 " (Min: %d Max: %d)", lookUpThreshold,
2390 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2391 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2392 ret = -EINVAL;
2393 goto exit;
2394 }
2395
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302396 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2397 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2398 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2400 "%s: Received Command to Set Roam trigger"
2401 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2402
2403 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2404 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2405 if (eHAL_STATUS_SUCCESS != status)
2406 {
2407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2408 "%s: Failed to set roam trigger, try again", __func__);
2409 ret = -EPERM;
2410 goto exit;
2411 }
2412
2413 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302414 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002415 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2416 }
2417 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2418 {
2419 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2420 int rssi = (-1) * lookUpThreshold;
2421 char extra[32];
2422 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302423 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2424 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2425 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002426 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002427 if (copy_to_user(priv_data.buf, &extra, len + 1))
2428 {
2429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2430 "%s: failed to copy data to user buffer", __func__);
2431 ret = -EFAULT;
2432 goto exit;
2433 }
2434 }
2435 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2436 {
2437 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002438 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002439 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002440
Srinivas Girigowdade697412013-02-14 16:31:48 -08002441 /* input refresh period is in terms of seconds */
2442 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2443 value = value + 18;
2444 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002445 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002446 if (ret < 0)
2447 {
2448 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002449 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002451 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002452 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002453 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2454 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002455 ret = -EINVAL;
2456 goto exit;
2457 }
2458
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002459 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2460 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002461 {
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002463 "Roam scan period value %d is out of range"
2464 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002465 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2466 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002467 ret = -EINVAL;
2468 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302469 }
2470 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2471 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2472 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002473 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002474
2475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2476 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002477 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002479 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2480 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002481 }
2482 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2483 {
2484 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2485 char extra[32];
2486 tANI_U8 len = 0;
2487
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302488 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2489 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2490 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002491 len = scnprintf(extra, sizeof(extra), "%s %d",
2492 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002493 /* Returned value is in units of seconds */
2494 if (copy_to_user(priv_data.buf, &extra, len + 1))
2495 {
2496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2497 "%s: failed to copy data to user buffer", __func__);
2498 ret = -EFAULT;
2499 goto exit;
2500 }
2501 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002502 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2503 {
2504 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002505 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002506 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002507
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002508 /* input refresh period is in terms of seconds */
2509 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2510 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002511
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002512 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002513 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002514 if (ret < 0)
2515 {
2516 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002517 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002519 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002520 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002521 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2522 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2523 ret = -EINVAL;
2524 goto exit;
2525 }
2526
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002527 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2528 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2529 {
2530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2531 "Neighbor scan results refresh period value %d is out of range"
2532 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2533 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2534 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2535 ret = -EINVAL;
2536 goto exit;
2537 }
2538 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2539
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2541 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002542 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002543
2544 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2545 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2546 }
2547 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2548 {
2549 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2550 char extra[32];
2551 tANI_U8 len = 0;
2552
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002553 len = scnprintf(extra, sizeof(extra), "%s %d",
2554 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 /* Returned value is in units of seconds */
2556 if (copy_to_user(priv_data.buf, &extra, len + 1))
2557 {
2558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2559 "%s: failed to copy data to user buffer", __func__);
2560 ret = -EFAULT;
2561 goto exit;
2562 }
2563 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002564#ifdef FEATURE_WLAN_LFR
2565 /* SETROAMMODE */
2566 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2567 {
2568 tANI_U8 *value = command;
2569 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2570
2571 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2572 value = value + SIZE_OF_SETROAMMODE + 1;
2573
2574 /* Convert the value from ascii to integer */
2575 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2576 if (ret < 0)
2577 {
2578 /* If the input value is greater than max value of datatype, then also
2579 kstrtou8 fails */
2580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2581 "%s: kstrtou8 failed range [%d - %d]", __func__,
2582 CFG_LFR_FEATURE_ENABLED_MIN,
2583 CFG_LFR_FEATURE_ENABLED_MAX);
2584 ret = -EINVAL;
2585 goto exit;
2586 }
2587 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2588 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2589 {
2590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2591 "Roam Mode value %d is out of range"
2592 " (Min: %d Max: %d)", roamMode,
2593 CFG_LFR_FEATURE_ENABLED_MIN,
2594 CFG_LFR_FEATURE_ENABLED_MAX);
2595 ret = -EINVAL;
2596 goto exit;
2597 }
2598
2599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2600 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2601 /*
2602 * Note that
2603 * SETROAMMODE 0 is to enable LFR while
2604 * SETROAMMODE 1 is to disable LFR, but
2605 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2606 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2607 */
2608 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2609 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2610 else
2611 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2612
2613 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2614 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2615 }
2616 /* GETROAMMODE */
2617 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2618 {
2619 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2620 char extra[32];
2621 tANI_U8 len = 0;
2622
2623 /*
2624 * roamMode value shall be inverted because the sementics is different.
2625 */
2626 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2627 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2628 else
2629 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2630
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002631 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002632 if (copy_to_user(priv_data.buf, &extra, len + 1))
2633 {
2634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2635 "%s: failed to copy data to user buffer", __func__);
2636 ret = -EFAULT;
2637 goto exit;
2638 }
2639 }
2640#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002641#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002642#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002643 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2644 {
2645 tANI_U8 *value = command;
2646 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2647
2648 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2649 value = value + 13;
2650 /* Convert the value from ascii to integer */
2651 ret = kstrtou8(value, 10, &roamRssiDiff);
2652 if (ret < 0)
2653 {
2654 /* If the input value is greater than max value of datatype, then also
2655 kstrtou8 fails */
2656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2657 "%s: kstrtou8 failed range [%d - %d]", __func__,
2658 CFG_ROAM_RSSI_DIFF_MIN,
2659 CFG_ROAM_RSSI_DIFF_MAX);
2660 ret = -EINVAL;
2661 goto exit;
2662 }
2663
2664 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2665 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2666 {
2667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2668 "Roam rssi diff value %d is out of range"
2669 " (Min: %d Max: %d)", roamRssiDiff,
2670 CFG_ROAM_RSSI_DIFF_MIN,
2671 CFG_ROAM_RSSI_DIFF_MAX);
2672 ret = -EINVAL;
2673 goto exit;
2674 }
2675
2676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2677 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2678
2679 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2680 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2681 }
2682 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2683 {
2684 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2685 char extra[32];
2686 tANI_U8 len = 0;
2687
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2689 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2690 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002691 len = scnprintf(extra, sizeof(extra), "%s %d",
2692 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002693 if (copy_to_user(priv_data.buf, &extra, len + 1))
2694 {
2695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2696 "%s: failed to copy data to user buffer", __func__);
2697 ret = -EFAULT;
2698 goto exit;
2699 }
2700 }
2701#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002702#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002703 else if (strncmp(command, "GETBAND", 7) == 0)
2704 {
2705 int band = -1;
2706 char extra[32];
2707 tANI_U8 len = 0;
2708 hdd_getBand_helper(pHddCtx, &band);
2709
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302710 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2711 TRACE_CODE_HDD_GETBAND_IOCTL,
2712 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002713 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002714 if (copy_to_user(priv_data.buf, &extra, len + 1))
2715 {
2716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2717 "%s: failed to copy data to user buffer", __func__);
2718 ret = -EFAULT;
2719 goto exit;
2720 }
2721 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002722 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2723 {
2724 tANI_U8 *value = command;
2725 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2726 tANI_U8 numChannels = 0;
2727 eHalStatus status = eHAL_STATUS_SUCCESS;
2728
2729 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2730 if (eHAL_STATUS_SUCCESS != status)
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: Failed to parse channel list information", __func__);
2734 ret = -EINVAL;
2735 goto exit;
2736 }
2737
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302738 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2739 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2740 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002741 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2742 {
2743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2744 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2745 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2746 ret = -EINVAL;
2747 goto exit;
2748 }
2749 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2750 numChannels);
2751 if (eHAL_STATUS_SUCCESS != status)
2752 {
2753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 "%s: Failed to update channel list information", __func__);
2755 ret = -EINVAL;
2756 goto exit;
2757 }
2758 }
2759 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2760 {
2761 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2762 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002763 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002764 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002765 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002766
2767 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2768 ChannelList, &numChannels ))
2769 {
2770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2771 "%s: failed to get roam scan channel list", __func__);
2772 ret = -EFAULT;
2773 goto exit;
2774 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302775 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2776 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2777 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002778 /* output channel list is of the format
2779 [Number of roam scan channels][Channel1][Channel2]... */
2780 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002781 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002782 for (j = 0; (j < numChannels); j++)
2783 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002784 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2785 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002786 }
2787
2788 if (copy_to_user(priv_data.buf, &extra, len + 1))
2789 {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s: failed to copy data to user buffer", __func__);
2792 ret = -EFAULT;
2793 goto exit;
2794 }
2795 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002796 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2797 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002798 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002799 char extra[32];
2800 tANI_U8 len = 0;
2801
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002802 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002803 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002804 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002805 hdd_is_okc_mode_enabled(pHddCtx) &&
2806 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2807 {
2808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002809 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002810 " hence this operation is not permitted!", __func__);
2811 ret = -EPERM;
2812 goto exit;
2813 }
2814
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002815 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002816 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002817 if (copy_to_user(priv_data.buf, &extra, len + 1))
2818 {
2819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2820 "%s: failed to copy data to user buffer", __func__);
2821 ret = -EFAULT;
2822 goto exit;
2823 }
2824 }
2825 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2826 {
2827 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2828 char extra[32];
2829 tANI_U8 len = 0;
2830
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002831 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002832 then this operation is not permitted (return FAILURE) */
2833 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002834 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002835 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2836 {
2837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002838 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002839 " hence this operation is not permitted!", __func__);
2840 ret = -EPERM;
2841 goto exit;
2842 }
2843
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002844 len = scnprintf(extra, sizeof(extra), "%s %d",
2845 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002846 if (copy_to_user(priv_data.buf, &extra, len + 1))
2847 {
2848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2849 "%s: failed to copy data to user buffer", __func__);
2850 ret = -EFAULT;
2851 goto exit;
2852 }
2853 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002854 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002855 {
2856 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2857 char extra[32];
2858 tANI_U8 len = 0;
2859
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002860 len = scnprintf(extra, sizeof(extra), "%s %d",
2861 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002862 if (copy_to_user(priv_data.buf, &extra, len + 1))
2863 {
2864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2865 "%s: failed to copy data to user buffer", __func__);
2866 ret = -EFAULT;
2867 goto exit;
2868 }
2869 }
2870 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2871 {
2872 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2873 char extra[32];
2874 tANI_U8 len = 0;
2875
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002876 len = scnprintf(extra, sizeof(extra), "%s %d",
2877 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002878 if (copy_to_user(priv_data.buf, &extra, len + 1))
2879 {
2880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2881 "%s: failed to copy data to user buffer", __func__);
2882 ret = -EFAULT;
2883 goto exit;
2884 }
2885 }
2886 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2887 {
2888 tANI_U8 *value = command;
2889 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2890
2891 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2892 value = value + 26;
2893 /* Convert the value from ascii to integer */
2894 ret = kstrtou8(value, 10, &minTime);
2895 if (ret < 0)
2896 {
2897 /* If the input value is greater than max value of datatype, then also
2898 kstrtou8 fails */
2899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2900 "%s: kstrtou8 failed range [%d - %d]", __func__,
2901 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2902 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2903 ret = -EINVAL;
2904 goto exit;
2905 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002906 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2907 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2908 {
2909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2910 "scan min channel time value %d is out of range"
2911 " (Min: %d Max: %d)", minTime,
2912 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2913 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2914 ret = -EINVAL;
2915 goto exit;
2916 }
2917
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302918 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2919 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2920 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2922 "%s: Received Command to change channel min time = %d", __func__, minTime);
2923
2924 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2925 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2926 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002927 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2928 {
2929 tANI_U8 *value = command;
2930 tANI_U8 channel = 0;
2931 tANI_U8 dwellTime = 0;
2932 tANI_U8 bufLen = 0;
2933 tANI_U8 *buf = NULL;
2934 tSirMacAddr targetApBssid;
2935 eHalStatus status = eHAL_STATUS_SUCCESS;
2936 struct ieee80211_channel chan;
2937 tANI_U8 finalLen = 0;
2938 tANI_U8 *finalBuf = NULL;
2939 tANI_U8 temp = 0;
2940 u64 cookie;
2941 hdd_station_ctx_t *pHddStaCtx = NULL;
2942 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2943
2944 /* if not associated, no need to send action frame */
2945 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2946 {
2947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2948 ret = -EINVAL;
2949 goto exit;
2950 }
2951
2952 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2953 &dwellTime, &buf, &bufLen);
2954 if (eHAL_STATUS_SUCCESS != status)
2955 {
2956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2957 "%s: Failed to parse send action frame data", __func__);
2958 ret = -EINVAL;
2959 goto exit;
2960 }
2961
2962 /* if the target bssid is different from currently associated AP,
2963 then no need to send action frame */
2964 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2965 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2966 {
2967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2968 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002969 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002970 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002971 goto exit;
2972 }
2973
2974 /* if the channel number is different from operating channel then
2975 no need to send action frame */
2976 if (channel != pHddStaCtx->conn_info.operationChannel)
2977 {
2978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2979 "%s: channel(%d) is different from operating channel(%d)",
2980 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2981 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002982 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002983 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002984 goto exit;
2985 }
2986 chan.center_freq = sme_ChnToFreq(channel);
2987
2988 finalLen = bufLen + 24;
2989 finalBuf = vos_mem_malloc(finalLen);
2990 if (NULL == finalBuf)
2991 {
2992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2993 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002994 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002995 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002996 goto exit;
2997 }
2998 vos_mem_zero(finalBuf, finalLen);
2999
3000 /* Fill subtype */
3001 temp = SIR_MAC_MGMT_ACTION << 4;
3002 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3003
3004 /* Fill type */
3005 temp = SIR_MAC_MGMT_FRAME;
3006 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3007
3008 /* Fill destination address (bssid of the AP) */
3009 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3010
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003011 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003012 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3013
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003014 /* Fill BSSID (AP mac address) */
3015 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003016
3017 /* Fill received buffer from 24th address */
3018 vos_mem_copy(finalBuf + 24, buf, bufLen);
3019
Jeff Johnson11c33152013-04-16 17:52:40 -07003020 /* done with the parsed buffer */
3021 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003022 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003023
DARAM SUDHA39eede62014-02-12 11:16:40 +05303024 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3026 &(pAdapter->wdev),
3027#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003028 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003029#endif
3030 &chan, 0,
3031#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3032 NL80211_CHAN_HT20, 1,
3033#endif
3034 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003035 1, &cookie );
3036 vos_mem_free(finalBuf);
3037 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003038 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3039 {
3040 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3041 char extra[32];
3042 tANI_U8 len = 0;
3043
3044 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003045 len = scnprintf(extra, sizeof(extra), "%s %d",
3046 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303047 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3048 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3049 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003050 if (copy_to_user(priv_data.buf, &extra, len + 1))
3051 {
3052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3053 "%s: failed to copy data to user buffer", __func__);
3054 ret = -EFAULT;
3055 goto exit;
3056 }
3057 }
3058 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3059 {
3060 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003061 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003062
3063 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3064 value = value + 19;
3065 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003066 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003067 if (ret < 0)
3068 {
3069 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003070 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003072 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003073 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3074 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3075 ret = -EINVAL;
3076 goto exit;
3077 }
3078
3079 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3080 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3081 {
3082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3083 "lfr mode value %d is out of range"
3084 " (Min: %d Max: %d)", maxTime,
3085 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3086 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3087 ret = -EINVAL;
3088 goto exit;
3089 }
3090
3091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3092 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3093
3094 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3095 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3096 }
3097 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3098 {
3099 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3100 char extra[32];
3101 tANI_U8 len = 0;
3102
3103 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003104 len = scnprintf(extra, sizeof(extra), "%s %d",
3105 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003106 if (copy_to_user(priv_data.buf, &extra, len + 1))
3107 {
3108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3109 "%s: failed to copy data to user buffer", __func__);
3110 ret = -EFAULT;
3111 goto exit;
3112 }
3113 }
3114 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3115 {
3116 tANI_U8 *value = command;
3117 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3118
3119 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3120 value = value + 16;
3121 /* Convert the value from ascii to integer */
3122 ret = kstrtou16(value, 10, &val);
3123 if (ret < 0)
3124 {
3125 /* If the input value is greater than max value of datatype, then also
3126 kstrtou16 fails */
3127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3128 "%s: kstrtou16 failed range [%d - %d]", __func__,
3129 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3130 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3131 ret = -EINVAL;
3132 goto exit;
3133 }
3134
3135 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3136 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3137 {
3138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3139 "scan home time value %d is out of range"
3140 " (Min: %d Max: %d)", val,
3141 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3142 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3143 ret = -EINVAL;
3144 goto exit;
3145 }
3146
3147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3148 "%s: Received Command to change scan home time = %d", __func__, val);
3149
3150 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3151 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3152 }
3153 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3154 {
3155 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3156 char extra[32];
3157 tANI_U8 len = 0;
3158
3159 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003160 len = scnprintf(extra, sizeof(extra), "%s %d",
3161 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003162 if (copy_to_user(priv_data.buf, &extra, len + 1))
3163 {
3164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3165 "%s: failed to copy data to user buffer", __func__);
3166 ret = -EFAULT;
3167 goto exit;
3168 }
3169 }
3170 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3171 {
3172 tANI_U8 *value = command;
3173 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3174
3175 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3176 value = value + 17;
3177 /* Convert the value from ascii to integer */
3178 ret = kstrtou8(value, 10, &val);
3179 if (ret < 0)
3180 {
3181 /* If the input value is greater than max value of datatype, then also
3182 kstrtou8 fails */
3183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3184 "%s: kstrtou8 failed range [%d - %d]", __func__,
3185 CFG_ROAM_INTRA_BAND_MIN,
3186 CFG_ROAM_INTRA_BAND_MAX);
3187 ret = -EINVAL;
3188 goto exit;
3189 }
3190
3191 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3192 (val > CFG_ROAM_INTRA_BAND_MAX))
3193 {
3194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3195 "intra band mode value %d is out of range"
3196 " (Min: %d Max: %d)", val,
3197 CFG_ROAM_INTRA_BAND_MIN,
3198 CFG_ROAM_INTRA_BAND_MAX);
3199 ret = -EINVAL;
3200 goto exit;
3201 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3203 "%s: Received Command to change intra band = %d", __func__, val);
3204
3205 pHddCtx->cfg_ini->nRoamIntraBand = val;
3206 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3207 }
3208 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3209 {
3210 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3211 char extra[32];
3212 tANI_U8 len = 0;
3213
3214 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003215 len = scnprintf(extra, sizeof(extra), "%s %d",
3216 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003217 if (copy_to_user(priv_data.buf, &extra, len + 1))
3218 {
3219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3220 "%s: failed to copy data to user buffer", __func__);
3221 ret = -EFAULT;
3222 goto exit;
3223 }
3224 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003225 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3226 {
3227 tANI_U8 *value = command;
3228 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3229
3230 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3231 value = value + 15;
3232 /* Convert the value from ascii to integer */
3233 ret = kstrtou8(value, 10, &nProbes);
3234 if (ret < 0)
3235 {
3236 /* If the input value is greater than max value of datatype, then also
3237 kstrtou8 fails */
3238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3239 "%s: kstrtou8 failed range [%d - %d]", __func__,
3240 CFG_ROAM_SCAN_N_PROBES_MIN,
3241 CFG_ROAM_SCAN_N_PROBES_MAX);
3242 ret = -EINVAL;
3243 goto exit;
3244 }
3245
3246 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3247 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3248 {
3249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3250 "NProbes value %d is out of range"
3251 " (Min: %d Max: %d)", nProbes,
3252 CFG_ROAM_SCAN_N_PROBES_MIN,
3253 CFG_ROAM_SCAN_N_PROBES_MAX);
3254 ret = -EINVAL;
3255 goto exit;
3256 }
3257
3258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3259 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3260
3261 pHddCtx->cfg_ini->nProbes = nProbes;
3262 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3263 }
3264 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3265 {
3266 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3267 char extra[32];
3268 tANI_U8 len = 0;
3269
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003270 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003271 if (copy_to_user(priv_data.buf, &extra, len + 1))
3272 {
3273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3274 "%s: failed to copy data to user buffer", __func__);
3275 ret = -EFAULT;
3276 goto exit;
3277 }
3278 }
3279 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3280 {
3281 tANI_U8 *value = command;
3282 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3283
3284 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3285 /* input value is in units of msec */
3286 value = value + 20;
3287 /* Convert the value from ascii to integer */
3288 ret = kstrtou16(value, 10, &homeAwayTime);
3289 if (ret < 0)
3290 {
3291 /* If the input value is greater than max value of datatype, then also
3292 kstrtou8 fails */
3293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3294 "%s: kstrtou8 failed range [%d - %d]", __func__,
3295 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3296 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3297 ret = -EINVAL;
3298 goto exit;
3299 }
3300
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003301 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3302 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3303 {
3304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3305 "homeAwayTime value %d is out of range"
3306 " (Min: %d Max: %d)", homeAwayTime,
3307 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3308 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3309 ret = -EINVAL;
3310 goto exit;
3311 }
3312
3313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3314 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003315 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3316 {
3317 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3318 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3319 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003320 }
3321 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3322 {
3323 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3324 char extra[32];
3325 tANI_U8 len = 0;
3326
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003327 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003328 if (copy_to_user(priv_data.buf, &extra, len + 1))
3329 {
3330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3331 "%s: failed to copy data to user buffer", __func__);
3332 ret = -EFAULT;
3333 goto exit;
3334 }
3335 }
3336 else if (strncmp(command, "REASSOC", 7) == 0)
3337 {
3338 tANI_U8 *value = command;
3339 tANI_U8 channel = 0;
3340 tSirMacAddr targetApBssid;
3341 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003342#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3343 tCsrHandoffRequest handoffInfo;
3344#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003345 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003346 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3347
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003348 /* if not associated, no need to proceed with reassoc */
3349 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3350 {
3351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3352 ret = -EINVAL;
3353 goto exit;
3354 }
3355
3356 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3357 if (eHAL_STATUS_SUCCESS != status)
3358 {
3359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3360 "%s: Failed to parse reassoc command data", __func__);
3361 ret = -EINVAL;
3362 goto exit;
3363 }
3364
3365 /* if the target bssid is same as currently associated AP,
3366 then no need to proceed with reassoc */
3367 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3368 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3369 {
3370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3371 ret = -EINVAL;
3372 goto exit;
3373 }
3374
3375 /* Check channel number is a valid channel number */
3376 if(VOS_STATUS_SUCCESS !=
3377 wlan_hdd_validate_operation_channel(pAdapter, channel))
3378 {
3379 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003380 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003381 return -EINVAL;
3382 }
3383
3384 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003385#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3386 handoffInfo.channel = channel;
3387 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3388 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3389#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003390 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003391 else if (strncmp(command, "SETWESMODE", 10) == 0)
3392 {
3393 tANI_U8 *value = command;
3394 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3395
3396 /* Move pointer to ahead of SETWESMODE<delimiter> */
3397 value = value + 11;
3398 /* Convert the value from ascii to integer */
3399 ret = kstrtou8(value, 10, &wesMode);
3400 if (ret < 0)
3401 {
3402 /* If the input value is greater than max value of datatype, then also
3403 kstrtou8 fails */
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3405 "%s: kstrtou8 failed range [%d - %d]", __func__,
3406 CFG_ENABLE_WES_MODE_NAME_MIN,
3407 CFG_ENABLE_WES_MODE_NAME_MAX);
3408 ret = -EINVAL;
3409 goto exit;
3410 }
3411
3412 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3413 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3414 {
3415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3416 "WES Mode value %d is out of range"
3417 " (Min: %d Max: %d)", wesMode,
3418 CFG_ENABLE_WES_MODE_NAME_MIN,
3419 CFG_ENABLE_WES_MODE_NAME_MAX);
3420 ret = -EINVAL;
3421 goto exit;
3422 }
3423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3424 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3425
3426 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3427 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3428 }
3429 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3430 {
3431 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3432 char extra[32];
3433 tANI_U8 len = 0;
3434
Arif Hussain826d9412013-11-12 16:44:54 -08003435 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003436 if (copy_to_user(priv_data.buf, &extra, len + 1))
3437 {
3438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3439 "%s: failed to copy data to user buffer", __func__);
3440 ret = -EFAULT;
3441 goto exit;
3442 }
3443 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003444#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003445#ifdef FEATURE_WLAN_LFR
3446 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3447 {
3448 tANI_U8 *value = command;
3449 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3450
3451 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3452 value = value + 12;
3453 /* Convert the value from ascii to integer */
3454 ret = kstrtou8(value, 10, &lfrMode);
3455 if (ret < 0)
3456 {
3457 /* If the input value is greater than max value of datatype, then also
3458 kstrtou8 fails */
3459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3460 "%s: kstrtou8 failed range [%d - %d]", __func__,
3461 CFG_LFR_FEATURE_ENABLED_MIN,
3462 CFG_LFR_FEATURE_ENABLED_MAX);
3463 ret = -EINVAL;
3464 goto exit;
3465 }
3466
3467 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3468 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3469 {
3470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3471 "lfr mode value %d is out of range"
3472 " (Min: %d Max: %d)", lfrMode,
3473 CFG_LFR_FEATURE_ENABLED_MIN,
3474 CFG_LFR_FEATURE_ENABLED_MAX);
3475 ret = -EINVAL;
3476 goto exit;
3477 }
3478
3479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3480 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3481
3482 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3483 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3484 }
3485#endif
3486#ifdef WLAN_FEATURE_VOWIFI_11R
3487 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3488 {
3489 tANI_U8 *value = command;
3490 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3491
3492 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3493 value = value + 18;
3494 /* Convert the value from ascii to integer */
3495 ret = kstrtou8(value, 10, &ft);
3496 if (ret < 0)
3497 {
3498 /* If the input value is greater than max value of datatype, then also
3499 kstrtou8 fails */
3500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3501 "%s: kstrtou8 failed range [%d - %d]", __func__,
3502 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3503 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3504 ret = -EINVAL;
3505 goto exit;
3506 }
3507
3508 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3509 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3510 {
3511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3512 "ft mode value %d is out of range"
3513 " (Min: %d Max: %d)", ft,
3514 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3515 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3516 ret = -EINVAL;
3517 goto exit;
3518 }
3519
3520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3521 "%s: Received Command to change ft mode = %d", __func__, ft);
3522
3523 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3524 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3525 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303526
3527 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3528 {
3529 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303530 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303531 tSirMacAddr targetApBssid;
3532 tANI_U8 trigger = 0;
3533 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303534 tHalHandle hHal;
3535 v_U32_t roamId = 0;
3536 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303537 hdd_station_ctx_t *pHddStaCtx = NULL;
3538 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303539 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303540
3541 /* if not associated, no need to proceed with reassoc */
3542 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3543 {
3544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3545 ret = -EINVAL;
3546 goto exit;
3547 }
3548
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303549 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303550 if (eHAL_STATUS_SUCCESS != status)
3551 {
3552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3553 "%s: Failed to parse reassoc command data", __func__);
3554 ret = -EINVAL;
3555 goto exit;
3556 }
3557
3558 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303559 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303560 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3561 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3562 {
3563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3564 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3565 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303566 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3567 &modProfileFields);
3568 sme_RoamReassoc(hHal, pAdapter->sessionId,
3569 NULL, modProfileFields, &roamId, 1);
3570 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303571 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303572
3573 /* Check channel number is a valid channel number */
3574 if(VOS_STATUS_SUCCESS !=
3575 wlan_hdd_validate_operation_channel(pAdapter, channel))
3576 {
3577 hddLog(VOS_TRACE_LEVEL_ERROR,
3578 "%s: Invalid Channel [%d]", __func__, channel);
3579 return -EINVAL;
3580 }
3581
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303582 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303583
3584 /* Proceed with scan/roam */
3585 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3586 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303587 (tSmeFastRoamTrigger)(trigger),
3588 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303589 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003590#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003591#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003592 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3593 {
3594 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003595 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003596
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003597 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003598 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003599 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003600 hdd_is_okc_mode_enabled(pHddCtx) &&
3601 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3602 {
3603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003604 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003605 " hence this operation is not permitted!", __func__);
3606 ret = -EPERM;
3607 goto exit;
3608 }
3609
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003610 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3611 value = value + 11;
3612 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003613 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003614 if (ret < 0)
3615 {
3616 /* If the input value is greater than max value of datatype, then also
3617 kstrtou8 fails */
3618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3619 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003620 CFG_ESE_FEATURE_ENABLED_MIN,
3621 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003622 ret = -EINVAL;
3623 goto exit;
3624 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003625 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3626 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003627 {
3628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003629 "Ese mode value %d is out of range"
3630 " (Min: %d Max: %d)", eseMode,
3631 CFG_ESE_FEATURE_ENABLED_MIN,
3632 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003633 ret = -EINVAL;
3634 goto exit;
3635 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003637 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003638
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003639 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3640 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003641 }
3642#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003643 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3644 {
3645 tANI_U8 *value = command;
3646 tANI_BOOLEAN roamScanControl = 0;
3647
3648 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3649 value = value + 19;
3650 /* Convert the value from ascii to integer */
3651 ret = kstrtou8(value, 10, &roamScanControl);
3652 if (ret < 0)
3653 {
3654 /* If the input value is greater than max value of datatype, then also
3655 kstrtou8 fails */
3656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3657 "%s: kstrtou8 failed ", __func__);
3658 ret = -EINVAL;
3659 goto exit;
3660 }
3661
3662 if (0 != roamScanControl)
3663 {
3664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3665 "roam scan control invalid value = %d",
3666 roamScanControl);
3667 ret = -EINVAL;
3668 goto exit;
3669 }
3670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3671 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3672
3673 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3674 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003675#ifdef FEATURE_WLAN_OKC
3676 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3677 {
3678 tANI_U8 *value = command;
3679 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3680
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003681 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003682 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003683 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003684 hdd_is_okc_mode_enabled(pHddCtx) &&
3685 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3686 {
3687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003688 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003689 " hence this operation is not permitted!", __func__);
3690 ret = -EPERM;
3691 goto exit;
3692 }
3693
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003694 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3695 value = value + 11;
3696 /* Convert the value from ascii to integer */
3697 ret = kstrtou8(value, 10, &okcMode);
3698 if (ret < 0)
3699 {
3700 /* If the input value is greater than max value of datatype, then also
3701 kstrtou8 fails */
3702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3703 "%s: kstrtou8 failed range [%d - %d]", __func__,
3704 CFG_OKC_FEATURE_ENABLED_MIN,
3705 CFG_OKC_FEATURE_ENABLED_MAX);
3706 ret = -EINVAL;
3707 goto exit;
3708 }
3709
3710 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3711 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3712 {
3713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3714 "Okc mode value %d is out of range"
3715 " (Min: %d Max: %d)", okcMode,
3716 CFG_OKC_FEATURE_ENABLED_MIN,
3717 CFG_OKC_FEATURE_ENABLED_MAX);
3718 ret = -EINVAL;
3719 goto exit;
3720 }
3721
3722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3723 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3724
3725 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3726 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003727#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003728 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3729 {
3730 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3731 char extra[32];
3732 tANI_U8 len = 0;
3733
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003734 len = scnprintf(extra, sizeof(extra), "%s %d",
3735 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003736 if (copy_to_user(priv_data.buf, &extra, len + 1))
3737 {
3738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3739 "%s: failed to copy data to user buffer", __func__);
3740 ret = -EFAULT;
3741 goto exit;
3742 }
3743 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303744#ifdef WLAN_FEATURE_PACKET_FILTERING
3745 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3746 {
3747 tANI_U8 filterType = 0;
3748 tANI_U8 *value = command;
3749
3750 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3751 value = value + 22;
3752
3753 /* Convert the value from ascii to integer */
3754 ret = kstrtou8(value, 10, &filterType);
3755 if (ret < 0)
3756 {
3757 /* If the input value is greater than max value of datatype,
3758 * then also kstrtou8 fails
3759 */
3760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3761 "%s: kstrtou8 failed range ", __func__);
3762 ret = -EINVAL;
3763 goto exit;
3764 }
3765
3766 if (filterType != 0 && filterType != 1)
3767 {
3768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3769 "%s: Accepted Values are 0 and 1 ", __func__);
3770 ret = -EINVAL;
3771 goto exit;
3772 }
3773 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3774 pAdapter->sessionId);
3775 }
3776#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303777 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3778 {
Kiet Lamad161252014-07-22 11:23:32 -07003779 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303780 int ret;
3781
Kiet Lamad161252014-07-22 11:23:32 -07003782 dhcpPhase = command + 11;
3783 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303784 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003786 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303787
3788 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003789
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303790 ret = wlan_hdd_scan_abort(pAdapter);
3791 if (ret < 0)
3792 {
3793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3794 FL("failed to abort existing scan %d"), ret);
3795 }
3796
Kiet Lamad161252014-07-22 11:23:32 -07003797 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3798 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303799 }
Kiet Lamad161252014-07-22 11:23:32 -07003800 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303801 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003803 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303804
3805 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003806
3807 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3808 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303809 }
3810 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003811 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3812 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3814 FL("making default scan to ACTIVE"));
3815 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003816 }
3817 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3818 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3820 FL("making default scan to PASSIVE"));
3821 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003822 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303823 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3824 {
3825 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3826 char extra[32];
3827 tANI_U8 len = 0;
3828
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303829 memset(extra, 0, sizeof(extra));
3830 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3831 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303832 {
3833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3834 "%s: failed to copy data to user buffer", __func__);
3835 ret = -EFAULT;
3836 goto exit;
3837 }
3838 ret = len;
3839 }
3840 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3841 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303842 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303843 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003844 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3845 {
3846 tANI_U8 filterType = 0;
3847 tANI_U8 *value;
3848 value = command + 9;
3849
3850 /* Convert the value from ascii to integer */
3851 ret = kstrtou8(value, 10, &filterType);
3852 if (ret < 0)
3853 {
3854 /* If the input value is greater than max value of datatype,
3855 * then also kstrtou8 fails
3856 */
3857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3858 "%s: kstrtou8 failed range ", __func__);
3859 ret = -EINVAL;
3860 goto exit;
3861 }
3862 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3863 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3864 {
3865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3866 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3867 " 2-Sink ", __func__);
3868 ret = -EINVAL;
3869 goto exit;
3870 }
3871 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3872 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303873 pScanInfo = &pHddCtx->scan_info;
3874 if (filterType && pScanInfo != NULL &&
3875 pHddCtx->scan_info.mScanPending)
3876 {
3877 /*Miracast Session started. Abort Scan */
3878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3879 "%s, Aborting Scan For Miracast",__func__);
3880 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3881 eCSR_SCAN_ABORT_DEFAULT);
3882 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003883 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303884 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003885 }
Leo Chang614d2072013-08-22 14:59:44 -07003886 else if (strncmp(command, "SETMCRATE", 9) == 0)
3887 {
Leo Chang614d2072013-08-22 14:59:44 -07003888 tANI_U8 *value = command;
3889 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003890 tSirRateUpdateInd *rateUpdate;
3891 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003892
3893 /* Only valid for SAP mode */
3894 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3895 {
3896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3897 "%s: SAP mode is not running", __func__);
3898 ret = -EFAULT;
3899 goto exit;
3900 }
3901
3902 /* Move pointer to ahead of SETMCRATE<delimiter> */
3903 /* input value is in units of hundred kbps */
3904 value = value + 10;
3905 /* Convert the value from ascii to integer, decimal base */
3906 ret = kstrtouint(value, 10, &targetRate);
3907
Leo Chang1f98cbd2013-10-17 15:03:52 -07003908 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3909 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003910 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003911 hddLog(VOS_TRACE_LEVEL_ERROR,
3912 "%s: SETMCRATE indication alloc fail", __func__);
3913 ret = -EFAULT;
3914 goto exit;
3915 }
3916 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3917
3918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3919 "MC Target rate %d", targetRate);
3920 /* Ignore unicast */
3921 rateUpdate->ucastDataRate = -1;
3922 rateUpdate->mcastDataRate24GHz = targetRate;
3923 rateUpdate->mcastDataRate5GHz = targetRate;
3924 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3925 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3926 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3927 if (eHAL_STATUS_SUCCESS != status)
3928 {
3929 hddLog(VOS_TRACE_LEVEL_ERROR,
3930 "%s: SET_MC_RATE failed", __func__);
3931 vos_mem_free(rateUpdate);
3932 ret = -EFAULT;
3933 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003934 }
3935 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303936#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003937 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303938 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003939 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303940 }
3941#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003942#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003943 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3944 {
3945 tANI_U8 *value = command;
3946 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3947 tANI_U8 numChannels = 0;
3948 eHalStatus status = eHAL_STATUS_SUCCESS;
3949
3950 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3951 if (eHAL_STATUS_SUCCESS != status)
3952 {
3953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3954 "%s: Failed to parse channel list information", __func__);
3955 ret = -EINVAL;
3956 goto exit;
3957 }
3958
3959 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3960 {
3961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3962 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3963 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3964 ret = -EINVAL;
3965 goto exit;
3966 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003967 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003968 ChannelList,
3969 numChannels);
3970 if (eHAL_STATUS_SUCCESS != status)
3971 {
3972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3973 "%s: Failed to update channel list information", __func__);
3974 ret = -EINVAL;
3975 goto exit;
3976 }
3977 }
3978 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3979 {
3980 tANI_U8 *value = command;
3981 char extra[128] = {0};
3982 int len = 0;
3983 tANI_U8 tid = 0;
3984 hdd_station_ctx_t *pHddStaCtx = NULL;
3985 tAniTrafStrmMetrics tsmMetrics;
3986 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3987
3988 /* if not associated, return error */
3989 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3990 {
3991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3992 ret = -EINVAL;
3993 goto exit;
3994 }
3995
3996 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3997 value = value + 12;
3998 /* Convert the value from ascii to integer */
3999 ret = kstrtou8(value, 10, &tid);
4000 if (ret < 0)
4001 {
4002 /* If the input value is greater than max value of datatype, then also
4003 kstrtou8 fails */
4004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4005 "%s: kstrtou8 failed range [%d - %d]", __func__,
4006 TID_MIN_VALUE,
4007 TID_MAX_VALUE);
4008 ret = -EINVAL;
4009 goto exit;
4010 }
4011
4012 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4013 {
4014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4015 "tid value %d is out of range"
4016 " (Min: %d Max: %d)", tid,
4017 TID_MIN_VALUE,
4018 TID_MAX_VALUE);
4019 ret = -EINVAL;
4020 goto exit;
4021 }
4022
4023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4024 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4025
4026 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4027 {
4028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4029 "%s: failed to get tsm stats", __func__);
4030 ret = -EFAULT;
4031 goto exit;
4032 }
4033
4034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4035 "UplinkPktQueueDly(%d)\n"
4036 "UplinkPktQueueDlyHist[0](%d)\n"
4037 "UplinkPktQueueDlyHist[1](%d)\n"
4038 "UplinkPktQueueDlyHist[2](%d)\n"
4039 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304040 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004041 "UplinkPktLoss(%d)\n"
4042 "UplinkPktCount(%d)\n"
4043 "RoamingCount(%d)\n"
4044 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4045 tsmMetrics.UplinkPktQueueDlyHist[0],
4046 tsmMetrics.UplinkPktQueueDlyHist[1],
4047 tsmMetrics.UplinkPktQueueDlyHist[2],
4048 tsmMetrics.UplinkPktQueueDlyHist[3],
4049 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4050 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4051
4052 /* Output TSM stats is of the format
4053 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4054 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004055 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004056 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4057 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4058 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4059 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4060 tsmMetrics.RoamingDly);
4061
4062 if (copy_to_user(priv_data.buf, &extra, len + 1))
4063 {
4064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4065 "%s: failed to copy data to user buffer", __func__);
4066 ret = -EFAULT;
4067 goto exit;
4068 }
4069 }
4070 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4071 {
4072 tANI_U8 *value = command;
4073 tANI_U8 *cckmIe = NULL;
4074 tANI_U8 cckmIeLen = 0;
4075 eHalStatus status = eHAL_STATUS_SUCCESS;
4076
4077 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4078 if (eHAL_STATUS_SUCCESS != status)
4079 {
4080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4081 "%s: Failed to parse cckm ie data", __func__);
4082 ret = -EINVAL;
4083 goto exit;
4084 }
4085
4086 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4087 {
4088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4089 "%s: CCKM Ie input length is more than max[%d]", __func__,
4090 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004091 vos_mem_free(cckmIe);
4092 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004093 ret = -EINVAL;
4094 goto exit;
4095 }
4096 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004097 vos_mem_free(cckmIe);
4098 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004099 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004100 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4101 {
4102 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004103 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004104 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004105
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004106 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004107 if (eHAL_STATUS_SUCCESS != status)
4108 {
4109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004110 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004111 ret = -EINVAL;
4112 goto exit;
4113 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004114 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4115 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4116 hdd_indicateEseBcnReportNoResults (pAdapter,
4117 eseBcnReq.bcnReq[0].measurementToken,
4118 0x02, //BIT(1) set for measurement done
4119 0); // no BSS
4120 goto exit;
4121 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004122
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004123 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4124 if (eHAL_STATUS_SUCCESS != status)
4125 {
4126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4127 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4128 ret = -EINVAL;
4129 goto exit;
4130 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004131 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004132#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304133 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4134 {
4135 eHalStatus status;
4136 char buf[32], len;
4137 long waitRet;
4138 bcnMissRateContext_t getBcnMissRateCtx;
4139
4140 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4141
4142 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4143 {
4144 hddLog(VOS_TRACE_LEVEL_WARN,
4145 FL("GETBCNMISSRATE: STA is not in connected state"));
4146 ret = -1;
4147 goto exit;
4148 }
4149
4150 init_completion(&(getBcnMissRateCtx.completion));
4151 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4152
4153 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4154 pAdapter->sessionId,
4155 (void *)getBcnMissRateCB,
4156 (void *)(&getBcnMissRateCtx));
4157 if( eHAL_STATUS_SUCCESS != status)
4158 {
4159 hddLog(VOS_TRACE_LEVEL_INFO,
4160 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4161 ret = -EINVAL;
4162 goto exit;
4163 }
4164
4165 waitRet = wait_for_completion_interruptible_timeout
4166 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4167 if(waitRet <= 0)
4168 {
4169 hddLog(VOS_TRACE_LEVEL_ERROR,
4170 FL("failed to wait on bcnMissRateComp %d"), ret);
4171
4172 //Make magic number to zero so that callback is not called.
4173 spin_lock(&hdd_context_lock);
4174 getBcnMissRateCtx.magic = 0x0;
4175 spin_unlock(&hdd_context_lock);
4176 ret = -EINVAL;
4177 goto exit;
4178 }
4179
4180 hddLog(VOS_TRACE_LEVEL_INFO,
4181 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4182
4183 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4184 if (copy_to_user(priv_data.buf, &buf, len + 1))
4185 {
4186 hddLog(VOS_TRACE_LEVEL_ERROR,
4187 "%s: failed to copy data to user buffer", __func__);
4188 ret = -EFAULT;
4189 goto exit;
4190 }
4191 ret = len;
4192 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304193#ifdef FEATURE_WLAN_TDLS
4194 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4195 tANI_U8 *value = command;
4196 int set_value;
4197 /* Move pointer to ahead of TDLSOFFCH*/
4198 value += 26;
4199 sscanf(value, "%d", &set_value);
4200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4201 "%s: Tdls offchannel offset:%d",
4202 __func__, set_value);
4203 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4204 if (ret < 0)
4205 {
4206 ret = -EINVAL;
4207 goto exit;
4208 }
4209
4210 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4211 tANI_U8 *value = command;
4212 int set_value;
4213 /* Move pointer to ahead of tdlsoffchnmode*/
4214 value += 18;
4215 sscanf(value, "%d", &set_value);
4216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4217 "%s: Tdls offchannel mode:%d",
4218 __func__, set_value);
4219 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4220 if (ret < 0)
4221 {
4222 ret = -EINVAL;
4223 goto exit;
4224 }
4225 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4226 tANI_U8 *value = command;
4227 int set_value;
4228 /* Move pointer to ahead of TDLSOFFCH*/
4229 value += 14;
4230 sscanf(value, "%d", &set_value);
4231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4232 "%s: Tdls offchannel num: %d",
4233 __func__, set_value);
4234 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4235 if (ret < 0)
4236 {
4237 ret = -EINVAL;
4238 goto exit;
4239 }
4240 }
4241#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304242 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4243 {
4244 eHalStatus status;
4245 char *buf = NULL;
4246 char len;
4247 long waitRet;
4248 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304249 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304250 tANI_U8 *ptr = command;
4251 int stats = *(ptr + 11) - '0';
4252
4253 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4254 if (!IS_FEATURE_FW_STATS_ENABLE)
4255 {
4256 hddLog(VOS_TRACE_LEVEL_INFO,
4257 FL("Get Firmware stats feature not supported"));
4258 ret = -EINVAL;
4259 goto exit;
4260 }
4261
4262 if (FW_STATS_MAX <= stats || 0 >= stats)
4263 {
4264 hddLog(VOS_TRACE_LEVEL_INFO,
4265 FL(" stats %d not supported"),stats);
4266 ret = -EINVAL;
4267 goto exit;
4268 }
4269
4270 init_completion(&(fwStatsCtx.completion));
4271 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4272 fwStatsCtx.pAdapter = pAdapter;
4273 fwStatsRsp->type = 0;
4274 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304275 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304276 if (eHAL_STATUS_SUCCESS != status)
4277 {
4278 hddLog(VOS_TRACE_LEVEL_ERROR,
4279 FL(" fail to post WDA cmd status = %d"), status);
4280 ret = -EINVAL;
4281 goto exit;
4282 }
4283 waitRet = wait_for_completion_timeout
4284 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4285 if (waitRet <= 0)
4286 {
4287 hddLog(VOS_TRACE_LEVEL_ERROR,
4288 FL("failed to wait on GwtFwstats"));
4289 //Make magic number to zero so that callback is not executed.
4290 spin_lock(&hdd_context_lock);
4291 fwStatsCtx.magic = 0x0;
4292 spin_unlock(&hdd_context_lock);
4293 ret = -EINVAL;
4294 goto exit;
4295 }
4296 if (fwStatsRsp->type)
4297 {
4298 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4299 if (!buf)
4300 {
4301 hddLog(VOS_TRACE_LEVEL_ERROR,
4302 FL(" failed to allocate memory"));
4303 ret = -ENOMEM;
4304 goto exit;
4305 }
4306 switch( fwStatsRsp->type )
4307 {
4308 case FW_UBSP_STATS:
4309 {
4310 len = snprintf(buf, FW_STATE_RSP_LEN,
4311 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304312 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4313 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304314 }
4315 break;
4316 default:
4317 {
4318 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4319 ret = -EFAULT;
4320 kfree(buf);
4321 goto exit;
4322 }
4323 }
4324 if (copy_to_user(priv_data.buf, buf, len + 1))
4325 {
4326 hddLog(VOS_TRACE_LEVEL_ERROR,
4327 FL(" failed to copy data to user buffer"));
4328 ret = -EFAULT;
4329 kfree(buf);
4330 goto exit;
4331 }
4332 ret = len;
4333 kfree(buf);
4334 }
4335 else
4336 {
4337 hddLog(VOS_TRACE_LEVEL_ERROR,
4338 FL("failed to fetch the stats"));
4339 ret = -EFAULT;
4340 goto exit;
4341 }
4342
4343 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004344 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304345 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4346 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4347 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304348 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4349 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004351 }
4352exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304353 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004354 if (command)
4355 {
4356 kfree(command);
4357 }
4358 return ret;
4359}
4360
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004361#ifdef CONFIG_COMPAT
4362static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4363{
4364 struct {
4365 compat_uptr_t buf;
4366 int used_len;
4367 int total_len;
4368 } compat_priv_data;
4369 hdd_priv_data_t priv_data;
4370 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004371
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004372 /*
4373 * Note that pAdapter and ifr have already been verified by caller,
4374 * and HDD context has also been validated
4375 */
4376 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4377 sizeof(compat_priv_data))) {
4378 ret = -EFAULT;
4379 goto exit;
4380 }
4381 priv_data.buf = compat_ptr(compat_priv_data.buf);
4382 priv_data.used_len = compat_priv_data.used_len;
4383 priv_data.total_len = compat_priv_data.total_len;
4384 ret = hdd_driver_command(pAdapter, &priv_data);
4385 exit:
4386 return ret;
4387}
4388#else /* CONFIG_COMPAT */
4389static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4390{
4391 /* will never be invoked */
4392 return 0;
4393}
4394#endif /* CONFIG_COMPAT */
4395
4396static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4397{
4398 hdd_priv_data_t priv_data;
4399 int ret = 0;
4400
4401 /*
4402 * Note that pAdapter and ifr have already been verified by caller,
4403 * and HDD context has also been validated
4404 */
4405 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4406 ret = -EFAULT;
4407 } else {
4408 ret = hdd_driver_command(pAdapter, &priv_data);
4409 }
4410 return ret;
4411}
4412
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304413int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004414{
4415 hdd_adapter_t *pAdapter;
4416 hdd_context_t *pHddCtx;
4417 int ret;
4418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304419 ENTER();
4420
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004421 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4422 if (NULL == pAdapter) {
4423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4424 "%s: HDD adapter context is Null", __func__);
4425 ret = -ENODEV;
4426 goto exit;
4427 }
4428 if (dev != pAdapter->dev) {
4429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4430 "%s: HDD adapter/dev inconsistency", __func__);
4431 ret = -ENODEV;
4432 goto exit;
4433 }
4434
4435 if ((!ifr) || (!ifr->ifr_data)) {
4436 ret = -EINVAL;
4437 goto exit;
4438 }
4439
4440 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4441 ret = wlan_hdd_validate_context(pHddCtx);
4442 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004443 ret = -EBUSY;
4444 goto exit;
4445 }
4446
4447 switch (cmd) {
4448 case (SIOCDEVPRIVATE + 1):
4449 if (is_compat_task())
4450 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4451 else
4452 ret = hdd_driver_ioctl(pAdapter, ifr);
4453 break;
4454 default:
4455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4456 __func__, cmd);
4457 ret = -EINVAL;
4458 break;
4459 }
4460 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304461 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004462 return ret;
4463}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004464
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304465int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4466{
4467 int ret;
4468
4469 vos_ssr_protect(__func__);
4470 ret = __hdd_ioctl(dev, ifr, cmd);
4471 vos_ssr_unprotect(__func__);
4472
4473 return ret;
4474}
4475
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004476#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004477/**---------------------------------------------------------------------------
4478
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004479 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004480
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004481 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004482 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4483 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4484 <space>Scan Mode N<space>Meas Duration N
4485 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4486 then take N.
4487 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4488 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4489 This function does not take care of removing duplicate channels from the list
4490
4491 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004492 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004493
4494 \return - 0 for success non-zero for failure
4495
4496 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004497static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4498 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004499{
4500 tANI_U8 *inPtr = pValue;
4501 int tempInt = 0;
4502 int j = 0, i = 0, v = 0;
4503 char buf[32];
4504
4505 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4506 /*no argument after the command*/
4507 if (NULL == inPtr)
4508 {
4509 return -EINVAL;
4510 }
4511 /*no space after the command*/
4512 else if (SPACE_ASCII_VALUE != *inPtr)
4513 {
4514 return -EINVAL;
4515 }
4516
4517 /*removing empty spaces*/
4518 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4519
4520 /*no argument followed by spaces*/
4521 if ('\0' == *inPtr) return -EINVAL;
4522
4523 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004524 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004525 if (1 != v) return -EINVAL;
4526
4527 v = kstrtos32(buf, 10, &tempInt);
4528 if ( v < 0) return -EINVAL;
4529
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004530 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004531
4532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004533 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004534
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004535 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004536 {
4537 for (i = 0; i < 4; i++)
4538 {
4539 /*inPtr pointing to the beginning of first space after number of ie fields*/
4540 inPtr = strpbrk( inPtr, " " );
4541 /*no ie data after the number of ie fields argument*/
4542 if (NULL == inPtr) return -EINVAL;
4543
4544 /*removing empty space*/
4545 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4546
4547 /*no ie data after the number of ie fields argument and spaces*/
4548 if ( '\0' == *inPtr ) return -EINVAL;
4549
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004550 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004551 if (1 != v) return -EINVAL;
4552
4553 v = kstrtos32(buf, 10, &tempInt);
4554 if (v < 0) return -EINVAL;
4555
4556 switch (i)
4557 {
4558 case 0: /* Measurement token */
4559 if (tempInt <= 0)
4560 {
4561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4562 "Invalid Measurement Token(%d)", tempInt);
4563 return -EINVAL;
4564 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004565 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004566 break;
4567
4568 case 1: /* Channel number */
4569 if ((tempInt <= 0) ||
4570 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4571 {
4572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4573 "Invalid Channel Number(%d)", tempInt);
4574 return -EINVAL;
4575 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004576 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004577 break;
4578
4579 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004580 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004581 {
4582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4583 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4584 return -EINVAL;
4585 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004586 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004587 break;
4588
4589 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004590 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4591 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004592 {
4593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4594 "Invalid Measurement Duration(%d)", tempInt);
4595 return -EINVAL;
4596 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004598 break;
4599 }
4600 }
4601 }
4602
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004603 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004604 {
4605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304606 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004607 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004608 pEseBcnReq->bcnReq[j].measurementToken,
4609 pEseBcnReq->bcnReq[j].channel,
4610 pEseBcnReq->bcnReq[j].scanMode,
4611 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004612 }
4613
4614 return VOS_STATUS_SUCCESS;
4615}
4616
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004617static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4618{
4619 struct statsContext *pStatsContext = NULL;
4620 hdd_adapter_t *pAdapter = NULL;
4621
4622 if (NULL == pContext)
4623 {
4624 hddLog(VOS_TRACE_LEVEL_ERROR,
4625 "%s: Bad param, pContext [%p]",
4626 __func__, pContext);
4627 return;
4628 }
4629
Jeff Johnson72a40512013-12-19 10:14:15 -08004630 /* there is a race condition that exists between this callback
4631 function and the caller since the caller could time out either
4632 before or while this code is executing. we use a spinlock to
4633 serialize these actions */
4634 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004635
4636 pStatsContext = pContext;
4637 pAdapter = pStatsContext->pAdapter;
4638 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4639 {
4640 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004641 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004642 hddLog(VOS_TRACE_LEVEL_WARN,
4643 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4644 __func__, pAdapter, pStatsContext->magic);
4645 return;
4646 }
4647
Jeff Johnson72a40512013-12-19 10:14:15 -08004648 /* context is valid so caller is still waiting */
4649
4650 /* paranoia: invalidate the magic */
4651 pStatsContext->magic = 0;
4652
4653 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004654 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4655 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4656 tsmMetrics.UplinkPktQueueDlyHist,
4657 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4658 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4659 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4660 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4661 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4662 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4663 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4664
Jeff Johnson72a40512013-12-19 10:14:15 -08004665 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004666 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004667
4668 /* serialization is complete */
4669 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004670}
4671
4672
4673
4674static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4675 tAniTrafStrmMetrics* pTsmMetrics)
4676{
4677 hdd_station_ctx_t *pHddStaCtx = NULL;
4678 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004679 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004680 long lrc;
4681 struct statsContext context;
4682 hdd_context_t *pHddCtx = NULL;
4683
4684 if (NULL == pAdapter)
4685 {
4686 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4687 return VOS_STATUS_E_FAULT;
4688 }
4689
4690 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4691 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4692
4693 /* we are connected prepare our callback context */
4694 init_completion(&context.completion);
4695 context.pAdapter = pAdapter;
4696 context.magic = STATS_CONTEXT_MAGIC;
4697
4698 /* query tsm stats */
4699 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4700 pHddStaCtx->conn_info.staId[ 0 ],
4701 pHddStaCtx->conn_info.bssId,
4702 &context, pHddCtx->pvosContext, tid);
4703
4704 if (eHAL_STATUS_SUCCESS != hstatus)
4705 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4707 __func__);
4708 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004709 }
4710 else
4711 {
4712 /* request was sent -- wait for the response */
4713 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4714 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004715 if (lrc <= 0)
4716 {
4717 hddLog(VOS_TRACE_LEVEL_ERROR,
4718 "%s: SME %s while retrieving statistics",
4719 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004720 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004721 }
4722 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004723
Jeff Johnson72a40512013-12-19 10:14:15 -08004724 /* either we never sent a request, we sent a request and received a
4725 response or we sent a request and timed out. if we never sent a
4726 request or if we sent a request and got a response, we want to
4727 clear the magic out of paranoia. if we timed out there is a
4728 race condition such that the callback function could be
4729 executing at the same time we are. of primary concern is if the
4730 callback function had already verified the "magic" but had not
4731 yet set the completion variable when a timeout occurred. we
4732 serialize these activities by invalidating the magic while
4733 holding a shared spinlock which will cause us to block if the
4734 callback is currently executing */
4735 spin_lock(&hdd_context_lock);
4736 context.magic = 0;
4737 spin_unlock(&hdd_context_lock);
4738
4739 if (VOS_STATUS_SUCCESS == vstatus)
4740 {
4741 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4742 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4743 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4744 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4745 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4746 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4747 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4748 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4749 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4750 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4751 }
4752 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004753}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004754#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004755
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004756#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004757void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4758{
4759 eCsrBand band = -1;
4760 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4761 switch (band)
4762 {
4763 case eCSR_BAND_ALL:
4764 *pBand = WLAN_HDD_UI_BAND_AUTO;
4765 break;
4766
4767 case eCSR_BAND_24:
4768 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4769 break;
4770
4771 case eCSR_BAND_5G:
4772 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4773 break;
4774
4775 default:
4776 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4777 *pBand = -1;
4778 break;
4779 }
4780}
4781
4782/**---------------------------------------------------------------------------
4783
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004784 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4785
4786 This function parses the send action frame data passed in the format
4787 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4788
Srinivas Girigowda56076852013-08-20 14:00:50 -07004789 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004790 \param - pTargetApBssid Pointer to target Ap bssid
4791 \param - pChannel Pointer to the Target AP channel
4792 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4793 \param - pBuf Pointer to data
4794 \param - pBufLen Pointer to data length
4795
4796 \return - 0 for success non-zero for failure
4797
4798 --------------------------------------------------------------------------*/
4799VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4800 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4801{
4802 tANI_U8 *inPtr = pValue;
4803 tANI_U8 *dataEnd;
4804 int tempInt;
4805 int j = 0;
4806 int i = 0;
4807 int v = 0;
4808 tANI_U8 tempBuf[32];
4809 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004810 /* 12 hexa decimal digits, 5 ':' and '\0' */
4811 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004812
4813 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4814 /*no argument after the command*/
4815 if (NULL == inPtr)
4816 {
4817 return -EINVAL;
4818 }
4819
4820 /*no space after the command*/
4821 else if (SPACE_ASCII_VALUE != *inPtr)
4822 {
4823 return -EINVAL;
4824 }
4825
4826 /*removing empty spaces*/
4827 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4828
4829 /*no argument followed by spaces*/
4830 if ('\0' == *inPtr)
4831 {
4832 return -EINVAL;
4833 }
4834
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004835 v = sscanf(inPtr, "%17s", macAddress);
4836 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004837 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4839 "Invalid MAC address or All hex inputs are not read (%d)", v);
4840 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004841 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004842
4843 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4844 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4845 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4846 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4847 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4848 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004849
4850 /* point to the next argument */
4851 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4852 /*no argument after the command*/
4853 if (NULL == inPtr) return -EINVAL;
4854
4855 /*removing empty spaces*/
4856 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4857
4858 /*no argument followed by spaces*/
4859 if ('\0' == *inPtr)
4860 {
4861 return -EINVAL;
4862 }
4863
4864 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004865 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004866 if (1 != v) return -EINVAL;
4867
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004868 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304869 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304870 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004871
4872 *pChannel = tempInt;
4873
4874 /* point to the next argument */
4875 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4876 /*no argument after the command*/
4877 if (NULL == inPtr) return -EINVAL;
4878 /*removing empty spaces*/
4879 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4880
4881 /*no argument followed by spaces*/
4882 if ('\0' == *inPtr)
4883 {
4884 return -EINVAL;
4885 }
4886
4887 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004888 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004889 if (1 != v) return -EINVAL;
4890
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004891 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004892 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004893
4894 *pDwellTime = tempInt;
4895
4896 /* point to the next argument */
4897 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4898 /*no argument after the command*/
4899 if (NULL == inPtr) return -EINVAL;
4900 /*removing empty spaces*/
4901 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4902
4903 /*no argument followed by spaces*/
4904 if ('\0' == *inPtr)
4905 {
4906 return -EINVAL;
4907 }
4908
4909 /* find the length of data */
4910 dataEnd = inPtr;
4911 while(('\0' != *dataEnd) )
4912 {
4913 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004914 }
Kiet Lambe150c22013-11-21 16:30:32 +05304915 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004916 if ( *pBufLen <= 0) return -EINVAL;
4917
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004918 /* Allocate the number of bytes based on the number of input characters
4919 whether it is even or odd.
4920 if the number of input characters are even, then we need N/2 byte.
4921 if the number of input characters are odd, then we need do (N+1)/2 to
4922 compensate rounding off.
4923 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4924 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4925 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004926 if (NULL == *pBuf)
4927 {
4928 hddLog(VOS_TRACE_LEVEL_FATAL,
4929 "%s: vos_mem_alloc failed ", __func__);
4930 return -EINVAL;
4931 }
4932
4933 /* the buffer received from the upper layer is character buffer,
4934 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4935 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4936 and f0 in 3rd location */
4937 for (i = 0, j = 0; j < *pBufLen; j += 2)
4938 {
Kiet Lambe150c22013-11-21 16:30:32 +05304939 if( j+1 == *pBufLen)
4940 {
4941 tempByte = hdd_parse_hex(inPtr[j]);
4942 }
4943 else
4944 {
4945 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4946 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004947 (*pBuf)[i++] = tempByte;
4948 }
4949 *pBufLen = i;
4950 return VOS_STATUS_SUCCESS;
4951}
4952
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004953/**---------------------------------------------------------------------------
4954
Srinivas Girigowdade697412013-02-14 16:31:48 -08004955 \brief hdd_parse_channellist() - HDD Parse channel list
4956
4957 This function parses the channel list passed in the format
4958 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004959 if the Number of channels (N) does not match with the actual number of channels passed
4960 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4961 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4962 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4963 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004964
4965 \param - pValue Pointer to input channel list
4966 \param - ChannelList Pointer to local output array to record channel list
4967 \param - pNumChannels Pointer to number of roam scan channels
4968
4969 \return - 0 for success non-zero for failure
4970
4971 --------------------------------------------------------------------------*/
4972VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4973{
4974 tANI_U8 *inPtr = pValue;
4975 int tempInt;
4976 int j = 0;
4977 int v = 0;
4978 char buf[32];
4979
4980 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4981 /*no argument after the command*/
4982 if (NULL == inPtr)
4983 {
4984 return -EINVAL;
4985 }
4986
4987 /*no space after the command*/
4988 else if (SPACE_ASCII_VALUE != *inPtr)
4989 {
4990 return -EINVAL;
4991 }
4992
4993 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004994 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004995
4996 /*no argument followed by spaces*/
4997 if ('\0' == *inPtr)
4998 {
4999 return -EINVAL;
5000 }
5001
5002 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005003 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005004 if (1 != v) return -EINVAL;
5005
Srinivas Girigowdade697412013-02-14 16:31:48 -08005006 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005007 if ((v < 0) ||
5008 (tempInt <= 0) ||
5009 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5010 {
5011 return -EINVAL;
5012 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005013
5014 *pNumChannels = tempInt;
5015
5016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5017 "Number of channels are: %d", *pNumChannels);
5018
5019 for (j = 0; j < (*pNumChannels); j++)
5020 {
5021 /*inPtr pointing to the beginning of first space after number of channels*/
5022 inPtr = strpbrk( inPtr, " " );
5023 /*no channel list after the number of channels argument*/
5024 if (NULL == inPtr)
5025 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005026 if (0 != j)
5027 {
5028 *pNumChannels = j;
5029 return VOS_STATUS_SUCCESS;
5030 }
5031 else
5032 {
5033 return -EINVAL;
5034 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005035 }
5036
5037 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005038 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005039
5040 /*no channel list after the number of channels argument and spaces*/
5041 if ( '\0' == *inPtr )
5042 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005043 if (0 != j)
5044 {
5045 *pNumChannels = j;
5046 return VOS_STATUS_SUCCESS;
5047 }
5048 else
5049 {
5050 return -EINVAL;
5051 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005052 }
5053
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005054 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005055 if (1 != v) return -EINVAL;
5056
Srinivas Girigowdade697412013-02-14 16:31:48 -08005057 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005058 if ((v < 0) ||
5059 (tempInt <= 0) ||
5060 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5061 {
5062 return -EINVAL;
5063 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005064 pChannelList[j] = tempInt;
5065
5066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5067 "Channel %d added to preferred channel list",
5068 pChannelList[j] );
5069 }
5070
Srinivas Girigowdade697412013-02-14 16:31:48 -08005071 return VOS_STATUS_SUCCESS;
5072}
5073
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005074
5075/**---------------------------------------------------------------------------
5076
5077 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5078
5079 This function parses the reasoc command data passed in the format
5080 REASSOC<space><bssid><space><channel>
5081
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005082 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005083 \param - pTargetApBssid Pointer to target Ap bssid
5084 \param - pChannel Pointer to the Target AP channel
5085
5086 \return - 0 for success non-zero for failure
5087
5088 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005089VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5090 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005091{
5092 tANI_U8 *inPtr = pValue;
5093 int tempInt;
5094 int v = 0;
5095 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005096 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005097 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005098
5099 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5100 /*no argument after the command*/
5101 if (NULL == inPtr)
5102 {
5103 return -EINVAL;
5104 }
5105
5106 /*no space after the command*/
5107 else if (SPACE_ASCII_VALUE != *inPtr)
5108 {
5109 return -EINVAL;
5110 }
5111
5112 /*removing empty spaces*/
5113 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5114
5115 /*no argument followed by spaces*/
5116 if ('\0' == *inPtr)
5117 {
5118 return -EINVAL;
5119 }
5120
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005121 v = sscanf(inPtr, "%17s", macAddress);
5122 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005123 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5125 "Invalid MAC address or All hex inputs are not read (%d)", v);
5126 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005127 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005128
5129 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5130 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5131 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5132 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5133 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5134 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005135
5136 /* point to the next argument */
5137 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5138 /*no argument after the command*/
5139 if (NULL == inPtr) return -EINVAL;
5140
5141 /*removing empty spaces*/
5142 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5143
5144 /*no argument followed by spaces*/
5145 if ('\0' == *inPtr)
5146 {
5147 return -EINVAL;
5148 }
5149
5150 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005151 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005152 if (1 != v) return -EINVAL;
5153
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005154 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005155 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305156 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005157 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5158 {
5159 return -EINVAL;
5160 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005161
5162 *pChannel = tempInt;
5163 return VOS_STATUS_SUCCESS;
5164}
5165
5166#endif
5167
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005168#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005169/**---------------------------------------------------------------------------
5170
5171 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5172
5173 This function parses the SETCCKM IE command
5174 SETCCKMIE<space><ie data>
5175
5176 \param - pValue Pointer to input data
5177 \param - pCckmIe Pointer to output cckm Ie
5178 \param - pCckmIeLen Pointer to output cckm ie length
5179
5180 \return - 0 for success non-zero for failure
5181
5182 --------------------------------------------------------------------------*/
5183VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5184 tANI_U8 *pCckmIeLen)
5185{
5186 tANI_U8 *inPtr = pValue;
5187 tANI_U8 *dataEnd;
5188 int j = 0;
5189 int i = 0;
5190 tANI_U8 tempByte = 0;
5191
5192 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5193 /*no argument after the command*/
5194 if (NULL == inPtr)
5195 {
5196 return -EINVAL;
5197 }
5198
5199 /*no space after the command*/
5200 else if (SPACE_ASCII_VALUE != *inPtr)
5201 {
5202 return -EINVAL;
5203 }
5204
5205 /*removing empty spaces*/
5206 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5207
5208 /*no argument followed by spaces*/
5209 if ('\0' == *inPtr)
5210 {
5211 return -EINVAL;
5212 }
5213
5214 /* find the length of data */
5215 dataEnd = inPtr;
5216 while(('\0' != *dataEnd) )
5217 {
5218 dataEnd++;
5219 ++(*pCckmIeLen);
5220 }
5221 if ( *pCckmIeLen <= 0) return -EINVAL;
5222
5223 /* Allocate the number of bytes based on the number of input characters
5224 whether it is even or odd.
5225 if the number of input characters are even, then we need N/2 byte.
5226 if the number of input characters are odd, then we need do (N+1)/2 to
5227 compensate rounding off.
5228 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5229 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5230 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5231 if (NULL == *pCckmIe)
5232 {
5233 hddLog(VOS_TRACE_LEVEL_FATAL,
5234 "%s: vos_mem_alloc failed ", __func__);
5235 return -EINVAL;
5236 }
5237 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5238 /* the buffer received from the upper layer is character buffer,
5239 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5240 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5241 and f0 in 3rd location */
5242 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5243 {
5244 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5245 (*pCckmIe)[i++] = tempByte;
5246 }
5247 *pCckmIeLen = i;
5248
5249 return VOS_STATUS_SUCCESS;
5250}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005251#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005252
Jeff Johnson295189b2012-06-20 16:38:30 -07005253/**---------------------------------------------------------------------------
5254
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005255 \brief hdd_is_valid_mac_address() - Validate MAC address
5256
5257 This function validates whether the given MAC address is valid or not
5258 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5259 where X is the hexa decimal digit character and separated by ':'
5260 This algorithm works even if MAC address is not separated by ':'
5261
5262 This code checks given input string mac contains exactly 12 hexadecimal digits.
5263 and a separator colon : appears in the input string only after
5264 an even number of hex digits.
5265
5266 \param - pMacAddr pointer to the input MAC address
5267 \return - 1 for valid and 0 for invalid
5268
5269 --------------------------------------------------------------------------*/
5270
5271v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5272{
5273 int xdigit = 0;
5274 int separator = 0;
5275 while (*pMacAddr)
5276 {
5277 if (isxdigit(*pMacAddr))
5278 {
5279 xdigit++;
5280 }
5281 else if (':' == *pMacAddr)
5282 {
5283 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5284 break;
5285
5286 ++separator;
5287 }
5288 else
5289 {
5290 separator = -1;
5291 /* Invalid MAC found */
5292 return 0;
5293 }
5294 ++pMacAddr;
5295 }
5296 return (xdigit == 12 && (separator == 5 || separator == 0));
5297}
5298
5299/**---------------------------------------------------------------------------
5300
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305301 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005302
5303 \param - dev Pointer to net_device structure
5304
5305 \return - 0 for success non-zero for failure
5306
5307 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305308int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005309{
5310 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5311 hdd_context_t *pHddCtx;
5312 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5313 VOS_STATUS status;
5314 v_BOOL_t in_standby = TRUE;
5315
5316 if (NULL == pAdapter)
5317 {
5318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305319 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005320 return -ENODEV;
5321 }
5322
5323 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305324 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5325 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005326 if (NULL == pHddCtx)
5327 {
5328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005329 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005330 return -ENODEV;
5331 }
5332
5333 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5334 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5335 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005336 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5337 {
5338 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305339 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005340 in_standby = FALSE;
5341 break;
5342 }
5343 else
5344 {
5345 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5346 pAdapterNode = pNext;
5347 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005348 }
5349
5350 if (TRUE == in_standby)
5351 {
5352 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5353 {
5354 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5355 "wlan out of power save", __func__);
5356 return -EINVAL;
5357 }
5358 }
5359
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005360 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005361 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5362 {
5363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005364 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005365 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305366 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005367 netif_tx_start_all_queues(dev);
5368 }
5369
5370 return 0;
5371}
5372
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305373/**---------------------------------------------------------------------------
5374
5375 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5376
5377 This is called in response to ifconfig up
5378
5379 \param - dev Pointer to net_device structure
5380
5381 \return - 0 for success non-zero for failure
5382
5383 --------------------------------------------------------------------------*/
5384int hdd_open(struct net_device *dev)
5385{
5386 int ret;
5387
5388 vos_ssr_protect(__func__);
5389 ret = __hdd_open(dev);
5390 vos_ssr_unprotect(__func__);
5391
5392 return ret;
5393}
5394
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305395int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005396{
5397 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5398
5399 if(pAdapter == NULL) {
5400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005401 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005402 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005403 }
5404
5405 netif_start_queue(dev);
5406
5407 return 0;
5408}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305409
5410int hdd_mon_open (struct net_device *dev)
5411{
5412 int ret;
5413
5414 vos_ssr_protect(__func__);
5415 ret = __hdd_mon_open(dev);
5416 vos_ssr_unprotect(__func__);
5417
5418 return ret;
5419}
5420
Jeff Johnson295189b2012-06-20 16:38:30 -07005421/**---------------------------------------------------------------------------
5422
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305423 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005424
5425 \param - dev Pointer to net_device structure
5426
5427 \return - 0 for success non-zero for failure
5428
5429 --------------------------------------------------------------------------*/
5430
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305431int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005432{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305433 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5435 hdd_context_t *pHddCtx;
5436 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5437 VOS_STATUS status;
5438 v_BOOL_t enter_standby = TRUE;
5439
5440 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 if (NULL == pAdapter)
5442 {
5443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305444 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 return -ENODEV;
5446 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305447 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305448 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305449
5450 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5451 ret = wlan_hdd_validate_context(pHddCtx);
5452 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005453 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305454 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 }
5456
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305457 /* Nothing to be done if the interface is not opened */
5458 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5459 {
5460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5461 "%s: NETDEV Interface is not OPENED", __func__);
5462 return -ENODEV;
5463 }
5464
5465 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005466 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005467 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305468
5469 /* Disable TX on the interface, after this hard_start_xmit() will not
5470 * be called on that interface
5471 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305474
5475 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 netif_carrier_off(pAdapter->dev);
5477
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305478 /* The interface is marked as down for outside world (aka kernel)
5479 * But the driver is pretty much alive inside. The driver needs to
5480 * tear down the existing connection on the netdev (session)
5481 * cleanup the data pipes and wait until the control plane is stabilized
5482 * for this interface. The call also needs to wait until the above
5483 * mentioned actions are completed before returning to the caller.
5484 * Notice that the hdd_stop_adapter is requested not to close the session
5485 * That is intentional to be able to scan if it is a STA/P2P interface
5486 */
5487 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305488#ifdef FEATURE_WLAN_TDLS
5489 mutex_lock(&pHddCtx->tdls_lock);
5490#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305491 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305492 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305493#ifdef FEATURE_WLAN_TDLS
5494 mutex_unlock(&pHddCtx->tdls_lock);
5495#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 /* SoftAP ifaces should never go in power save mode
5497 making sure same here. */
5498 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5499 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005501 )
5502 {
5503 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5505 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 EXIT();
5507 return 0;
5508 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305509 /* Find if any iface is up. If any iface is up then can't put device to
5510 * sleep/power save mode
5511 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005512 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5513 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5514 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005515 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5516 {
5517 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305518 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005519 enter_standby = FALSE;
5520 break;
5521 }
5522 else
5523 {
5524 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5525 pAdapterNode = pNext;
5526 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 }
5528
5529 if (TRUE == enter_standby)
5530 {
5531 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5532 "entering standby", __func__);
5533 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5534 {
5535 /*log and return success*/
5536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5537 "wlan in power save", __func__);
5538 }
5539 }
5540
5541 EXIT();
5542 return 0;
5543}
5544
5545/**---------------------------------------------------------------------------
5546
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305547 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005548
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305549 This is called in response to ifconfig down
5550
5551 \param - dev Pointer to net_device structure
5552
5553 \return - 0 for success non-zero for failure
5554-----------------------------------------------------------------------------*/
5555int hdd_stop (struct net_device *dev)
5556{
5557 int ret;
5558
5559 vos_ssr_protect(__func__);
5560 ret = __hdd_stop(dev);
5561 vos_ssr_unprotect(__func__);
5562
5563 return ret;
5564}
5565
5566/**---------------------------------------------------------------------------
5567
5568 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005569
5570 \param - dev Pointer to net_device structure
5571
5572 \return - void
5573
5574 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305575static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005576{
5577 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305578 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 ENTER();
5580
5581 do
5582 {
5583 if (NULL == pAdapter)
5584 {
5585 hddLog(VOS_TRACE_LEVEL_FATAL,
5586 "%s: NULL pAdapter", __func__);
5587 break;
5588 }
5589
5590 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5591 {
5592 hddLog(VOS_TRACE_LEVEL_FATAL,
5593 "%s: Invalid magic", __func__);
5594 break;
5595 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305596 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5597 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005598 {
5599 hddLog(VOS_TRACE_LEVEL_FATAL,
5600 "%s: NULL pHddCtx", __func__);
5601 break;
5602 }
5603
5604 if (dev != pAdapter->dev)
5605 {
5606 hddLog(VOS_TRACE_LEVEL_FATAL,
5607 "%s: Invalid device reference", __func__);
5608 /* we haven't validated all cases so let this go for now */
5609 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305610#ifdef FEATURE_WLAN_TDLS
5611 mutex_lock(&pHddCtx->tdls_lock);
5612#endif
c_hpothu002231a2015-02-05 14:58:51 +05305613 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305614#ifdef FEATURE_WLAN_TDLS
5615 mutex_unlock(&pHddCtx->tdls_lock);
5616#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005617
5618 /* after uninit our adapter structure will no longer be valid */
5619 pAdapter->dev = NULL;
5620 pAdapter->magic = 0;
5621 } while (0);
5622
5623 EXIT();
5624}
5625
5626/**---------------------------------------------------------------------------
5627
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305628 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5629
5630 This is called during the netdev unregister to uninitialize all data
5631associated with the device
5632
5633 \param - dev Pointer to net_device structure
5634
5635 \return - void
5636
5637 --------------------------------------------------------------------------*/
5638static void hdd_uninit (struct net_device *dev)
5639{
5640 vos_ssr_protect(__func__);
5641 __hdd_uninit(dev);
5642 vos_ssr_unprotect(__func__);
5643}
5644
5645/**---------------------------------------------------------------------------
5646
Jeff Johnson295189b2012-06-20 16:38:30 -07005647 \brief hdd_release_firmware() -
5648
5649 This function calls the release firmware API to free the firmware buffer.
5650
5651 \param - pFileName Pointer to the File Name.
5652 pCtx - Pointer to the adapter .
5653
5654
5655 \return - 0 for success, non zero for failure
5656
5657 --------------------------------------------------------------------------*/
5658
5659VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5660{
5661 VOS_STATUS status = VOS_STATUS_SUCCESS;
5662 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5663 ENTER();
5664
5665
5666 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5667
5668 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5669
5670 if(pHddCtx->fw) {
5671 release_firmware(pHddCtx->fw);
5672 pHddCtx->fw = NULL;
5673 }
5674 else
5675 status = VOS_STATUS_E_FAILURE;
5676 }
5677 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5678 if(pHddCtx->nv) {
5679 release_firmware(pHddCtx->nv);
5680 pHddCtx->nv = NULL;
5681 }
5682 else
5683 status = VOS_STATUS_E_FAILURE;
5684
5685 }
5686
5687 EXIT();
5688 return status;
5689}
5690
5691/**---------------------------------------------------------------------------
5692
5693 \brief hdd_request_firmware() -
5694
5695 This function reads the firmware file using the request firmware
5696 API and returns the the firmware data and the firmware file size.
5697
5698 \param - pfileName - Pointer to the file name.
5699 - pCtx - Pointer to the adapter .
5700 - ppfw_data - Pointer to the pointer of the firmware data.
5701 - pSize - Pointer to the file size.
5702
5703 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5704
5705 --------------------------------------------------------------------------*/
5706
5707
5708VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5709{
5710 int status;
5711 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5712 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5713 ENTER();
5714
5715 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5716
5717 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5718
5719 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5720 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5721 __func__, pfileName);
5722 retval = VOS_STATUS_E_FAILURE;
5723 }
5724
5725 else {
5726 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5727 *pSize = pHddCtx->fw->size;
5728 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5729 __func__, *pSize);
5730 }
5731 }
5732 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5733
5734 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5735
5736 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5737 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5738 __func__, pfileName);
5739 retval = VOS_STATUS_E_FAILURE;
5740 }
5741
5742 else {
5743 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5744 *pSize = pHddCtx->nv->size;
5745 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5746 __func__, *pSize);
5747 }
5748 }
5749
5750 EXIT();
5751 return retval;
5752}
5753/**---------------------------------------------------------------------------
5754 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5755
5756 This is the function invoked by SME to inform the result of a full power
5757 request issued by HDD
5758
5759 \param - callbackcontext - Pointer to cookie
5760 status - result of request
5761
5762 \return - None
5763
5764--------------------------------------------------------------------------*/
5765void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5766{
5767 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5768
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005769 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 if(&pHddCtx->full_pwr_comp_var)
5771 {
5772 complete(&pHddCtx->full_pwr_comp_var);
5773 }
5774}
5775
5776/**---------------------------------------------------------------------------
5777
5778 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5779
5780 This is the function invoked by SME to inform the result of BMPS
5781 request issued by HDD
5782
5783 \param - callbackcontext - Pointer to cookie
5784 status - result of request
5785
5786 \return - None
5787
5788--------------------------------------------------------------------------*/
5789void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5790{
5791
5792 struct completion *completion_var = (struct completion*) callbackContext;
5793
Arif Hussain6d2a3322013-11-17 19:50:10 -08005794 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005795 if(completion_var != NULL)
5796 {
5797 complete(completion_var);
5798 }
5799}
5800
5801/**---------------------------------------------------------------------------
5802
5803 \brief hdd_get_cfg_file_size() -
5804
5805 This function reads the configuration file using the request firmware
5806 API and returns the configuration file size.
5807
5808 \param - pCtx - Pointer to the adapter .
5809 - pFileName - Pointer to the file name.
5810 - pBufSize - Pointer to the buffer size.
5811
5812 \return - 0 for success, non zero for failure
5813
5814 --------------------------------------------------------------------------*/
5815
5816VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5817{
5818 int status;
5819 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5820
5821 ENTER();
5822
5823 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5824
5825 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5826 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5827 status = VOS_STATUS_E_FAILURE;
5828 }
5829 else {
5830 *pBufSize = pHddCtx->fw->size;
5831 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5832 release_firmware(pHddCtx->fw);
5833 pHddCtx->fw = NULL;
5834 }
5835
5836 EXIT();
5837 return VOS_STATUS_SUCCESS;
5838}
5839
5840/**---------------------------------------------------------------------------
5841
5842 \brief hdd_read_cfg_file() -
5843
5844 This function reads the configuration file using the request firmware
5845 API and returns the cfg data and the buffer size of the configuration file.
5846
5847 \param - pCtx - Pointer to the adapter .
5848 - pFileName - Pointer to the file name.
5849 - pBuffer - Pointer to the data buffer.
5850 - pBufSize - Pointer to the buffer size.
5851
5852 \return - 0 for success, non zero for failure
5853
5854 --------------------------------------------------------------------------*/
5855
5856VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5857 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5858{
5859 int status;
5860 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5861
5862 ENTER();
5863
5864 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5865
5866 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5867 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5868 return VOS_STATUS_E_FAILURE;
5869 }
5870 else {
5871 if(*pBufSize != pHddCtx->fw->size) {
5872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5873 "file size", __func__);
5874 release_firmware(pHddCtx->fw);
5875 pHddCtx->fw = NULL;
5876 return VOS_STATUS_E_FAILURE;
5877 }
5878 else {
5879 if(pBuffer) {
5880 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5881 }
5882 release_firmware(pHddCtx->fw);
5883 pHddCtx->fw = NULL;
5884 }
5885 }
5886
5887 EXIT();
5888
5889 return VOS_STATUS_SUCCESS;
5890}
5891
5892/**---------------------------------------------------------------------------
5893
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305894 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005895
5896 This function sets the user specified mac address using
5897 the command ifconfig wlanX hw ether <mac adress>.
5898
5899 \param - dev - Pointer to the net device.
5900 - addr - Pointer to the sockaddr.
5901 \return - 0 for success, non zero for failure
5902
5903 --------------------------------------------------------------------------*/
5904
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305905static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005906{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305907 hdd_adapter_t *pAdapter;
5908 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005909 struct sockaddr *psta_mac_addr = addr;
5910 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305911 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005912
5913 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305914 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5915 if (NULL == pAdapter)
5916 {
5917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5918 "%s: Adapter is NULL",__func__);
5919 return -EINVAL;
5920 }
5921 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5922 ret = wlan_hdd_validate_context(pHddCtx);
5923 if (0 != ret)
5924 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305925 return ret;
5926 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005927
5928 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5930
5931 EXIT();
5932 return halStatus;
5933}
5934
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305935/**---------------------------------------------------------------------------
5936
5937 \brief hdd_set_mac_address() -
5938
5939 Wrapper function to protect __hdd_set_mac_address() function from ssr
5940
5941 \param - dev - Pointer to the net device.
5942 - addr - Pointer to the sockaddr.
5943 \return - 0 for success, non zero for failure
5944
5945 --------------------------------------------------------------------------*/
5946static int hdd_set_mac_address(struct net_device *dev, void *addr)
5947{
5948 int ret;
5949
5950 vos_ssr_protect(__func__);
5951 ret = __hdd_set_mac_address(dev, addr);
5952 vos_ssr_unprotect(__func__);
5953
5954 return ret;
5955}
5956
Jeff Johnson295189b2012-06-20 16:38:30 -07005957tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5958{
5959 int i;
5960 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5961 {
Abhishek Singheb183782014-02-06 13:37:21 +05305962 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 break;
5964 }
5965
5966 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5967 return NULL;
5968
5969 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5970 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5971}
5972
5973void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5974{
5975 int i;
5976 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5977 {
5978 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5979 {
5980 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5981 break;
5982 }
5983 }
5984 return;
5985}
5986
5987#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5988 static struct net_device_ops wlan_drv_ops = {
5989 .ndo_open = hdd_open,
5990 .ndo_stop = hdd_stop,
5991 .ndo_uninit = hdd_uninit,
5992 .ndo_start_xmit = hdd_hard_start_xmit,
5993 .ndo_tx_timeout = hdd_tx_timeout,
5994 .ndo_get_stats = hdd_stats,
5995 .ndo_do_ioctl = hdd_ioctl,
5996 .ndo_set_mac_address = hdd_set_mac_address,
5997 .ndo_select_queue = hdd_select_queue,
5998#ifdef WLAN_FEATURE_PACKET_FILTERING
5999#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6000 .ndo_set_rx_mode = hdd_set_multicast_list,
6001#else
6002 .ndo_set_multicast_list = hdd_set_multicast_list,
6003#endif //LINUX_VERSION_CODE
6004#endif
6005 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 static struct net_device_ops wlan_mon_drv_ops = {
6007 .ndo_open = hdd_mon_open,
6008 .ndo_stop = hdd_stop,
6009 .ndo_uninit = hdd_uninit,
6010 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6011 .ndo_tx_timeout = hdd_tx_timeout,
6012 .ndo_get_stats = hdd_stats,
6013 .ndo_do_ioctl = hdd_ioctl,
6014 .ndo_set_mac_address = hdd_set_mac_address,
6015 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306016
Jeff Johnson295189b2012-06-20 16:38:30 -07006017#endif
6018
6019void hdd_set_station_ops( struct net_device *pWlanDev )
6020{
6021#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006022 pWlanDev->netdev_ops = &wlan_drv_ops;
6023#else
6024 pWlanDev->open = hdd_open;
6025 pWlanDev->stop = hdd_stop;
6026 pWlanDev->uninit = hdd_uninit;
6027 pWlanDev->hard_start_xmit = NULL;
6028 pWlanDev->tx_timeout = hdd_tx_timeout;
6029 pWlanDev->get_stats = hdd_stats;
6030 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 pWlanDev->set_mac_address = hdd_set_mac_address;
6032#endif
6033}
6034
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006035static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006036{
6037 struct net_device *pWlanDev = NULL;
6038 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 /*
6040 * cfg80211 initialization and registration....
6041 */
6042 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6043
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 if(pWlanDev != NULL)
6045 {
6046
6047 //Save the pointer to the net_device in the HDD adapter
6048 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6049
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6051
6052 pAdapter->dev = pWlanDev;
6053 pAdapter->pHddCtx = pHddCtx;
6054 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306055 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006056
6057 init_completion(&pAdapter->session_open_comp_var);
6058 init_completion(&pAdapter->session_close_comp_var);
6059 init_completion(&pAdapter->disconnect_comp_var);
6060 init_completion(&pAdapter->linkup_event_var);
6061 init_completion(&pAdapter->cancel_rem_on_chan_var);
6062 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306063 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6065 init_completion(&pAdapter->offchannel_tx_event);
6066#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006068#ifdef FEATURE_WLAN_TDLS
6069 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006070 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006071 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306072 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006073#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 init_completion(&pHddCtx->mc_sus_event_var);
6075 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306076 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006077 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006078 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006079
Rajeev79dbe4c2013-10-05 11:03:42 +05306080#ifdef FEATURE_WLAN_BATCH_SCAN
6081 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6082 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6083 pAdapter->pBatchScanRsp = NULL;
6084 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006085 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006086 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306087 mutex_init(&pAdapter->hdd_batch_scan_lock);
6088#endif
6089
Jeff Johnson295189b2012-06-20 16:38:30 -07006090 pAdapter->isLinkUpSvcNeeded = FALSE;
6091 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6092 //Init the net_device structure
6093 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6094
6095 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6096 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6097 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6098 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6099
6100 hdd_set_station_ops( pAdapter->dev );
6101
6102 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006103 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6104 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6105 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006106 /* set pWlanDev's parent to underlying device */
6107 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006108
6109 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006110 }
6111
6112 return pAdapter;
6113}
6114
6115VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6116{
6117 struct net_device *pWlanDev = pAdapter->dev;
6118 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6119 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6120 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6121
6122 if( rtnl_lock_held )
6123 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006124 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6126 {
6127 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6128 return VOS_STATUS_E_FAILURE;
6129 }
6130 }
6131 if (register_netdevice(pWlanDev))
6132 {
6133 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6134 return VOS_STATUS_E_FAILURE;
6135 }
6136 }
6137 else
6138 {
6139 if(register_netdev(pWlanDev))
6140 {
6141 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6142 return VOS_STATUS_E_FAILURE;
6143 }
6144 }
6145 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6146
6147 return VOS_STATUS_SUCCESS;
6148}
6149
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006150static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006151{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006152 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006153
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006154 if (NULL == pAdapter)
6155 {
6156 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6157 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006158 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006159
6160 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6161 {
6162 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6163 return eHAL_STATUS_NOT_INITIALIZED;
6164 }
6165
6166 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6167
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006168#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006169 /* need to make sure all of our scheduled work has completed.
6170 * This callback is called from MC thread context, so it is safe to
6171 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006172 *
6173 * Even though this is called from MC thread context, if there is a faulty
6174 * work item in the system, that can hang this call forever. So flushing
6175 * this global work queue is not safe; and now we make sure that
6176 * individual work queues are stopped correctly. But the cancel work queue
6177 * is a GPL only API, so the proprietary version of the driver would still
6178 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006179 */
6180 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006181#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006182
6183 /* We can be blocked while waiting for scheduled work to be
6184 * flushed, and the adapter structure can potentially be freed, in
6185 * which case the magic will have been reset. So make sure the
6186 * magic is still good, and hence the adapter structure is still
6187 * valid, before signaling completion */
6188 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6189 {
6190 complete(&pAdapter->session_close_comp_var);
6191 }
6192
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 return eHAL_STATUS_SUCCESS;
6194}
6195
6196VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6197{
6198 struct net_device *pWlanDev = pAdapter->dev;
6199 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6200 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6201 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6202 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306203 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006204
6205 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006206 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006207 //Open a SME session for future operation
6208 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006209 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006210 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6211 {
6212 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006213 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 halStatus, halStatus );
6215 status = VOS_STATUS_E_FAILURE;
6216 goto error_sme_open;
6217 }
6218
6219 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306220 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 &pAdapter->session_open_comp_var,
6222 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306223 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006224 {
6225 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306226 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 status = VOS_STATUS_E_FAILURE;
6228 goto error_sme_open;
6229 }
6230
6231 // Register wireless extensions
6232 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6233 {
6234 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006235 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 halStatus, halStatus );
6237 status = VOS_STATUS_E_FAILURE;
6238 goto error_register_wext;
6239 }
6240 //Safe to register the hard_start_xmit function again
6241#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6242 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6243#else
6244 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6245#endif
6246
6247 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306248 hddLog(VOS_TRACE_LEVEL_INFO,
6249 "%s: Set HDD connState to eConnectionState_NotConnected",
6250 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6252
6253 //Set the default operation channel
6254 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6255
6256 /* Make the default Auth Type as OPEN*/
6257 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6258
6259 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6260 {
6261 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006262 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006263 status, status );
6264 goto error_init_txrx;
6265 }
6266
6267 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6268
6269 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6270 {
6271 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006272 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 status, status );
6274 goto error_wmm_init;
6275 }
6276
6277 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6278
6279 return VOS_STATUS_SUCCESS;
6280
6281error_wmm_init:
6282 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6283 hdd_deinit_tx_rx(pAdapter);
6284error_init_txrx:
6285 hdd_UnregisterWext(pWlanDev);
6286error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006287 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 {
6289 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006290 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006292 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306294 unsigned long rc;
6295
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306297 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006299 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306300 if (rc <= 0)
6301 hddLog(VOS_TRACE_LEVEL_ERROR,
6302 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 }
6304}
6305error_sme_open:
6306 return status;
6307}
6308
Jeff Johnson295189b2012-06-20 16:38:30 -07006309void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6310{
6311 hdd_cfg80211_state_t *cfgState;
6312
6313 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6314
6315 if( NULL != cfgState->buf )
6316 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306317 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6319 rc = wait_for_completion_interruptible_timeout(
6320 &pAdapter->tx_action_cnf_event,
6321 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306322 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306325 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6326 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 }
6328 }
6329 return;
6330}
Jeff Johnson295189b2012-06-20 16:38:30 -07006331
c_hpothu002231a2015-02-05 14:58:51 +05306332void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006333{
6334 ENTER();
6335 switch ( pAdapter->device_mode )
6336 {
6337 case WLAN_HDD_INFRA_STATION:
6338 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006339 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 {
6341 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6342 {
6343 hdd_deinit_tx_rx( pAdapter );
6344 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6345 }
6346
6347 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6348 {
6349 hdd_wmm_adapter_close( pAdapter );
6350 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6351 }
6352
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 break;
6355 }
6356
6357 case WLAN_HDD_SOFTAP:
6358 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306360
6361 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6362 {
6363 hdd_wmm_adapter_close( pAdapter );
6364 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6365 }
6366
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006368
c_hpothu002231a2015-02-05 14:58:51 +05306369 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 break;
6373 }
6374
6375 case WLAN_HDD_MONITOR:
6376 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006378 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6379 {
6380 hdd_deinit_tx_rx( pAdapter );
6381 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6382 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 if(NULL != pAdapterforTx)
6384 {
6385 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6386 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 break;
6388 }
6389
6390
6391 default:
6392 break;
6393 }
6394
6395 EXIT();
6396}
6397
6398void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6399{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006400 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306401
6402 ENTER();
6403 if (NULL == pAdapter)
6404 {
6405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6406 "%s: HDD adapter is Null", __func__);
6407 return;
6408 }
6409
6410 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006411
Rajeev79dbe4c2013-10-05 11:03:42 +05306412#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306413 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6414 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006415 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306416 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6417 )
6418 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006419 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306420 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006421 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6422 {
6423 hdd_deinit_batch_scan(pAdapter);
6424 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306425 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006426 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306427#endif
6428
Jeff Johnson295189b2012-06-20 16:38:30 -07006429 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6430 if( rtnl_held )
6431 {
6432 unregister_netdevice(pWlanDev);
6433 }
6434 else
6435 {
6436 unregister_netdev(pWlanDev);
6437 }
6438 // note that the pAdapter is no longer valid at this point
6439 // since the memory has been reclaimed
6440 }
6441
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306442 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006443}
6444
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006445void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6446{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306447 VOS_STATUS status;
6448 hdd_adapter_t *pAdapter = NULL;
6449 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006450
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306451 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006452
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306453 /*loop through all adapters.*/
6454 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006455 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306456 pAdapter = pAdapterNode->pAdapter;
6457 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6458 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006459
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306460 { // we skip this registration for modes other than STA and P2P client modes.
6461 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6462 pAdapterNode = pNext;
6463 continue;
6464 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006465
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306466 //Apply Dynamic DTIM For P2P
6467 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6468 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6469 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6470 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6471 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6472 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6473 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6474 (eConnectionState_Associated ==
6475 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6476 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6477 {
6478 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006479
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306480 powerRequest.uIgnoreDTIM = 1;
6481 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6482
6483 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6484 {
6485 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6486 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6487 }
6488 else
6489 {
6490 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6491 }
6492
6493 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6494 * specified during Enter/Exit BMPS when LCD off*/
6495 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6496 NULL, eANI_BOOLEAN_FALSE);
6497 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6498 NULL, eANI_BOOLEAN_FALSE);
6499
6500 /* switch to the DTIM specified in cfg.ini */
6501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6502 "Switch to DTIM %d", powerRequest.uListenInterval);
6503 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6504 break;
6505
6506 }
6507
6508 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6509 pAdapterNode = pNext;
6510 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006511}
6512
6513void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6514{
6515 /*Switch back to DTIM 1*/
6516 tSirSetPowerParamsReq powerRequest = { 0 };
6517
6518 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6519 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006520 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006521
6522 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6523 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6524 NULL, eANI_BOOLEAN_FALSE);
6525 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6526 NULL, eANI_BOOLEAN_FALSE);
6527
6528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6529 "Switch to DTIM%d",powerRequest.uListenInterval);
6530 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6531
6532}
6533
Jeff Johnson295189b2012-06-20 16:38:30 -07006534VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6535{
6536 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306537 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6538 {
6539 hddLog( LOGE, FL("Wlan Unload in progress"));
6540 return VOS_STATUS_E_PERM;
6541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006542 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6543 {
6544 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6545 }
6546
6547 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6548 {
6549 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6550 }
6551
6552 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6553 {
6554 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6555 }
6556
6557 return status;
6558}
6559
6560VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6561{
6562 hdd_adapter_t *pAdapter = NULL;
6563 eHalStatus halStatus;
6564 VOS_STATUS status = VOS_STATUS_E_INVAL;
6565 v_BOOL_t disableBmps = FALSE;
6566 v_BOOL_t disableImps = FALSE;
6567
6568 switch(session_type)
6569 {
6570 case WLAN_HDD_INFRA_STATION:
6571 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006572 case WLAN_HDD_P2P_CLIENT:
6573 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 //Exit BMPS -> Is Sta/P2P Client is already connected
6575 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6576 if((NULL != pAdapter)&&
6577 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6578 {
6579 disableBmps = TRUE;
6580 }
6581
6582 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6583 if((NULL != pAdapter)&&
6584 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6585 {
6586 disableBmps = TRUE;
6587 }
6588
6589 //Exit both Bmps and Imps incase of Go/SAP Mode
6590 if((WLAN_HDD_SOFTAP == session_type) ||
6591 (WLAN_HDD_P2P_GO == session_type))
6592 {
6593 disableBmps = TRUE;
6594 disableImps = TRUE;
6595 }
6596
6597 if(TRUE == disableImps)
6598 {
6599 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6600 {
6601 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6602 }
6603 }
6604
6605 if(TRUE == disableBmps)
6606 {
6607 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6608 {
6609 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6610
6611 if(eHAL_STATUS_SUCCESS != halStatus)
6612 {
6613 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006614 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 VOS_ASSERT(0);
6616 return status;
6617 }
6618 }
6619
6620 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6621 {
6622 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6623
6624 if(eHAL_STATUS_SUCCESS != halStatus)
6625 {
6626 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006627 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006628 VOS_ASSERT(0);
6629 return status;
6630 }
6631 }
6632 }
6633
6634 if((TRUE == disableBmps) ||
6635 (TRUE == disableImps))
6636 {
6637 /* Now, get the chip into Full Power now */
6638 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6639 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6640 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6641
6642 if(halStatus != eHAL_STATUS_SUCCESS)
6643 {
6644 if(halStatus == eHAL_STATUS_PMC_PENDING)
6645 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306646 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006647 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306648 ret = wait_for_completion_interruptible_timeout(
6649 &pHddCtx->full_pwr_comp_var,
6650 msecs_to_jiffies(1000));
6651 if (ret <= 0)
6652 {
6653 hddLog(VOS_TRACE_LEVEL_ERROR,
6654 "%s: wait on full_pwr_comp_var failed %ld",
6655 __func__, ret);
6656 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006657 }
6658 else
6659 {
6660 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006661 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006662 VOS_ASSERT(0);
6663 return status;
6664 }
6665 }
6666
6667 status = VOS_STATUS_SUCCESS;
6668 }
6669
6670 break;
6671 }
6672 return status;
6673}
6674
6675hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006676 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006677 tANI_U8 rtnl_held )
6678{
6679 hdd_adapter_t *pAdapter = NULL;
6680 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6681 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6682 VOS_STATUS exitbmpsStatus;
6683
Arif Hussain6d2a3322013-11-17 19:50:10 -08006684 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006685
Nirav Shah436658f2014-02-28 17:05:45 +05306686 if(macAddr == NULL)
6687 {
6688 /* Not received valid macAddr */
6689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6690 "%s:Unable to add virtual intf: Not able to get"
6691 "valid mac address",__func__);
6692 return NULL;
6693 }
6694
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 //Disable BMPS incase of Concurrency
6696 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6697
6698 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6699 {
6700 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306701 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 VOS_ASSERT(0);
6703 return NULL;
6704 }
6705
6706 switch(session_type)
6707 {
6708 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006709 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006710 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006711 {
6712 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6713
6714 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306715 {
6716 hddLog(VOS_TRACE_LEVEL_FATAL,
6717 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006718 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306719 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006720
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306721#ifdef FEATURE_WLAN_TDLS
6722 /* A Mutex Lock is introduced while changing/initializing the mode to
6723 * protect the concurrent access for the Adapters by TDLS module.
6724 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306725 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306726#endif
6727
Jeff Johnsone7245742012-09-05 17:12:55 -07006728 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6729 NL80211_IFTYPE_P2P_CLIENT:
6730 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006731
Jeff Johnson295189b2012-06-20 16:38:30 -07006732 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306733#ifdef FEATURE_WLAN_TDLS
6734 mutex_unlock(&pHddCtx->tdls_lock);
6735#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306736
6737 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 if( VOS_STATUS_SUCCESS != status )
6739 goto err_free_netdev;
6740
6741 status = hdd_register_interface( pAdapter, rtnl_held );
6742 if( VOS_STATUS_SUCCESS != status )
6743 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306744#ifdef FEATURE_WLAN_TDLS
6745 mutex_lock(&pHddCtx->tdls_lock);
6746#endif
c_hpothu002231a2015-02-05 14:58:51 +05306747 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306748#ifdef FEATURE_WLAN_TDLS
6749 mutex_unlock(&pHddCtx->tdls_lock);
6750#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 goto err_free_netdev;
6752 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306753
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306754 // Workqueue which gets scheduled in IPv4 notification callback.
6755 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6756
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306757#ifdef WLAN_NS_OFFLOAD
6758 // Workqueue which gets scheduled in IPv6 notification callback.
6759 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6760#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006761 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 netif_tx_disable(pAdapter->dev);
6764 //netif_tx_disable(pWlanDev);
6765 netif_carrier_off(pAdapter->dev);
6766
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306767 if (WLAN_HDD_P2P_CLIENT == session_type ||
6768 WLAN_HDD_P2P_DEVICE == session_type)
6769 {
6770 /* Initialize the work queue to defer the
6771 * back to back RoC request */
6772 INIT_DELAYED_WORK(&pAdapter->roc_work,
6773 hdd_p2p_roc_work_queue);
6774 }
6775
Jeff Johnson295189b2012-06-20 16:38:30 -07006776 break;
6777 }
6778
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006780 case WLAN_HDD_SOFTAP:
6781 {
6782 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6783 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306784 {
6785 hddLog(VOS_TRACE_LEVEL_FATAL,
6786 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306788 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006789
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6791 NL80211_IFTYPE_AP:
6792 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006793 pAdapter->device_mode = session_type;
6794
6795 status = hdd_init_ap_mode(pAdapter);
6796 if( VOS_STATUS_SUCCESS != status )
6797 goto err_free_netdev;
6798
6799 status = hdd_register_hostapd( pAdapter, rtnl_held );
6800 if( VOS_STATUS_SUCCESS != status )
6801 {
c_hpothu002231a2015-02-05 14:58:51 +05306802 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 goto err_free_netdev;
6804 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306805 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 netif_tx_disable(pAdapter->dev);
6807 netif_carrier_off(pAdapter->dev);
6808
6809 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306810
6811 if (WLAN_HDD_P2P_GO == session_type)
6812 {
6813 /* Initialize the work queue to
6814 * defer the back to back RoC request */
6815 INIT_DELAYED_WORK(&pAdapter->roc_work,
6816 hdd_p2p_roc_work_queue);
6817 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 break;
6819 }
6820 case WLAN_HDD_MONITOR:
6821 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6823 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306824 {
6825 hddLog(VOS_TRACE_LEVEL_FATAL,
6826 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006827 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306828 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006829
6830 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6831 pAdapter->device_mode = session_type;
6832 status = hdd_register_interface( pAdapter, rtnl_held );
6833#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6834 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6835#else
6836 pAdapter->dev->open = hdd_mon_open;
6837 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6838#endif
6839 hdd_init_tx_rx( pAdapter );
6840 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6841 //Set adapter to be used for data tx. It will use either GO or softap.
6842 pAdapter->sessionCtx.monitor.pAdapterForTx =
6843 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6845 {
6846 pAdapter->sessionCtx.monitor.pAdapterForTx =
6847 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6848 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 /* This workqueue will be used to transmit management packet over
6850 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006851 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6852 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6853 return NULL;
6854 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006855
Jeff Johnson295189b2012-06-20 16:38:30 -07006856 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6857 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006858 }
6859 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006860 case WLAN_HDD_FTM:
6861 {
6862 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6863
6864 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306865 {
6866 hddLog(VOS_TRACE_LEVEL_FATAL,
6867 FL("failed to allocate adapter for session %d"), session_type);
6868 return NULL;
6869 }
6870
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6872 * message while loading driver in FTM mode. */
6873 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6874 pAdapter->device_mode = session_type;
6875 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306876
6877 hdd_init_tx_rx( pAdapter );
6878
6879 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306880 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306881 netif_tx_disable(pAdapter->dev);
6882 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 }
6884 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006885 default:
6886 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306887 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6888 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006889 VOS_ASSERT(0);
6890 return NULL;
6891 }
6892 }
6893
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 if( VOS_STATUS_SUCCESS == status )
6895 {
6896 //Add it to the hdd's session list.
6897 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6898 if( NULL == pHddAdapterNode )
6899 {
6900 status = VOS_STATUS_E_NOMEM;
6901 }
6902 else
6903 {
6904 pHddAdapterNode->pAdapter = pAdapter;
6905 status = hdd_add_adapter_back ( pHddCtx,
6906 pHddAdapterNode );
6907 }
6908 }
6909
6910 if( VOS_STATUS_SUCCESS != status )
6911 {
6912 if( NULL != pAdapter )
6913 {
6914 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6915 pAdapter = NULL;
6916 }
6917 if( NULL != pHddAdapterNode )
6918 {
6919 vos_mem_free( pHddAdapterNode );
6920 }
6921
6922 goto resume_bmps;
6923 }
6924
6925 if(VOS_STATUS_SUCCESS == status)
6926 {
6927 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6928
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006929 //Initialize the WoWL service
6930 if(!hdd_init_wowl(pAdapter))
6931 {
6932 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6933 goto err_free_netdev;
6934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006935 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006936 return pAdapter;
6937
6938err_free_netdev:
6939 free_netdev(pAdapter->dev);
6940 wlan_hdd_release_intf_addr( pHddCtx,
6941 pAdapter->macAddressCurrent.bytes );
6942
6943resume_bmps:
6944 //If bmps disabled enable it
6945 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6946 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306947 if (pHddCtx->hdd_wlan_suspended)
6948 {
6949 hdd_set_pwrparams(pHddCtx);
6950 }
6951 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 }
6953 return NULL;
6954}
6955
6956VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6957 tANI_U8 rtnl_held )
6958{
6959 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6960 VOS_STATUS status;
6961
6962 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6963 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306964 {
6965 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6966 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306968 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006969
6970 while ( pCurrent->pAdapter != pAdapter )
6971 {
6972 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6973 if( VOS_STATUS_SUCCESS != status )
6974 break;
6975
6976 pCurrent = pNext;
6977 }
6978 pAdapterNode = pCurrent;
6979 if( VOS_STATUS_SUCCESS == status )
6980 {
6981 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6982 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306983
6984#ifdef FEATURE_WLAN_TDLS
6985
6986 /* A Mutex Lock is introduced while changing/initializing the mode to
6987 * protect the concurrent access for the Adapters by TDLS module.
6988 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306989 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306990#endif
6991
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 hdd_remove_adapter( pHddCtx, pAdapterNode );
6993 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006994 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006995
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306996#ifdef FEATURE_WLAN_TDLS
6997 mutex_unlock(&pHddCtx->tdls_lock);
6998#endif
6999
Jeff Johnson295189b2012-06-20 16:38:30 -07007000
7001 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307002 if ((!vos_concurrent_open_sessions_running()) &&
7003 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7004 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007005 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307006 if (pHddCtx->hdd_wlan_suspended)
7007 {
7008 hdd_set_pwrparams(pHddCtx);
7009 }
7010 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 }
7012
7013 return VOS_STATUS_SUCCESS;
7014 }
7015
7016 return VOS_STATUS_E_FAILURE;
7017}
7018
7019VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7020{
7021 hdd_adapter_list_node_t *pHddAdapterNode;
7022 VOS_STATUS status;
7023
7024 ENTER();
7025
7026 do
7027 {
7028 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7029 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7030 {
7031 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7032 vos_mem_free( pHddAdapterNode );
7033 }
7034 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7035
7036 EXIT();
7037
7038 return VOS_STATUS_SUCCESS;
7039}
7040
7041void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7042{
7043 v_U8_t addIE[1] = {0};
7044
7045 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7046 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7047 eANI_BOOLEAN_FALSE) )
7048 {
7049 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007050 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 }
7052
7053 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7054 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7055 eANI_BOOLEAN_FALSE) )
7056 {
7057 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007058 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 }
7060
7061 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7062 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7063 eANI_BOOLEAN_FALSE) )
7064 {
7065 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007066 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007067 }
7068}
7069
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307070VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7071 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007072{
7073 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7074 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307075 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307077 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307078 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007079
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307080 if (pHddCtx->isLogpInProgress) {
7081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7082 "%s:LOGP in Progress. Ignore!!!",__func__);
7083 return VOS_STATUS_E_FAILURE;
7084 }
7085
Jeff Johnson295189b2012-06-20 16:38:30 -07007086 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307087
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307088 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 switch(pAdapter->device_mode)
7090 {
7091 case WLAN_HDD_INFRA_STATION:
7092 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007093 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307094 {
7095 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7096 if( hdd_connIsConnected(pstation) ||
7097 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307099#ifdef FEATURE_WLAN_TDLS
7100 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307101 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307102 mutex_unlock(&pHddCtx->tdls_lock);
7103#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7105 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7106 pAdapter->sessionId,
7107 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7108 else
7109 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7110 pAdapter->sessionId,
7111 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7112 //success implies disconnect command got queued up successfully
7113 if(halStatus == eHAL_STATUS_SUCCESS)
7114 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307115 ret = wait_for_completion_interruptible_timeout(
7116 &pAdapter->disconnect_comp_var,
7117 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7118 if (ret <= 0)
7119 {
7120 hddLog(VOS_TRACE_LEVEL_ERROR,
7121 "%s: wait on disconnect_comp_var failed %ld",
7122 __func__, ret);
7123 }
7124 }
7125 else
7126 {
7127 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7128 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007129 }
7130 memset(&wrqu, '\0', sizeof(wrqu));
7131 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7132 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7133 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7134 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307135 else if(pstation->conn_info.connState ==
7136 eConnectionState_Disconnecting)
7137 {
7138 ret = wait_for_completion_interruptible_timeout(
7139 &pAdapter->disconnect_comp_var,
7140 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7141 if (ret <= 0)
7142 {
7143 hddLog(VOS_TRACE_LEVEL_ERROR,
7144 FL("wait on disconnect_comp_var failed %ld"), ret);
7145 }
7146 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307147 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007148 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307149 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307150 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307152 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7153 {
7154 while (pAdapter->is_roc_inprogress)
7155 {
7156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7157 "%s: ROC in progress for session %d!!!",
7158 __func__, pAdapter->sessionId);
7159 // waiting for ROC to expire
7160 msleep(500);
7161 /* In GO present case , if retry exceeds 3,
7162 it means something went wrong. */
7163 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7164 {
7165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7166 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307167 if (eHAL_STATUS_SUCCESS !=
7168 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7169 pAdapter->sessionId ))
7170 {
7171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7172 FL("Failed to Cancel Remain on Channel"));
7173 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307174 wait_for_completion_interruptible_timeout(
7175 &pAdapter->cancel_rem_on_chan_var,
7176 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7177 break;
7178 }
7179 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307180#ifdef WLAN_OPEN_SOURCE
7181 cancel_delayed_work_sync(&pAdapter->roc_work);
7182#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307183 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307184#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307185#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307186 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7187#endif
7188#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307189
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307190#ifdef WLAN_OPEN_SOURCE
7191 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7192#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307193
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307194 /* It is possible that the caller of this function does not
7195 * wish to close the session
7196 */
7197 if (VOS_TRUE == bCloseSession &&
7198 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007199 {
7200 INIT_COMPLETION(pAdapter->session_close_comp_var);
7201 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307202 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7203 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007204 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307205 unsigned long ret;
7206
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307208 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307209 &pAdapter->session_close_comp_var,
7210 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307211 if ( 0 >= ret)
7212 {
7213 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307214 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307215 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 }
7217 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307218 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 break;
7220
7221 case WLAN_HDD_SOFTAP:
7222 case WLAN_HDD_P2P_GO:
7223 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307224 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7225 while (pAdapter->is_roc_inprogress) {
7226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7227 "%s: ROC in progress for session %d!!!",
7228 __func__, pAdapter->sessionId);
7229 msleep(500);
7230 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7232 "%s: ROC completion is not received.!!!", __func__);
7233 WLANSAP_CancelRemainOnChannel(
7234 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7235 wait_for_completion_interruptible_timeout(
7236 &pAdapter->cancel_rem_on_chan_var,
7237 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7238 break;
7239 }
7240 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307241
7242#ifdef WLAN_OPEN_SOURCE
7243 cancel_delayed_work_sync(&pAdapter->roc_work);
7244#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307245 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007246 mutex_lock(&pHddCtx->sap_lock);
7247 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7248 {
7249 VOS_STATUS status;
7250 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7251
7252 //Stop Bss.
7253 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7254 if (VOS_IS_STATUS_SUCCESS(status))
7255 {
7256 hdd_hostapd_state_t *pHostapdState =
7257 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7258
7259 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7260
7261 if (!VOS_IS_STATUS_SUCCESS(status))
7262 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307263 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7264 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007265 }
7266 }
7267 else
7268 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007269 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007270 }
7271 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307272 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007273
7274 if (eHAL_STATUS_FAILURE ==
7275 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7276 0, NULL, eANI_BOOLEAN_FALSE))
7277 {
7278 hddLog(LOGE,
7279 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007280 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007281 }
7282
7283 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7284 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7285 eANI_BOOLEAN_FALSE) )
7286 {
7287 hddLog(LOGE,
7288 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7289 }
7290
7291 // Reset WNI_CFG_PROBE_RSP Flags
7292 wlan_hdd_reset_prob_rspies(pAdapter);
7293 kfree(pAdapter->sessionCtx.ap.beacon);
7294 pAdapter->sessionCtx.ap.beacon = NULL;
7295 }
7296 mutex_unlock(&pHddCtx->sap_lock);
7297 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007298
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007300#ifdef WLAN_OPEN_SOURCE
7301 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7302#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007304
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 default:
7306 break;
7307 }
7308
7309 EXIT();
7310 return VOS_STATUS_SUCCESS;
7311}
7312
7313VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7314{
7315 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7316 VOS_STATUS status;
7317 hdd_adapter_t *pAdapter;
7318
7319 ENTER();
7320
7321 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7322
7323 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7324 {
7325 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007326
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307327 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007328
7329 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7330 pAdapterNode = pNext;
7331 }
7332
7333 EXIT();
7334
7335 return VOS_STATUS_SUCCESS;
7336}
7337
Rajeev Kumarf999e582014-01-09 17:33:29 -08007338
7339#ifdef FEATURE_WLAN_BATCH_SCAN
7340/**---------------------------------------------------------------------------
7341
7342 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7343 structures
7344
7345 \param - pAdapter Pointer to HDD adapter
7346
7347 \return - None
7348
7349 --------------------------------------------------------------------------*/
7350void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7351{
7352 tHddBatchScanRsp *pNode;
7353 tHddBatchScanRsp *pPrev;
7354
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307355 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007356 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307357 hddLog(VOS_TRACE_LEVEL_ERROR,
7358 "%s: Adapter context is Null", __func__);
7359 return;
7360 }
7361
7362 pNode = pAdapter->pBatchScanRsp;
7363 while (pNode)
7364 {
7365 pPrev = pNode;
7366 pNode = pNode->pNext;
7367 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007368 }
7369
7370 pAdapter->pBatchScanRsp = NULL;
7371 pAdapter->numScanList = 0;
7372 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7373 pAdapter->prev_batch_id = 0;
7374
7375 return;
7376}
7377#endif
7378
7379
Jeff Johnson295189b2012-06-20 16:38:30 -07007380VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7381{
7382 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7383 VOS_STATUS status;
7384 hdd_adapter_t *pAdapter;
7385
7386 ENTER();
7387
7388 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7389
7390 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7391 {
7392 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307393 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007394 netif_tx_disable(pAdapter->dev);
7395 netif_carrier_off(pAdapter->dev);
7396
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007397 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7398
Jeff Johnson295189b2012-06-20 16:38:30 -07007399 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307400
7401 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7402
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307403 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7404 {
7405 hdd_wmm_adapter_close( pAdapter );
7406 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007408
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307409 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7410 {
7411 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7412 }
7413
Rajeev Kumarf999e582014-01-09 17:33:29 -08007414#ifdef FEATURE_WLAN_BATCH_SCAN
7415 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7416 {
7417 hdd_deinit_batch_scan(pAdapter);
7418 }
7419#endif
7420
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307421#ifdef FEATURE_WLAN_TDLS
7422 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307423 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307424 mutex_unlock(&pHddCtx->tdls_lock);
7425#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7427 pAdapterNode = pNext;
7428 }
7429
7430 EXIT();
7431
7432 return VOS_STATUS_SUCCESS;
7433}
7434
7435VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7436{
7437 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7438 VOS_STATUS status;
7439 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307440 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007441
7442 ENTER();
7443
7444 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7445
7446 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7447 {
7448 pAdapter = pAdapterNode->pAdapter;
7449
Kumar Anand82c009f2014-05-29 00:29:42 -07007450 hdd_wmm_init( pAdapter );
7451
Jeff Johnson295189b2012-06-20 16:38:30 -07007452 switch(pAdapter->device_mode)
7453 {
7454 case WLAN_HDD_INFRA_STATION:
7455 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007456 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307457
7458 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7459
Jeff Johnson295189b2012-06-20 16:38:30 -07007460 hdd_init_station_mode(pAdapter);
7461 /* Open the gates for HDD to receive Wext commands */
7462 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007463 pHddCtx->scan_info.mScanPending = FALSE;
7464 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007465
7466 //Trigger the initial scan
7467 hdd_wlan_initial_scan(pAdapter);
7468
7469 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307470 if (eConnectionState_Associated == connState ||
7471 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007472 {
7473 union iwreq_data wrqu;
7474 memset(&wrqu, '\0', sizeof(wrqu));
7475 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7476 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7477 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007478 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007479
Jeff Johnson295189b2012-06-20 16:38:30 -07007480 /* indicate disconnected event to nl80211 */
7481 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7482 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007483 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307484 else if (eConnectionState_Connecting == connState)
7485 {
7486 /*
7487 * Indicate connect failure to supplicant if we were in the
7488 * process of connecting
7489 */
7490 cfg80211_connect_result(pAdapter->dev, NULL,
7491 NULL, 0, NULL, 0,
7492 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7493 GFP_KERNEL);
7494 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 break;
7496
7497 case WLAN_HDD_SOFTAP:
7498 /* softAP can handle SSR */
7499 break;
7500
7501 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007504 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 break;
7506
7507 case WLAN_HDD_MONITOR:
7508 /* monitor interface start */
7509 break;
7510 default:
7511 break;
7512 }
7513
7514 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7515 pAdapterNode = pNext;
7516 }
7517
7518 EXIT();
7519
7520 return VOS_STATUS_SUCCESS;
7521}
7522
7523VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7524{
7525 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7526 hdd_adapter_t *pAdapter;
7527 VOS_STATUS status;
7528 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307529 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007530
7531 ENTER();
7532
7533 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7534
7535 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7536 {
7537 pAdapter = pAdapterNode->pAdapter;
7538
7539 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7540 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7541 {
7542 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7543 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7544
Abhishek Singhf4669da2014-05-26 15:07:49 +05307545 hddLog(VOS_TRACE_LEVEL_INFO,
7546 "%s: Set HDD connState to eConnectionState_NotConnected",
7547 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7549 init_completion(&pAdapter->disconnect_comp_var);
7550 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7551 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7552
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307553 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007554 &pAdapter->disconnect_comp_var,
7555 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307556 if (0 >= ret)
7557 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7558 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007559
7560 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7561 pHddCtx->isAmpAllowed = VOS_FALSE;
7562 sme_RoamConnect(pHddCtx->hHal,
7563 pAdapter->sessionId, &(pWextState->roamProfile),
7564 &roamId);
7565 }
7566
7567 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7568 pAdapterNode = pNext;
7569 }
7570
7571 EXIT();
7572
7573 return VOS_STATUS_SUCCESS;
7574}
7575
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007576void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7577{
7578 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7579 VOS_STATUS status;
7580 hdd_adapter_t *pAdapter;
7581 hdd_station_ctx_t *pHddStaCtx;
7582 hdd_ap_ctx_t *pHddApCtx;
7583 hdd_hostapd_state_t * pHostapdState;
7584 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7585 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7586 const char *p2pMode = "DEV";
7587 const char *ccMode = "Standalone";
7588 int n;
7589
7590 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7591 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7592 {
7593 pAdapter = pAdapterNode->pAdapter;
7594 switch (pAdapter->device_mode) {
7595 case WLAN_HDD_INFRA_STATION:
7596 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7597 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7598 staChannel = pHddStaCtx->conn_info.operationChannel;
7599 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7600 }
7601 break;
7602 case WLAN_HDD_P2P_CLIENT:
7603 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7604 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7605 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7606 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7607 p2pMode = "CLI";
7608 }
7609 break;
7610 case WLAN_HDD_P2P_GO:
7611 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7612 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7613 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7614 p2pChannel = pHddApCtx->operatingChannel;
7615 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7616 }
7617 p2pMode = "GO";
7618 break;
7619 case WLAN_HDD_SOFTAP:
7620 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7621 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7622 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7623 apChannel = pHddApCtx->operatingChannel;
7624 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7625 }
7626 break;
7627 default:
7628 break;
7629 }
7630 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7631 pAdapterNode = pNext;
7632 }
7633 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7634 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7635 }
7636 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7637 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7638 if (p2pChannel > 0) {
7639 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7640 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7641 }
7642 if (apChannel > 0) {
7643 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7644 apChannel, MAC_ADDR_ARRAY(apBssid));
7645 }
7646
7647 if (p2pChannel > 0 && apChannel > 0) {
7648 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7649 }
7650}
7651
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007652bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007653{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007654 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007655}
7656
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007657/* Once SSR is disabled then it cannot be set. */
7658void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007659{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007660 if (HDD_SSR_DISABLED == isSsrRequired)
7661 return;
7662
Jeff Johnson295189b2012-06-20 16:38:30 -07007663 isSsrRequired = value;
7664}
7665
7666VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7667 hdd_adapter_list_node_t** ppAdapterNode)
7668{
7669 VOS_STATUS status;
7670 spin_lock(&pHddCtx->hddAdapters.lock);
7671 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7672 (hdd_list_node_t**) ppAdapterNode );
7673 spin_unlock(&pHddCtx->hddAdapters.lock);
7674 return status;
7675}
7676
7677VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7678 hdd_adapter_list_node_t* pAdapterNode,
7679 hdd_adapter_list_node_t** pNextAdapterNode)
7680{
7681 VOS_STATUS status;
7682 spin_lock(&pHddCtx->hddAdapters.lock);
7683 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7684 (hdd_list_node_t*) pAdapterNode,
7685 (hdd_list_node_t**)pNextAdapterNode );
7686
7687 spin_unlock(&pHddCtx->hddAdapters.lock);
7688 return status;
7689}
7690
7691VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7692 hdd_adapter_list_node_t* pAdapterNode)
7693{
7694 VOS_STATUS status;
7695 spin_lock(&pHddCtx->hddAdapters.lock);
7696 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7697 &pAdapterNode->node );
7698 spin_unlock(&pHddCtx->hddAdapters.lock);
7699 return status;
7700}
7701
7702VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7703 hdd_adapter_list_node_t** ppAdapterNode)
7704{
7705 VOS_STATUS status;
7706 spin_lock(&pHddCtx->hddAdapters.lock);
7707 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7708 (hdd_list_node_t**) ppAdapterNode );
7709 spin_unlock(&pHddCtx->hddAdapters.lock);
7710 return status;
7711}
7712
7713VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7714 hdd_adapter_list_node_t* pAdapterNode)
7715{
7716 VOS_STATUS status;
7717 spin_lock(&pHddCtx->hddAdapters.lock);
7718 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7719 (hdd_list_node_t*) pAdapterNode );
7720 spin_unlock(&pHddCtx->hddAdapters.lock);
7721 return status;
7722}
7723
7724VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7725 hdd_adapter_list_node_t* pAdapterNode)
7726{
7727 VOS_STATUS status;
7728 spin_lock(&pHddCtx->hddAdapters.lock);
7729 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7730 (hdd_list_node_t*) pAdapterNode );
7731 spin_unlock(&pHddCtx->hddAdapters.lock);
7732 return status;
7733}
7734
7735hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7736 tSirMacAddr macAddr )
7737{
7738 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7739 hdd_adapter_t *pAdapter;
7740 VOS_STATUS status;
7741
7742 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7743
7744 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7745 {
7746 pAdapter = pAdapterNode->pAdapter;
7747
7748 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7749 macAddr, sizeof(tSirMacAddr) ) )
7750 {
7751 return pAdapter;
7752 }
7753 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7754 pAdapterNode = pNext;
7755 }
7756
7757 return NULL;
7758
7759}
7760
7761hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7762{
7763 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7764 hdd_adapter_t *pAdapter;
7765 VOS_STATUS status;
7766
7767 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7768
7769 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7770 {
7771 pAdapter = pAdapterNode->pAdapter;
7772
7773 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7774 IFNAMSIZ ) )
7775 {
7776 return pAdapter;
7777 }
7778 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7779 pAdapterNode = pNext;
7780 }
7781
7782 return NULL;
7783
7784}
7785
7786hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7787{
7788 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7789 hdd_adapter_t *pAdapter;
7790 VOS_STATUS status;
7791
7792 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7793
7794 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7795 {
7796 pAdapter = pAdapterNode->pAdapter;
7797
7798 if( pAdapter && (mode == pAdapter->device_mode) )
7799 {
7800 return pAdapter;
7801 }
7802 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7803 pAdapterNode = pNext;
7804 }
7805
7806 return NULL;
7807
7808}
7809
7810//Remove this function later
7811hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7812{
7813 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7814 hdd_adapter_t *pAdapter;
7815 VOS_STATUS status;
7816
7817 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7818
7819 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7820 {
7821 pAdapter = pAdapterNode->pAdapter;
7822
7823 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7824 {
7825 return pAdapter;
7826 }
7827
7828 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7829 pAdapterNode = pNext;
7830 }
7831
7832 return NULL;
7833
7834}
7835
Jeff Johnson295189b2012-06-20 16:38:30 -07007836/**---------------------------------------------------------------------------
7837
7838 \brief hdd_set_monitor_tx_adapter() -
7839
7840 This API initializes the adapter to be used while transmitting on monitor
7841 adapter.
7842
7843 \param - pHddCtx - Pointer to the HDD context.
7844 pAdapter - Adapter that will used for TX. This can be NULL.
7845 \return - None.
7846 --------------------------------------------------------------------------*/
7847void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7848{
7849 hdd_adapter_t *pMonAdapter;
7850
7851 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7852
7853 if( NULL != pMonAdapter )
7854 {
7855 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7856 }
7857}
Jeff Johnson295189b2012-06-20 16:38:30 -07007858/**---------------------------------------------------------------------------
7859
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307860 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007861
7862 This API returns the operating channel of the requested device mode
7863
7864 \param - pHddCtx - Pointer to the HDD context.
7865 - mode - Device mode for which operating channel is required
7866 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7867 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7868 \return - channel number. "0" id the requested device is not found OR it is not connected.
7869 --------------------------------------------------------------------------*/
7870v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7871{
7872 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7873 VOS_STATUS status;
7874 hdd_adapter_t *pAdapter;
7875 v_U8_t operatingChannel = 0;
7876
7877 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7878
7879 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7880 {
7881 pAdapter = pAdapterNode->pAdapter;
7882
7883 if( mode == pAdapter->device_mode )
7884 {
7885 switch(pAdapter->device_mode)
7886 {
7887 case WLAN_HDD_INFRA_STATION:
7888 case WLAN_HDD_P2P_CLIENT:
7889 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7890 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7891 break;
7892 case WLAN_HDD_SOFTAP:
7893 case WLAN_HDD_P2P_GO:
7894 /*softap connection info */
7895 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7896 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7897 break;
7898 default:
7899 break;
7900 }
7901
7902 break; //Found the device of interest. break the loop
7903 }
7904
7905 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7906 pAdapterNode = pNext;
7907 }
7908 return operatingChannel;
7909}
7910
7911#ifdef WLAN_FEATURE_PACKET_FILTERING
7912/**---------------------------------------------------------------------------
7913
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307914 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007915
7916 This used to set the multicast address list.
7917
7918 \param - dev - Pointer to the WLAN device.
7919 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307920 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07007921
7922 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307923static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007924{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307925 hdd_adapter_t *pAdapter;
7926 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007927 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307928 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007929 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307930
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307931 ENTER();
7932
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307933 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307934 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 {
7936 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307937 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007938 return;
7939 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307940 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7941 ret = wlan_hdd_validate_context(pHddCtx);
7942 if (0 != ret)
7943 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307944 return;
7945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007946 if (dev->flags & IFF_ALLMULTI)
7947 {
7948 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007949 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307950 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307952 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 {
7954 mc_count = netdev_mc_count(dev);
7955 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007956 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007957 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7958 {
7959 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007960 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307961 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 return;
7963 }
7964
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307965 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007966
7967 netdev_for_each_mc_addr(ha, dev) {
7968 if (i == mc_count)
7969 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307970 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7971 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007972 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307973 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307974 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 i++;
7976 }
7977 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307978
7979 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 return;
7981}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307982
7983static void hdd_set_multicast_list(struct net_device *dev)
7984{
7985 vos_ssr_protect(__func__);
7986 __hdd_set_multicast_list(dev);
7987 vos_ssr_unprotect(__func__);
7988}
Jeff Johnson295189b2012-06-20 16:38:30 -07007989#endif
7990
7991/**---------------------------------------------------------------------------
7992
7993 \brief hdd_select_queue() -
7994
7995 This function is registered with the Linux OS for network
7996 core to decide which queue to use first.
7997
7998 \param - dev - Pointer to the WLAN device.
7999 - skb - Pointer to OS packet (sk_buff).
8000 \return - ac, Queue Index/access category corresponding to UP in IP header
8001
8002 --------------------------------------------------------------------------*/
8003v_U16_t hdd_select_queue(struct net_device *dev,
8004 struct sk_buff *skb)
8005{
8006 return hdd_wmm_select_queue(dev, skb);
8007}
8008
8009
8010/**---------------------------------------------------------------------------
8011
8012 \brief hdd_wlan_initial_scan() -
8013
8014 This function triggers the initial scan
8015
8016 \param - pAdapter - Pointer to the HDD adapter.
8017
8018 --------------------------------------------------------------------------*/
8019void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8020{
8021 tCsrScanRequest scanReq;
8022 tCsrChannelInfo channelInfo;
8023 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008024 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008025 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8026
8027 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8028 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8029 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8030
8031 if(sme_Is11dSupported(pHddCtx->hHal))
8032 {
8033 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8034 if ( HAL_STATUS_SUCCESS( halStatus ) )
8035 {
8036 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8037 if( !scanReq.ChannelInfo.ChannelList )
8038 {
8039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8040 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008041 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008042 return;
8043 }
8044 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8045 channelInfo.numOfChannels);
8046 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8047 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008048 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 }
8050
8051 scanReq.scanType = eSIR_PASSIVE_SCAN;
8052 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8053 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8054 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8055 }
8056 else
8057 {
8058 scanReq.scanType = eSIR_ACTIVE_SCAN;
8059 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8060 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8061 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8062 }
8063
8064 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8065 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8066 {
8067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8068 __func__, halStatus );
8069 }
8070
8071 if(sme_Is11dSupported(pHddCtx->hHal))
8072 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8073}
8074
Jeff Johnson295189b2012-06-20 16:38:30 -07008075/**---------------------------------------------------------------------------
8076
8077 \brief hdd_full_power_callback() - HDD full power callback function
8078
8079 This is the function invoked by SME to inform the result of a full power
8080 request issued by HDD
8081
8082 \param - callbackcontext - Pointer to cookie
8083 \param - status - result of request
8084
8085 \return - None
8086
8087 --------------------------------------------------------------------------*/
8088static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8089{
Jeff Johnson72a40512013-12-19 10:14:15 -08008090 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008091
8092 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308093 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008094
8095 if (NULL == callbackContext)
8096 {
8097 hddLog(VOS_TRACE_LEVEL_ERROR,
8098 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008099 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 return;
8101 }
8102
Jeff Johnson72a40512013-12-19 10:14:15 -08008103 /* there is a race condition that exists between this callback
8104 function and the caller since the caller could time out either
8105 before or while this code is executing. we use a spinlock to
8106 serialize these actions */
8107 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008108
8109 if (POWER_CONTEXT_MAGIC != pContext->magic)
8110 {
8111 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008112 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008113 hddLog(VOS_TRACE_LEVEL_WARN,
8114 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008115 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 return;
8117 }
8118
Jeff Johnson72a40512013-12-19 10:14:15 -08008119 /* context is valid so caller is still waiting */
8120
8121 /* paranoia: invalidate the magic */
8122 pContext->magic = 0;
8123
8124 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008126
8127 /* serialization is complete */
8128 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008129}
8130
8131/**---------------------------------------------------------------------------
8132
8133 \brief hdd_wlan_exit() - HDD WLAN exit function
8134
8135 This is the driver exit point (invoked during rmmod)
8136
8137 \param - pHddCtx - Pointer to the HDD Context
8138
8139 \return - None
8140
8141 --------------------------------------------------------------------------*/
8142void hdd_wlan_exit(hdd_context_t *pHddCtx)
8143{
8144 eHalStatus halStatus;
8145 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8146 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308147 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008148 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008149 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308151 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008152
8153 ENTER();
8154
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308155#ifdef WLAN_NS_OFFLOAD
8156 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8157 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8158#endif
8159 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8160 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8161
Jeff Johnson88ba7742013-02-27 14:36:02 -08008162 if (VOS_FTM_MODE != hdd_get_conparam())
8163 {
Katya Nigamdc373382015-02-25 18:52:19 +05308164 /* This will issue a dump command which will clean up
8165 BTQM queues and unblock MC thread */
8166 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
8167
Jeff Johnson88ba7742013-02-27 14:36:02 -08008168 // Unloading, restart logic is no more required.
8169 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008170
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308171#ifdef FEATURE_WLAN_TDLS
8172 /* At the time of driver unloading; if tdls connection is present;
8173 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8174 * wlan_hdd_tdls_find_peer always checks for valid context;
8175 * as load/unload in progress there can be a race condition.
8176 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8177 * when tdls state is enabled.
8178 * As soon as driver set load/unload flag; tdls flag also needs
8179 * to be disabled so that hdd_rx_packet_cbk won't call
8180 * wlan_hdd_tdls_find_peer.
8181 */
8182 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8183#endif
8184
c_hpothu5ab05e92014-06-13 17:34:05 +05308185 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8186 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008187 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308188 pAdapter = pAdapterNode->pAdapter;
8189 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308191 /* Disable TX on the interface, after this hard_start_xmit() will
8192 * not be called on that interface
8193 */
8194 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8195 netif_tx_disable(pAdapter->dev);
8196
8197 /* Mark the interface status as "down" for outside world */
8198 netif_carrier_off(pAdapter->dev);
8199
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308200 /* DeInit the adapter. This ensures that all data packets
8201 * are freed.
8202 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308203#ifdef FEATURE_WLAN_TDLS
8204 mutex_lock(&pHddCtx->tdls_lock);
8205#endif
c_hpothu002231a2015-02-05 14:58:51 +05308206 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308207#ifdef FEATURE_WLAN_TDLS
8208 mutex_unlock(&pHddCtx->tdls_lock);
8209#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308210
c_hpothu5ab05e92014-06-13 17:34:05 +05308211 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8212 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8213 {
8214 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8215 hdd_UnregisterWext(pAdapter->dev);
8216 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308217
Jeff Johnson295189b2012-06-20 16:38:30 -07008218 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308219 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8220 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008221 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308222 // Cancel any outstanding scan requests. We are about to close all
8223 // of our adapters, but an adapter structure is what SME passes back
8224 // to our callback function. Hence if there are any outstanding scan
8225 // requests then there is a race condition between when the adapter
8226 // is closed and when the callback is invoked.We try to resolve that
8227 // race condition here by canceling any outstanding scans before we
8228 // close the adapters.
8229 // Note that the scans may be cancelled in an asynchronous manner,
8230 // so ideally there needs to be some kind of synchronization. Rather
8231 // than introduce a new synchronization here, we will utilize the
8232 // fact that we are about to Request Full Power, and since that is
8233 // synchronized, the expectation is that by the time Request Full
8234 // Power has completed all scans will be cancelled.
8235 if (pHddCtx->scan_info.mScanPending)
8236 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308237 if(NULL != pAdapter)
8238 {
8239 hddLog(VOS_TRACE_LEVEL_INFO,
8240 FL("abort scan mode: %d sessionId: %d"),
8241 pAdapter->device_mode,
8242 pAdapter->sessionId);
8243 }
8244 hdd_abort_mac_scan(pHddCtx,
8245 pHddCtx->scan_info.sessionId,
8246 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308247 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008248 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308249 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008250 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308251 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308252 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8253 {
8254 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8256 "%s: in middle of FTM START", __func__);
8257 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8258 msecs_to_jiffies(20000));
8259 if(!lrc)
8260 {
8261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8262 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8263 }
8264 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008265 wlan_hdd_ftm_close(pHddCtx);
8266 goto free_hdd_ctx;
8267 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308268
Jeff Johnson295189b2012-06-20 16:38:30 -07008269 /* DeRegister with platform driver as client for Suspend/Resume */
8270 vosStatus = hddDeregisterPmOps(pHddCtx);
8271 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8272 {
8273 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8274 VOS_ASSERT(0);
8275 }
8276
8277 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8278 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8279 {
8280 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8281 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008282
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008283 //Stop the traffic monitor timer
8284 if ( VOS_TIMER_STATE_RUNNING ==
8285 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8286 {
8287 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8288 }
8289
8290 // Destroy the traffic monitor timer
8291 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8292 &pHddCtx->tx_rx_trafficTmr)))
8293 {
8294 hddLog(VOS_TRACE_LEVEL_ERROR,
8295 "%s: Cannot deallocate Traffic monitor timer", __func__);
8296 }
8297
Jeff Johnson295189b2012-06-20 16:38:30 -07008298 //Disable IMPS/BMPS as we do not want the device to enter any power
8299 //save mode during shutdown
8300 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8301 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8302 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8303
8304 //Ensure that device is in full power as we will touch H/W during vos_Stop
8305 init_completion(&powerContext.completion);
8306 powerContext.magic = POWER_CONTEXT_MAGIC;
8307
8308 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8309 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8310
8311 if (eHAL_STATUS_SUCCESS != halStatus)
8312 {
8313 if (eHAL_STATUS_PMC_PENDING == halStatus)
8314 {
8315 /* request was sent -- wait for the response */
8316 lrc = wait_for_completion_interruptible_timeout(
8317 &powerContext.completion,
8318 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 if (lrc <= 0)
8320 {
8321 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008322 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008323 }
8324 }
8325 else
8326 {
8327 hddLog(VOS_TRACE_LEVEL_ERROR,
8328 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008329 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008330 /* continue -- need to clean up as much as possible */
8331 }
8332 }
8333
Jeff Johnson72a40512013-12-19 10:14:15 -08008334 /* either we never sent a request, we sent a request and received a
8335 response or we sent a request and timed out. if we never sent a
8336 request or if we sent a request and got a response, we want to
8337 clear the magic out of paranoia. if we timed out there is a
8338 race condition such that the callback function could be
8339 executing at the same time we are. of primary concern is if the
8340 callback function had already verified the "magic" but had not
8341 yet set the completion variable when a timeout occurred. we
8342 serialize these activities by invalidating the magic while
8343 holding a shared spinlock which will cause us to block if the
8344 callback is currently executing */
8345 spin_lock(&hdd_context_lock);
8346 powerContext.magic = 0;
8347 spin_unlock(&hdd_context_lock);
8348
Yue Ma0d4891e2013-08-06 17:01:45 -07008349 hdd_debugfs_exit(pHddCtx);
8350
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 // Unregister the Net Device Notifier
8352 unregister_netdevice_notifier(&hdd_netdev_notifier);
8353
Jeff Johnson295189b2012-06-20 16:38:30 -07008354 hdd_stop_all_adapters( pHddCtx );
8355
Jeff Johnson295189b2012-06-20 16:38:30 -07008356#ifdef WLAN_BTAMP_FEATURE
8357 vosStatus = WLANBAP_Stop(pVosContext);
8358 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8359 {
8360 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8361 "%s: Failed to stop BAP",__func__);
8362 }
8363#endif //WLAN_BTAMP_FEATURE
8364
8365 //Stop all the modules
8366 vosStatus = vos_stop( pVosContext );
8367 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8368 {
8369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8370 "%s: Failed to stop VOSS",__func__);
8371 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8372 }
8373
Jeff Johnson295189b2012-06-20 16:38:30 -07008374 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008375 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008376
8377 //Close the scheduler before calling vos_close to make sure no thread is
8378 // scheduled after the each module close is called i.e after all the data
8379 // structures are freed.
8380 vosStatus = vos_sched_close( pVosContext );
8381 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8382 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8383 "%s: Failed to close VOSS Scheduler",__func__);
8384 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8385 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008386#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008387#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8388 /* Destroy the wake lock */
8389 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8390#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008391 /* Destroy the wake lock */
8392 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008393#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008394
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308395#ifdef CONFIG_ENABLE_LINUX_REG
8396 vosStatus = vos_nv_close();
8397 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8398 {
8399 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8400 "%s: Failed to close NV", __func__);
8401 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8402 }
8403#endif
8404
Jeff Johnson295189b2012-06-20 16:38:30 -07008405 //Close VOSS
8406 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8407 vos_close(pVosContext);
8408
Jeff Johnson295189b2012-06-20 16:38:30 -07008409 //Close Watchdog
8410 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8411 vos_watchdog_close(pVosContext);
8412
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308413 //Clean up HDD Nlink Service
8414 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308415
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308416#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308417 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308418 {
8419 wlan_logging_sock_deactivate_svc();
8420 }
8421#endif
8422
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308423#ifdef WLAN_KD_READY_NOTIFIER
8424 nl_srv_exit(pHddCtx->ptt_pid);
8425#else
8426 nl_srv_exit();
8427#endif /* WLAN_KD_READY_NOTIFIER */
8428
8429
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 hdd_close_all_adapters( pHddCtx );
8431
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 /* free the power on lock from platform driver */
8433 if (free_riva_power_on_lock("wlan"))
8434 {
8435 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8436 __func__);
8437 }
8438
Jeff Johnson88ba7742013-02-27 14:36:02 -08008439free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308440
8441 //Free up dynamically allocated members inside HDD Adapter
8442 if (pHddCtx->cfg_ini)
8443 {
8444 kfree(pHddCtx->cfg_ini);
8445 pHddCtx->cfg_ini= NULL;
8446 }
8447
Leo Changf04ddad2013-09-18 13:46:38 -07008448 /* FTM mode, WIPHY did not registered
8449 If un-register here, system crash will happen */
8450 if (VOS_FTM_MODE != hdd_get_conparam())
8451 {
8452 wiphy_unregister(wiphy) ;
8453 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 if (hdd_is_ssr_required())
8456 {
8457 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008458 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008459 msleep(5000);
8460 }
8461 hdd_set_ssr_required (VOS_FALSE);
8462}
8463
8464
8465/**---------------------------------------------------------------------------
8466
8467 \brief hdd_update_config_from_nv() - Function to update the contents of
8468 the running configuration with parameters taken from NV storage
8469
8470 \param - pHddCtx - Pointer to the HDD global context
8471
8472 \return - VOS_STATUS_SUCCESS if successful
8473
8474 --------------------------------------------------------------------------*/
8475static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8476{
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 v_BOOL_t itemIsValid = VOS_FALSE;
8478 VOS_STATUS status;
8479 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8480 v_U8_t macLoop;
8481
8482 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8483 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8484 if(status != VOS_STATUS_SUCCESS)
8485 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008486 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 return VOS_STATUS_E_FAILURE;
8488 }
8489
8490 if (itemIsValid == VOS_TRUE)
8491 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008492 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008493 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8494 VOS_MAX_CONCURRENCY_PERSONA);
8495 if(status != VOS_STATUS_SUCCESS)
8496 {
8497 /* Get MAC from NV fail, not update CFG info
8498 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008499 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008500 return VOS_STATUS_E_FAILURE;
8501 }
8502
8503 /* If first MAC is not valid, treat all others are not valid
8504 * Then all MACs will be got from ini file */
8505 if(vos_is_macaddr_zero(&macFromNV[0]))
8506 {
8507 /* MAC address in NV file is not configured yet */
8508 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8509 return VOS_STATUS_E_INVAL;
8510 }
8511
8512 /* Get MAC address from NV, update CFG info */
8513 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8514 {
8515 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8516 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308517 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008518 /* This MAC is not valid, skip it
8519 * This MAC will be got from ini file */
8520 }
8521 else
8522 {
8523 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8524 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8525 VOS_MAC_ADDR_SIZE);
8526 }
8527 }
8528 }
8529 else
8530 {
8531 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8532 return VOS_STATUS_E_FAILURE;
8533 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008534
Jeff Johnson295189b2012-06-20 16:38:30 -07008535
8536 return VOS_STATUS_SUCCESS;
8537}
8538
8539/**---------------------------------------------------------------------------
8540
8541 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8542
8543 \param - pAdapter - Pointer to the HDD
8544
8545 \return - None
8546
8547 --------------------------------------------------------------------------*/
8548VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8549{
8550 eHalStatus halStatus;
8551 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308552 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008553
Jeff Johnson295189b2012-06-20 16:38:30 -07008554
8555 // Send ready indication to the HDD. This will kick off the MAC
8556 // into a 'running' state and should kick off an initial scan.
8557 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8558 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8559 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308560 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008561 "code %08d [x%08x]",__func__, halStatus, halStatus );
8562 return VOS_STATUS_E_FAILURE;
8563 }
8564
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308565 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008566 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8567 // And RIVA will crash
8568 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8569 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308570 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8571 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8572
8573
Jeff Johnson295189b2012-06-20 16:38:30 -07008574 return VOS_STATUS_SUCCESS;
8575}
8576
Jeff Johnson295189b2012-06-20 16:38:30 -07008577/* wake lock APIs for HDD */
8578void hdd_prevent_suspend(void)
8579{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008580#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008581 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008582#else
8583 wcnss_prevent_suspend();
8584#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008585}
8586
8587void hdd_allow_suspend(void)
8588{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008589#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008590 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008591#else
8592 wcnss_allow_suspend();
8593#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008594}
8595
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308596void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008597{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008598#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008599 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008600#else
8601 /* Do nothing as there is no API in wcnss for timeout*/
8602#endif
8603}
8604
Jeff Johnson295189b2012-06-20 16:38:30 -07008605/**---------------------------------------------------------------------------
8606
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008607 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8608 information between Host and Riva
8609
8610 This function gets reported version of FW
8611 It also finds the version of Riva headers used to compile the host
8612 It compares the above two and prints a warning if they are different
8613 It gets the SW and HW version string
8614 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8615 indicating the features they support through a bitmap
8616
8617 \param - pHddCtx - Pointer to HDD context
8618
8619 \return - void
8620
8621 --------------------------------------------------------------------------*/
8622
8623void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8624{
8625
8626 tSirVersionType versionCompiled;
8627 tSirVersionType versionReported;
8628 tSirVersionString versionString;
8629 tANI_U8 fwFeatCapsMsgSupported = 0;
8630 VOS_STATUS vstatus;
8631
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008632 memset(&versionCompiled, 0, sizeof(versionCompiled));
8633 memset(&versionReported, 0, sizeof(versionReported));
8634
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008635 /* retrieve and display WCNSS version information */
8636 do {
8637
8638 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8639 &versionCompiled);
8640 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8641 {
8642 hddLog(VOS_TRACE_LEVEL_FATAL,
8643 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008644 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008645 break;
8646 }
8647
8648 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8649 &versionReported);
8650 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8651 {
8652 hddLog(VOS_TRACE_LEVEL_FATAL,
8653 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008654 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008655 break;
8656 }
8657
8658 if ((versionCompiled.major != versionReported.major) ||
8659 (versionCompiled.minor != versionReported.minor) ||
8660 (versionCompiled.version != versionReported.version) ||
8661 (versionCompiled.revision != versionReported.revision))
8662 {
8663 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8664 "Host expected %u.%u.%u.%u\n",
8665 WLAN_MODULE_NAME,
8666 (int)versionReported.major,
8667 (int)versionReported.minor,
8668 (int)versionReported.version,
8669 (int)versionReported.revision,
8670 (int)versionCompiled.major,
8671 (int)versionCompiled.minor,
8672 (int)versionCompiled.version,
8673 (int)versionCompiled.revision);
8674 }
8675 else
8676 {
8677 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8678 WLAN_MODULE_NAME,
8679 (int)versionReported.major,
8680 (int)versionReported.minor,
8681 (int)versionReported.version,
8682 (int)versionReported.revision);
8683 }
8684
8685 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8686 versionString,
8687 sizeof(versionString));
8688 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8689 {
8690 hddLog(VOS_TRACE_LEVEL_FATAL,
8691 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008692 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008693 break;
8694 }
8695
8696 pr_info("%s: WCNSS software version %s\n",
8697 WLAN_MODULE_NAME, versionString);
8698
8699 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8700 versionString,
8701 sizeof(versionString));
8702 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8703 {
8704 hddLog(VOS_TRACE_LEVEL_FATAL,
8705 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008706 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008707 break;
8708 }
8709
8710 pr_info("%s: WCNSS hardware version %s\n",
8711 WLAN_MODULE_NAME, versionString);
8712
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008713 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8714 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008715 send the message only if it the riva is 1.1
8716 minor numbers for different riva branches:
8717 0 -> (1.0)Mainline Build
8718 1 -> (1.1)Mainline Build
8719 2->(1.04) Stability Build
8720 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008721 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008722 ((versionReported.minor>=1) && (versionReported.version>=1)))
8723 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8724 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008725
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008726 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008727 {
8728#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8729 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8730 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8731#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008732 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8733 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8734 {
8735 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8736 }
8737
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008738 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008739 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008740
8741 } while (0);
8742
8743}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308744void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8745{
8746 struct sk_buff *skb;
8747 struct nlmsghdr *nlh;
8748 tAniMsgHdr *ani_hdr;
8749
8750 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8751
8752 if(skb == NULL) {
8753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8754 "%s: alloc_skb failed", __func__);
8755 return;
8756 }
8757
8758 nlh = (struct nlmsghdr *)skb->data;
8759 nlh->nlmsg_pid = 0; /* from kernel */
8760 nlh->nlmsg_flags = 0;
8761 nlh->nlmsg_seq = 0;
8762 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8763
8764 ani_hdr = NLMSG_DATA(nlh);
8765 ani_hdr->type = type;
8766
8767 switch(type) {
8768 case WLAN_SVC_SAP_RESTART_IND:
8769 ani_hdr->length = 0;
8770 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8771 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8772 break;
8773 default:
8774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8775 "Attempt to send unknown nlink message %d", type);
8776 kfree_skb(skb);
8777 return;
8778 }
8779
8780 nl_srv_bcast(skb);
8781
8782 return;
8783}
8784
8785
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008786
8787/**---------------------------------------------------------------------------
8788
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308789 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8790
8791 \param - pHddCtx - Pointer to the hdd context
8792
8793 \return - true if hardware supports 5GHz
8794
8795 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308796boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308797{
8798 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8799 * then hardware support 5Ghz.
8800 */
8801 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8802 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308803 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308804 return true;
8805 }
8806 else
8807 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308809 __func__);
8810 return false;
8811 }
8812}
8813
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308814/**---------------------------------------------------------------------------
8815
8816 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8817 generate function
8818
8819 This is generate the random mac address for WLAN interface
8820
8821 \param - pHddCtx - Pointer to HDD context
8822 idx - Start interface index to get auto
8823 generated mac addr.
8824 mac_addr - Mac address
8825
8826 \return - 0 for success, < 0 for failure
8827
8828 --------------------------------------------------------------------------*/
8829
8830static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8831 int idx, v_MACADDR_t mac_addr)
8832{
8833 int i;
8834 unsigned int serialno;
8835 serialno = wcnss_get_serial_number();
8836
8837 if (0 != serialno)
8838 {
8839 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8840 bytes of the serial number that can be used to generate
8841 the other 3 bytes of the MAC address. Mask off all but
8842 the lower 3 bytes (this will also make sure we don't
8843 overflow in the next step) */
8844 serialno &= 0x00FFFFFF;
8845
8846 /* we need a unique address for each session */
8847 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8848
8849 /* autogen other Mac addresses */
8850 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8851 {
8852 /* start with the entire default address */
8853 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8854 /* then replace the lower 3 bytes */
8855 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8856 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8857 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8858
8859 serialno++;
8860 hddLog(VOS_TRACE_LEVEL_ERROR,
8861 "%s: Derived Mac Addr: "
8862 MAC_ADDRESS_STR, __func__,
8863 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8864 }
8865
8866 }
8867 else
8868 {
8869 hddLog(LOGE, FL("Failed to Get Serial NO"));
8870 return -1;
8871 }
8872 return 0;
8873}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308874
8875/**---------------------------------------------------------------------------
8876
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308877 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8878 completed to flush out the scan results
8879
8880 11d scan is done during driver load and is a passive scan on all
8881 channels supported by the device, 11d scans may find some APs on
8882 frequencies which are forbidden to be used in the regulatory domain
8883 the device is operating in. If these APs are notified to the supplicant
8884 it may try to connect to these APs, thus flush out all the scan results
8885 which are present in SME after 11d scan is done.
8886
8887 \return - eHalStatus
8888
8889 --------------------------------------------------------------------------*/
8890static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8891 tANI_U32 scanId, eCsrScanStatus status)
8892{
8893 ENTER();
8894
8895 sme_ScanFlushResult(halHandle, 0);
8896
8897 EXIT();
8898
8899 return eHAL_STATUS_SUCCESS;
8900}
8901
8902/**---------------------------------------------------------------------------
8903
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 \brief hdd_wlan_startup() - HDD init function
8905
8906 This is the driver startup code executed once a WLAN device has been detected
8907
8908 \param - dev - Pointer to the underlying device
8909
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008910 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008911
8912 --------------------------------------------------------------------------*/
8913
8914int hdd_wlan_startup(struct device *dev )
8915{
8916 VOS_STATUS status;
8917 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008918 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008919 hdd_context_t *pHddCtx = NULL;
8920 v_CONTEXT_t pVosContext= NULL;
8921#ifdef WLAN_BTAMP_FEATURE
8922 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8923 WLANBAP_ConfigType btAmpConfig;
8924 hdd_config_t *pConfig;
8925#endif
8926 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308928 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008929
8930 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 /*
8932 * cfg80211: wiphy allocation
8933 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308934 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008935
8936 if(wiphy == NULL)
8937 {
8938 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008939 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008941 pHddCtx = wiphy_priv(wiphy);
8942
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 //Initialize the adapter context to zeros.
8944 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8945
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308948 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008949
8950 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8951
8952 /*Get vos context here bcoz vos_open requires it*/
8953 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8954
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008955 if(pVosContext == NULL)
8956 {
8957 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8958 goto err_free_hdd_context;
8959 }
8960
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 //Save the Global VOSS context in adapter context for future.
8962 pHddCtx->pvosContext = pVosContext;
8963
8964 //Save the adapter context in global context for future.
8965 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8966
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 pHddCtx->parent_dev = dev;
8968
8969 init_completion(&pHddCtx->full_pwr_comp_var);
8970 init_completion(&pHddCtx->standby_comp_var);
8971 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008972 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008973 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308974 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308975 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008976
8977#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008978 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008979#else
8980 init_completion(&pHddCtx->driver_crda_req);
8981#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008982
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308983 spin_lock_init(&pHddCtx->schedScan_lock);
8984
Jeff Johnson295189b2012-06-20 16:38:30 -07008985 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8986
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308987#ifdef FEATURE_WLAN_TDLS
8988 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8989 * invoked by other instances also) to protect the concurrent
8990 * access for the Adapters by TDLS module.
8991 */
8992 mutex_init(&pHddCtx->tdls_lock);
8993#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05308994 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05308995 mutex_init(&pHddCtx->wmmLock);
8996
Agarwal Ashish1f422872014-07-22 00:11:55 +05308997 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308998
Agarwal Ashish1f422872014-07-22 00:11:55 +05308999 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 // Load all config first as TL config is needed during vos_open
9001 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9002 if(pHddCtx->cfg_ini == NULL)
9003 {
9004 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9005 goto err_free_hdd_context;
9006 }
9007
9008 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9009
9010 // Read and parse the qcom_cfg.ini file
9011 status = hdd_parse_config_ini( pHddCtx );
9012 if ( VOS_STATUS_SUCCESS != status )
9013 {
9014 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9015 __func__, WLAN_INI_FILE);
9016 goto err_config;
9017 }
Arif Hussaind5218912013-12-05 01:10:55 -08009018#ifdef MEMORY_DEBUG
9019 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9020 vos_mem_init();
9021
9022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9023 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9024#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009025
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309026 /* INI has been read, initialise the configuredMcastBcastFilter with
9027 * INI value as this will serve as the default value
9028 */
9029 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9030 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9031 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309032
9033 if (false == hdd_is_5g_supported(pHddCtx))
9034 {
9035 //5Ghz is not supported.
9036 if (1 != pHddCtx->cfg_ini->nBandCapability)
9037 {
9038 hddLog(VOS_TRACE_LEVEL_INFO,
9039 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9040 pHddCtx->cfg_ini->nBandCapability = 1;
9041 }
9042 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309043
9044 /* If SNR Monitoring is enabled, FW has to parse all beacons
9045 * for calcaluting and storing the average SNR, so set Nth beacon
9046 * filter to 1 to enable FW to parse all the beaocons
9047 */
9048 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9049 {
9050 /* The log level is deliberately set to WARN as overriding
9051 * nthBeaconFilter to 1 will increase power cosumption and this
9052 * might just prove helpful to detect the power issue.
9053 */
9054 hddLog(VOS_TRACE_LEVEL_WARN,
9055 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9056 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9057 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309059 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009060 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009061 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009062 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009063 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9064 {
9065 hddLog(VOS_TRACE_LEVEL_FATAL,
9066 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9067 goto err_config;
9068 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009069 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009070
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009071 // Update VOS trace levels based upon the cfg.ini
9072 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9073 pHddCtx->cfg_ini->vosTraceEnableBAP);
9074 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9075 pHddCtx->cfg_ini->vosTraceEnableTL);
9076 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9077 pHddCtx->cfg_ini->vosTraceEnableWDI);
9078 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9079 pHddCtx->cfg_ini->vosTraceEnableHDD);
9080 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9081 pHddCtx->cfg_ini->vosTraceEnableSME);
9082 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9083 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309084 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9085 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009086 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9087 pHddCtx->cfg_ini->vosTraceEnableWDA);
9088 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9089 pHddCtx->cfg_ini->vosTraceEnableSYS);
9090 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9091 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009092 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9093 pHddCtx->cfg_ini->vosTraceEnableSAP);
9094 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9095 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009096
Jeff Johnson295189b2012-06-20 16:38:30 -07009097 // Update WDI trace levels based upon the cfg.ini
9098 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9099 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9100 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9101 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9102 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9103 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9104 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9105 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009106
Jeff Johnson88ba7742013-02-27 14:36:02 -08009107 if (VOS_FTM_MODE == hdd_get_conparam())
9108 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9110 {
9111 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9112 goto err_free_hdd_context;
9113 }
9114 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05309115
9116 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009119
Jeff Johnson88ba7742013-02-27 14:36:02 -08009120 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9122 {
9123 status = vos_watchdog_open(pVosContext,
9124 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9125
9126 if(!VOS_IS_STATUS_SUCCESS( status ))
9127 {
9128 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309129 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009130 }
9131 }
9132
9133 pHddCtx->isLogpInProgress = FALSE;
9134 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9135
Amar Singhala49cbc52013-10-08 18:37:44 -07009136#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009137 /* initialize the NV module. This is required so that
9138 we can initialize the channel information in wiphy
9139 from the NV.bin data. The channel information in
9140 wiphy needs to be initialized before wiphy registration */
9141
9142 status = vos_nv_open();
9143 if (!VOS_IS_STATUS_SUCCESS(status))
9144 {
9145 /* NV module cannot be initialized */
9146 hddLog( VOS_TRACE_LEVEL_FATAL,
9147 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309148 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009149 }
9150
9151 status = vos_init_wiphy_from_nv_bin();
9152 if (!VOS_IS_STATUS_SUCCESS(status))
9153 {
9154 /* NV module cannot be initialized */
9155 hddLog( VOS_TRACE_LEVEL_FATAL,
9156 "%s: vos_init_wiphy failed", __func__);
9157 goto err_vos_nv_close;
9158 }
9159
Amar Singhala49cbc52013-10-08 18:37:44 -07009160#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309161 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309162 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 if ( !VOS_IS_STATUS_SUCCESS( status ))
9164 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009165 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309166 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 }
9168
Jeff Johnson295189b2012-06-20 16:38:30 -07009169 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9170
9171 if ( NULL == pHddCtx->hHal )
9172 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009173 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009174 goto err_vosclose;
9175 }
9176
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009177 status = vos_preStart( pHddCtx->pvosContext );
9178 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9179 {
9180 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309181 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009182 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009183
Arif Hussaineaf68602013-12-30 23:10:44 -08009184 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9185 {
9186 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9188 __func__, enable_dfs_chan_scan);
9189 }
9190 if (0 == enable_11d || 1 == enable_11d)
9191 {
9192 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9193 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9194 __func__, enable_11d);
9195 }
9196
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009197 /* Note that the vos_preStart() sequence triggers the cfg download.
9198 The cfg download must occur before we update the SME config
9199 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009200 status = hdd_set_sme_config( pHddCtx );
9201
9202 if ( VOS_STATUS_SUCCESS != status )
9203 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009204 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309205 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009206 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009207
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 /* In the integrated architecture we update the configuration from
9209 the INI file and from NV before vOSS has been started so that
9210 the final contents are available to send down to the cCPU */
9211
9212 // Apply the cfg.ini to cfg.dat
9213 if (FALSE == hdd_update_config_dat(pHddCtx))
9214 {
9215 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309216 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009217 }
9218
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309219 // Get mac addr from platform driver
9220 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9221
9222 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309224 /* Store the mac addr for first interface */
9225 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9226
9227 hddLog(VOS_TRACE_LEVEL_ERROR,
9228 "%s: WLAN Mac Addr: "
9229 MAC_ADDRESS_STR, __func__,
9230 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9231
9232 /* Here, passing Arg2 as 1 because we do not want to change the
9233 last 3 bytes (means non OUI bytes) of first interface mac
9234 addr.
9235 */
9236 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9237 {
9238 hddLog(VOS_TRACE_LEVEL_ERROR,
9239 "%s: Failed to generate wlan interface mac addr "
9240 "using MAC from ini file ", __func__);
9241 }
9242 }
9243 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9244 {
9245 // Apply the NV to cfg.dat
9246 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009247#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9248 /* There was not a valid set of MAC Addresses in NV. See if the
9249 default addresses were modified by the cfg.ini settings. If so,
9250 we'll use them, but if not, we'll autogenerate a set of MAC
9251 addresses based upon the device serial number */
9252
9253 static const v_MACADDR_t default_address =
9254 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009255
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309256 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9257 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009258 {
9259 /* cfg.ini has the default address, invoke autogen logic */
9260
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309261 /* Here, passing Arg2 as 0 because we want to change the
9262 last 3 bytes (means non OUI bytes) of all the interfaces
9263 mac addr.
9264 */
9265 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9266 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009267 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309268 hddLog(VOS_TRACE_LEVEL_ERROR,
9269 "%s: Failed to generate wlan interface mac addr "
9270 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9271 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009272 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009273 }
9274 else
9275#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9276 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009277 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 "%s: Invalid MAC address in NV, using MAC from ini file "
9279 MAC_ADDRESS_STR, __func__,
9280 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9281 }
9282 }
9283 {
9284 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309285
9286 /* Set the MAC Address Currently this is used by HAL to
9287 * add self sta. Remove this once self sta is added as
9288 * part of session open.
9289 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009290 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9291 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9292 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309293
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 if (!HAL_STATUS_SUCCESS( halStatus ))
9295 {
9296 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9297 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309298 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 }
9300 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009301
9302 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9303 Note: Firmware image will be read and downloaded inside vos_start API */
9304 status = vos_start( pHddCtx->pvosContext );
9305 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9306 {
9307 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309308 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009309 }
9310
Leo Chang6cec3e22014-01-21 15:33:49 -08009311#ifdef FEATURE_WLAN_CH_AVOID
9312 /* Plug in avoid channel notification callback
9313 * This should happen before ADD_SELF_STA
9314 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309315
9316 /* check the Channel Avoidance is enabled */
9317 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9318 {
9319 sme_AddChAvoidCallback(pHddCtx->hHal,
9320 hdd_hostapd_ch_avoid_cb);
9321 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009322#endif /* FEATURE_WLAN_CH_AVOID */
9323
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009324 /* Exchange capability info between Host and FW and also get versioning info from FW */
9325 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009326
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309327#ifdef CONFIG_ENABLE_LINUX_REG
9328 status = wlan_hdd_init_channels(pHddCtx);
9329 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9330 {
9331 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9332 __func__);
9333 goto err_vosstop;
9334 }
9335#endif
9336
Jeff Johnson295189b2012-06-20 16:38:30 -07009337 status = hdd_post_voss_start_config( pHddCtx );
9338 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9339 {
9340 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9341 __func__);
9342 goto err_vosstop;
9343 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009344
9345#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309346 wlan_hdd_cfg80211_update_reg_info( wiphy );
9347
9348 /* registration of wiphy dev with cfg80211 */
9349 if (0 > wlan_hdd_cfg80211_register(wiphy))
9350 {
9351 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9352 goto err_vosstop;
9353 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009354#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009355
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309356#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309357 /* registration of wiphy dev with cfg80211 */
9358 if (0 > wlan_hdd_cfg80211_register(wiphy))
9359 {
9360 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9361 goto err_vosstop;
9362 }
9363
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309364 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309365 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9366 {
9367 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9368 __func__);
9369 goto err_unregister_wiphy;
9370 }
9371#endif
9372
c_hpothu4a298be2014-12-22 21:12:51 +05309373 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9374
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9376 {
9377 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9378 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9379 }
9380 else
9381 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009382 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9383 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9384 if (pAdapter != NULL)
9385 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309386 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309388 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9389 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9390 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009391
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309392 /* Generate the P2P Device Address. This consists of the device's
9393 * primary MAC address with the locally administered bit set.
9394 */
9395 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009396 }
9397 else
9398 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309399 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9400 if (p2p_dev_addr != NULL)
9401 {
9402 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9403 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9404 }
9405 else
9406 {
9407 hddLog(VOS_TRACE_LEVEL_FATAL,
9408 "%s: Failed to allocate mac_address for p2p_device",
9409 __func__);
9410 goto err_close_adapter;
9411 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009413
9414 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9415 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9416 if ( NULL == pP2pAdapter )
9417 {
9418 hddLog(VOS_TRACE_LEVEL_FATAL,
9419 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009420 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009421 goto err_close_adapter;
9422 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009423 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009425
9426 if( pAdapter == NULL )
9427 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9429 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009431
Arif Hussain66559122013-11-21 10:11:40 -08009432 if (country_code)
9433 {
9434 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009435 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009436 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9437#ifndef CONFIG_ENABLE_LINUX_REG
9438 hdd_checkandupdate_phymode(pAdapter, country_code);
9439#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009440 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9441 (void *)(tSmeChangeCountryCallback)
9442 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009443 country_code,
9444 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309445 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009446 if (eHAL_STATUS_SUCCESS == ret)
9447 {
Arif Hussaincb607082013-12-20 11:57:42 -08009448 ret = wait_for_completion_interruptible_timeout(
9449 &pAdapter->change_country_code,
9450 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9451
9452 if (0 >= ret)
9453 {
9454 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9455 "%s: SME while setting country code timed out", __func__);
9456 }
Arif Hussain66559122013-11-21 10:11:40 -08009457 }
9458 else
9459 {
Arif Hussaincb607082013-12-20 11:57:42 -08009460 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9461 "%s: SME Change Country code from module param fail ret=%d",
9462 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009463 }
9464 }
9465
Jeff Johnson295189b2012-06-20 16:38:30 -07009466#ifdef WLAN_BTAMP_FEATURE
9467 vStatus = WLANBAP_Open(pVosContext);
9468 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9469 {
9470 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9471 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009472 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009473 }
9474
9475 vStatus = BSL_Init(pVosContext);
9476 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9477 {
9478 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9479 "%s: Failed to Init BSL",__func__);
9480 goto err_bap_close;
9481 }
9482 vStatus = WLANBAP_Start(pVosContext);
9483 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9484 {
9485 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9486 "%s: Failed to start TL",__func__);
9487 goto err_bap_close;
9488 }
9489
9490 pConfig = pHddCtx->cfg_ini;
9491 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9492 status = WLANBAP_SetConfig(&btAmpConfig);
9493
9494#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009495
Mihir Shete9c238772014-10-15 14:35:16 +05309496 /*
9497 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9498 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9499 * which is greater than 0xf. So the below check is safe to make
9500 * sure that there is no entry for UapsdMask in the ini
9501 */
9502 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9503 {
9504 if(IS_DYNAMIC_WMM_PS_ENABLED)
9505 {
9506 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9507 __func__);
9508 pHddCtx->cfg_ini->UapsdMask =
9509 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9510 }
9511 else
9512 {
9513 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9514 __func__);
9515 pHddCtx->cfg_ini->UapsdMask =
9516 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9517 }
9518 }
9519
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009520#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9521 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9522 {
9523 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9524 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9525 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9526 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9527 }
9528#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009529
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309530 wlan_hdd_tdls_init(pHddCtx);
9531
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309532 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9533
Jeff Johnson295189b2012-06-20 16:38:30 -07009534 /* Register with platform driver as client for Suspend/Resume */
9535 status = hddRegisterPmOps(pHddCtx);
9536 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9537 {
9538 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9539#ifdef WLAN_BTAMP_FEATURE
9540 goto err_bap_stop;
9541#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009542 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009543#endif //WLAN_BTAMP_FEATURE
9544 }
9545
Yue Ma0d4891e2013-08-06 17:01:45 -07009546 /* Open debugfs interface */
9547 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9548 {
9549 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9550 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009551 }
9552
Jeff Johnson295189b2012-06-20 16:38:30 -07009553 /* Register TM level change handler function to the platform */
9554 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9555 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9556 {
9557 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9558 goto err_unregister_pmops;
9559 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009560
9561 /* register for riva power on lock to platform driver */
9562 if (req_riva_power_on_lock("wlan"))
9563 {
9564 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9565 __func__);
9566 goto err_unregister_pmops;
9567 }
9568
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 // register net device notifier for device change notification
9570 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9571
9572 if(ret < 0)
9573 {
9574 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9575 goto err_free_power_on_lock;
9576 }
9577
9578 //Initialize the nlink service
9579 if(nl_srv_init() != 0)
9580 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309581 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009582 goto err_reg_netdev;
9583 }
9584
Leo Chang4ce1cc52013-10-21 18:27:15 -07009585#ifdef WLAN_KD_READY_NOTIFIER
9586 pHddCtx->kd_nl_init = 1;
9587#endif /* WLAN_KD_READY_NOTIFIER */
9588
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 //Initialize the BTC service
9590 if(btc_activate_service(pHddCtx) != 0)
9591 {
9592 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9593 goto err_nl_srv;
9594 }
9595
9596#ifdef PTT_SOCK_SVC_ENABLE
9597 //Initialize the PTT service
9598 if(ptt_sock_activate_svc(pHddCtx) != 0)
9599 {
9600 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9601 goto err_nl_srv;
9602 }
9603#endif
9604
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309605#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9606 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9607 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309608 if(wlan_logging_sock_activate_svc(
9609 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9610 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9611 {
9612 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9613 " failed", __func__);
9614 goto err_nl_srv;
9615 }
9616 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9617 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309618 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9619 pHddCtx->cfg_ini->gEnableDebugLog =
9620 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309621 }
9622#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009625 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009626 /* Action frame registered in one adapter which will
9627 * applicable to all interfaces
9628 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309629 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009631
9632 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309633 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009634
Jeff Johnson295189b2012-06-20 16:38:30 -07009635
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009636#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009637#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9638 /* Initialize the wake lcok */
9639 wake_lock_init(&pHddCtx->rx_wake_lock,
9640 WAKE_LOCK_SUSPEND,
9641 "qcom_rx_wakelock");
9642#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009643 /* Initialize the wake lcok */
9644 wake_lock_init(&pHddCtx->sap_wake_lock,
9645 WAKE_LOCK_SUSPEND,
9646 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009647#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009648
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009649 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9650 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009651
Katya Nigam5c306ea2014-06-19 15:39:54 +05309652 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9654 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309655
9656#ifdef FEATURE_WLAN_SCAN_PNO
9657 /*SME must send channel update configuration to RIVA*/
9658 sme_UpdateChannelConfig(pHddCtx->hHal);
9659#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309660 /* Send the update default channel list to the FW*/
9661 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309662#ifndef CONFIG_ENABLE_LINUX_REG
9663 /*updating wiphy so that regulatory user hints can be processed*/
9664 if (wiphy)
9665 {
9666 regulatory_hint(wiphy, "00");
9667 }
9668#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009669 // Initialize the restart logic
9670 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309671
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009672 //Register the traffic monitor timer now
9673 if ( pHddCtx->cfg_ini->dynSplitscan)
9674 {
9675 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9676 VOS_TIMER_TYPE_SW,
9677 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9678 (void *)pHddCtx);
9679 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309680#ifdef WLAN_FEATURE_EXTSCAN
9681 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9682 wlan_hdd_cfg80211_extscan_callback,
9683 pHddCtx);
9684#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309685
9686#ifdef WLAN_NS_OFFLOAD
9687 // Register IPv6 notifier to notify if any change in IP
9688 // So that we can reconfigure the offload parameters
9689 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
9690 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
9691 if (ret)
9692 {
9693 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
9694 }
9695 else
9696 {
9697 hddLog(LOGE, FL("Registered IPv6 notifier"));
9698 }
9699#endif
9700
9701 // Register IPv4 notifier to notify if any change in IP
9702 // So that we can reconfigure the offload parameters
9703 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
9704 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
9705 if (ret)
9706 {
9707 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
9708 }
9709 else
9710 {
9711 hddLog(LOGE, FL("Registered IPv4 notifier"));
9712 }
9713
Jeff Johnson295189b2012-06-20 16:38:30 -07009714 goto success;
9715
9716err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009717#ifdef WLAN_KD_READY_NOTIFIER
9718 nl_srv_exit(pHddCtx->ptt_pid);
9719#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009720 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009721#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009722err_reg_netdev:
9723 unregister_netdevice_notifier(&hdd_netdev_notifier);
9724
9725err_free_power_on_lock:
9726 free_riva_power_on_lock("wlan");
9727
9728err_unregister_pmops:
9729 hddDevTmUnregisterNotifyCallback(pHddCtx);
9730 hddDeregisterPmOps(pHddCtx);
9731
Yue Ma0d4891e2013-08-06 17:01:45 -07009732 hdd_debugfs_exit(pHddCtx);
9733
Jeff Johnson295189b2012-06-20 16:38:30 -07009734#ifdef WLAN_BTAMP_FEATURE
9735err_bap_stop:
9736 WLANBAP_Stop(pVosContext);
9737#endif
9738
9739#ifdef WLAN_BTAMP_FEATURE
9740err_bap_close:
9741 WLANBAP_Close(pVosContext);
9742#endif
9743
Jeff Johnson295189b2012-06-20 16:38:30 -07009744err_close_adapter:
9745 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309746#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309747err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309748#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309749 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009750err_vosstop:
9751 vos_stop(pVosContext);
9752
Amar Singhala49cbc52013-10-08 18:37:44 -07009753err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009754 status = vos_sched_close( pVosContext );
9755 if (!VOS_IS_STATUS_SUCCESS(status)) {
9756 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9757 "%s: Failed to close VOSS Scheduler", __func__);
9758 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9759 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009760 vos_close(pVosContext );
9761
Amar Singhal0a402232013-10-11 20:57:16 -07009762err_vos_nv_close:
9763
c_hpothue6a36282014-03-19 12:27:38 +05309764#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009765 vos_nv_close();
9766
c_hpothu70f8d812014-03-22 22:59:23 +05309767#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009768
9769err_wdclose:
9770 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9771 vos_watchdog_close(pVosContext);
9772
Jeff Johnson295189b2012-06-20 16:38:30 -07009773err_config:
9774 kfree(pHddCtx->cfg_ini);
9775 pHddCtx->cfg_ini= NULL;
9776
9777err_free_hdd_context:
9778 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 wiphy_free(wiphy) ;
9780 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 VOS_BUG(1);
9782
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009783 if (hdd_is_ssr_required())
9784 {
9785 /* WDI timeout had happened during load, so SSR is needed here */
9786 subsystem_restart("wcnss");
9787 msleep(5000);
9788 }
9789 hdd_set_ssr_required (VOS_FALSE);
9790
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009791 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009792
9793success:
9794 EXIT();
9795 return 0;
9796}
9797
9798/**---------------------------------------------------------------------------
9799
Jeff Johnson32d95a32012-09-10 13:15:23 -07009800 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009801
Jeff Johnson32d95a32012-09-10 13:15:23 -07009802 This is the driver entry point - called in different timeline depending
9803 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009804
9805 \param - None
9806
9807 \return - 0 for success, non zero for failure
9808
9809 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009810static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009811{
9812 VOS_STATUS status;
9813 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 struct device *dev = NULL;
9815 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009816#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9817 int max_retries = 0;
9818#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309819#ifdef HAVE_CBC_DONE
9820 int max_cbc_retries = 0;
9821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009822
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309823#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9824 wlan_logging_sock_init_svc();
9825#endif
9826
Jeff Johnson295189b2012-06-20 16:38:30 -07009827 ENTER();
9828
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009829#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009830 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009831#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009832
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309833 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9835 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9836
Jeff Johnson295189b2012-06-20 16:38:30 -07009837#ifdef ANI_BUS_TYPE_PCI
9838
9839 dev = wcnss_wlan_get_device();
9840
9841#endif // ANI_BUS_TYPE_PCI
9842
9843#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009844
9845#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9846 /* wait until WCNSS driver downloads NV */
9847 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9848 msleep(1000);
9849 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309850
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009851 if (max_retries >= 5) {
9852 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309853#ifdef WLAN_OPEN_SOURCE
9854 wake_lock_destroy(&wlan_wake_lock);
9855#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309856
9857#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9858 wlan_logging_sock_deinit_svc();
9859#endif
9860
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009861 return -ENODEV;
9862 }
9863#endif
9864
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309865#ifdef HAVE_CBC_DONE
9866 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
9867 msleep(1000);
9868 }
9869 if (max_cbc_retries >= 10) {
9870 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
9871 }
9872#endif
9873
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 dev = wcnss_wlan_get_device();
9875#endif // ANI_BUS_TYPE_PLATFORM
9876
9877
9878 do {
9879 if (NULL == dev) {
9880 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9881 ret_status = -1;
9882 break;
9883 }
9884
Jeff Johnson295189b2012-06-20 16:38:30 -07009885#ifdef TIMER_MANAGER
9886 vos_timer_manager_init();
9887#endif
9888
9889 /* Preopen VOSS so that it is ready to start at least SAL */
9890 status = vos_preOpen(&pVosContext);
9891
9892 if (!VOS_IS_STATUS_SUCCESS(status))
9893 {
9894 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9895 ret_status = -1;
9896 break;
9897 }
9898
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009899#ifndef MODULE
9900 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9901 */
9902 hdd_set_conparam((v_UINT_t)con_mode);
9903#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009904
9905 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009906 if (hdd_wlan_startup(dev))
9907 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009909 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 vos_preClose( &pVosContext );
9911 ret_status = -1;
9912 break;
9913 }
9914
Jeff Johnson295189b2012-06-20 16:38:30 -07009915 } while (0);
9916
9917 if (0 != ret_status)
9918 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009919#ifdef TIMER_MANAGER
9920 vos_timer_exit();
9921#endif
9922#ifdef MEMORY_DEBUG
9923 vos_mem_exit();
9924#endif
9925
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009926#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009927 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009928#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309929
9930#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9931 wlan_logging_sock_deinit_svc();
9932#endif
9933
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9935 }
9936 else
9937 {
9938 //Send WLAN UP indication to Nlink Service
9939 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9940
9941 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 }
9943
9944 EXIT();
9945
9946 return ret_status;
9947}
9948
Jeff Johnson32d95a32012-09-10 13:15:23 -07009949/**---------------------------------------------------------------------------
9950
9951 \brief hdd_module_init() - Init Function
9952
9953 This is the driver entry point (invoked when module is loaded using insmod)
9954
9955 \param - None
9956
9957 \return - 0 for success, non zero for failure
9958
9959 --------------------------------------------------------------------------*/
9960#ifdef MODULE
9961static int __init hdd_module_init ( void)
9962{
9963 return hdd_driver_init();
9964}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009965#else /* #ifdef MODULE */
9966static int __init hdd_module_init ( void)
9967{
9968 /* Driver initialization is delayed to fwpath_changed_handler */
9969 return 0;
9970}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009971#endif /* #ifdef MODULE */
9972
Jeff Johnson295189b2012-06-20 16:38:30 -07009973
9974/**---------------------------------------------------------------------------
9975
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009976 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009977
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009978 This is the driver exit point (invoked when module is unloaded using rmmod
9979 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009980
9981 \param - None
9982
9983 \return - None
9984
9985 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009986static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009987{
9988 hdd_context_t *pHddCtx = NULL;
9989 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309990 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309991 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009992
9993 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9994
9995 //Get the global vos context
9996 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9997
9998 if(!pVosContext)
9999 {
10000 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10001 goto done;
10002 }
10003
10004 //Get the HDD context.
10005 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10006
10007 if(!pHddCtx)
10008 {
10009 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10010 }
10011 else
10012 {
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010013 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10014 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10015 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10016 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010018 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010019 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10020 msecs_to_jiffies(30000));
10021 if(!rc)
10022 {
10023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10024 "%s:SSR timedout, fatal error", __func__);
10025 VOS_BUG(0);
10026 }
10027 }
10028
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010029 rtnl_lock();
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010030 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10031 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010032 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -070010033
c_hpothu8adb97b2014-12-08 19:38:20 +053010034 /* Driver Need to send country code 00 in below condition
10035 * 1) If gCountryCodePriority is set to 1; and last country
10036 * code set is through 11d. This needs to be done in case
10037 * when NV country code is 00.
10038 * This Needs to be done as when kernel store last country
10039 * code and if stored country code is not through 11d,
10040 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10041 * in next load/unload as soon as we get any country through
10042 * 11d. In sme_HandleChangeCountryCodeByUser
10043 * pMsg->countryCode will be last countryCode and
10044 * pMac->scan.countryCode11d will be country through 11d so
10045 * due to mismatch driver will disable 11d.
10046 *
10047 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010048
c_hpothu8adb97b2014-12-08 19:38:20 +053010049 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010050 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010051 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010052 {
10053 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010054 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010055 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10056 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010057
c_hpothu8adb97b2014-12-08 19:38:20 +053010058 //Do all the cleanup before deregistering the driver
10059 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010060 }
10061
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 vos_preClose( &pVosContext );
10063
10064#ifdef TIMER_MANAGER
10065 vos_timer_exit();
10066#endif
10067#ifdef MEMORY_DEBUG
10068 vos_mem_exit();
10069#endif
10070
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010071#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10072 wlan_logging_sock_deinit_svc();
10073#endif
10074
Jeff Johnson295189b2012-06-20 16:38:30 -070010075done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010076#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010077 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010078#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010079
Jeff Johnson295189b2012-06-20 16:38:30 -070010080 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10081}
10082
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010083/**---------------------------------------------------------------------------
10084
10085 \brief hdd_module_exit() - Exit function
10086
10087 This is the driver exit point (invoked when module is unloaded using rmmod)
10088
10089 \param - None
10090
10091 \return - None
10092
10093 --------------------------------------------------------------------------*/
10094static void __exit hdd_module_exit(void)
10095{
10096 hdd_driver_exit();
10097}
10098
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010099#ifdef MODULE
10100static int fwpath_changed_handler(const char *kmessage,
10101 struct kernel_param *kp)
10102{
Jeff Johnson76052702013-04-16 13:55:05 -070010103 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010104}
10105
10106static int con_mode_handler(const char *kmessage,
10107 struct kernel_param *kp)
10108{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010109 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010110}
10111#else /* #ifdef MODULE */
10112/**---------------------------------------------------------------------------
10113
Jeff Johnson76052702013-04-16 13:55:05 -070010114 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010115
Jeff Johnson76052702013-04-16 13:55:05 -070010116 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010117 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010118 - invoked when module parameter fwpath is modified from userspace to signal
10119 initializing the WLAN driver or when con_mode is modified from userspace
10120 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010121
10122 \return - 0 for success, non zero for failure
10123
10124 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010125static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010126{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010127 int ret_status;
10128
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010129 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010130 ret_status = hdd_driver_init();
10131 wlan_hdd_inited = ret_status ? 0 : 1;
10132 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010133 }
10134
10135 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010136
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010137 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010138
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010139 ret_status = hdd_driver_init();
10140 wlan_hdd_inited = ret_status ? 0 : 1;
10141 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010142}
10143
Jeff Johnson295189b2012-06-20 16:38:30 -070010144/**---------------------------------------------------------------------------
10145
Jeff Johnson76052702013-04-16 13:55:05 -070010146 \brief fwpath_changed_handler() - Handler Function
10147
10148 Handle changes to the fwpath parameter
10149
10150 \return - 0 for success, non zero for failure
10151
10152 --------------------------------------------------------------------------*/
10153static int fwpath_changed_handler(const char *kmessage,
10154 struct kernel_param *kp)
10155{
10156 int ret;
10157
10158 ret = param_set_copystring(kmessage, kp);
10159 if (0 == ret)
10160 ret = kickstart_driver();
10161 return ret;
10162}
10163
10164/**---------------------------------------------------------------------------
10165
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010166 \brief con_mode_handler() -
10167
10168 Handler function for module param con_mode when it is changed by userspace
10169 Dynamically linked - do nothing
10170 Statically linked - exit and init driver, as in rmmod and insmod
10171
Jeff Johnson76052702013-04-16 13:55:05 -070010172 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010173
Jeff Johnson76052702013-04-16 13:55:05 -070010174 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010175
10176 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010177static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010178{
Jeff Johnson76052702013-04-16 13:55:05 -070010179 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010180
Jeff Johnson76052702013-04-16 13:55:05 -070010181 ret = param_set_int(kmessage, kp);
10182 if (0 == ret)
10183 ret = kickstart_driver();
10184 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010185}
10186#endif /* #ifdef MODULE */
10187
10188/**---------------------------------------------------------------------------
10189
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 \brief hdd_get_conparam() -
10191
10192 This is the driver exit point (invoked when module is unloaded using rmmod)
10193
10194 \param - None
10195
10196 \return - tVOS_CON_MODE
10197
10198 --------------------------------------------------------------------------*/
10199tVOS_CON_MODE hdd_get_conparam ( void )
10200{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010201#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010203#else
10204 return (tVOS_CON_MODE)curr_con_mode;
10205#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010206}
10207void hdd_set_conparam ( v_UINT_t newParam )
10208{
10209 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010210#ifndef MODULE
10211 curr_con_mode = con_mode;
10212#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010213}
10214/**---------------------------------------------------------------------------
10215
10216 \brief hdd_softap_sta_deauth() - function
10217
10218 This to take counter measure to handle deauth req from HDD
10219
10220 \param - pAdapter - Pointer to the HDD
10221
10222 \param - enable - boolean value
10223
10224 \return - None
10225
10226 --------------------------------------------------------------------------*/
10227
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010228VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10229 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010230{
Jeff Johnson295189b2012-06-20 16:38:30 -070010231 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010232 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010233
10234 ENTER();
10235
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010236 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10237 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010238
10239 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010240 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010241 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010242
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010243 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010244
10245 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010246 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010247}
10248
10249/**---------------------------------------------------------------------------
10250
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010251 \brief hdd_del_all_sta() - function
10252
10253 This function removes all the stations associated on stopping AP/P2P GO.
10254
10255 \param - pAdapter - Pointer to the HDD
10256
10257 \return - None
10258
10259 --------------------------------------------------------------------------*/
10260
10261int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10262{
10263 v_U16_t i;
10264 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010265 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10266 ptSapContext pSapCtx = NULL;
10267 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10268 if(pSapCtx == NULL){
10269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10270 FL("psapCtx is NULL"));
10271 return 1;
10272 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010273 ENTER();
10274
10275 hddLog(VOS_TRACE_LEVEL_INFO,
10276 "%s: Delete all STAs associated.",__func__);
10277 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10278 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10279 )
10280 {
10281 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10282 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010283 if ((pSapCtx->aStaInfo[i].isUsed) &&
10284 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010285 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010286 struct tagCsrDelStaParams delStaParams;
10287
10288 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010289 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010290 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10291 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010292 &delStaParams);
10293 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010294 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010295 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010296 }
10297 }
10298 }
10299
10300 EXIT();
10301 return 0;
10302}
10303
10304/**---------------------------------------------------------------------------
10305
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 \brief hdd_softap_sta_disassoc() - function
10307
10308 This to take counter measure to handle deauth req from HDD
10309
10310 \param - pAdapter - Pointer to the HDD
10311
10312 \param - enable - boolean value
10313
10314 \return - None
10315
10316 --------------------------------------------------------------------------*/
10317
10318void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10319{
10320 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10321
10322 ENTER();
10323
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010324 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010325
10326 //Ignore request to disassoc bcmc station
10327 if( pDestMacAddress[0] & 0x1 )
10328 return;
10329
10330 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10331}
10332
10333void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10334{
10335 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10336
10337 ENTER();
10338
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010339 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010340
10341 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10342}
10343
Jeff Johnson295189b2012-06-20 16:38:30 -070010344/**---------------------------------------------------------------------------
10345 *
10346 * \brief hdd_get__concurrency_mode() -
10347 *
10348 *
10349 * \param - None
10350 *
10351 * \return - CONCURRENCY MODE
10352 *
10353 * --------------------------------------------------------------------------*/
10354tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10355{
10356 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10357 hdd_context_t *pHddCtx;
10358
10359 if (NULL != pVosContext)
10360 {
10361 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10362 if (NULL != pHddCtx)
10363 {
10364 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10365 }
10366 }
10367
10368 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010369 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010370 return VOS_STA;
10371}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010372v_BOOL_t
10373wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10374{
10375 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010376
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010377 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10378 if (pAdapter == NULL)
10379 {
10380 hddLog(VOS_TRACE_LEVEL_INFO,
10381 FL("GO doesn't exist"));
10382 return TRUE;
10383 }
10384 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10385 {
10386 hddLog(VOS_TRACE_LEVEL_INFO,
10387 FL("GO started"));
10388 return TRUE;
10389 }
10390 else
10391 /* wait till GO changes its interface to p2p device */
10392 hddLog(VOS_TRACE_LEVEL_INFO,
10393 FL("Del_bss called, avoid apps suspend"));
10394 return FALSE;
10395
10396}
Jeff Johnson295189b2012-06-20 16:38:30 -070010397/* Decide whether to allow/not the apps power collapse.
10398 * Allow apps power collapse if we are in connected state.
10399 * if not, allow only if we are in IMPS */
10400v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10401{
10402 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010403 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010404 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010405 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10406 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10407 hdd_adapter_t *pAdapter = NULL;
10408 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010409 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010410
Jeff Johnson295189b2012-06-20 16:38:30 -070010411 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10412 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010413
Yathish9f22e662012-12-10 14:21:35 -080010414 concurrent_state = hdd_get_concurrency_mode();
10415
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010416 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10417 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10418 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010419#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010420
Yathish9f22e662012-12-10 14:21:35 -080010421 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010422 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010423 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10424 return TRUE;
10425#endif
10426
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 /*loop through all adapters. TBD fix for Concurrency */
10428 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10429 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10430 {
10431 pAdapter = pAdapterNode->pAdapter;
10432 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10433 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10434 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010435 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010436 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010437 && pmcState != STOPPED && pmcState != STANDBY &&
10438 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010439 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10440 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010442 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010443 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10444 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010445 return FALSE;
10446 }
10447 }
10448 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10449 pAdapterNode = pNext;
10450 }
10451 return TRUE;
10452}
10453
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010454/* Decides whether to send suspend notification to Riva
10455 * if any adapter is in BMPS; then it is required */
10456v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10457{
10458 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10459 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10460
10461 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10462 {
10463 return TRUE;
10464 }
10465 return FALSE;
10466}
10467
Jeff Johnson295189b2012-06-20 16:38:30 -070010468void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10469{
10470 switch(mode)
10471 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010472 case VOS_STA_MODE:
10473 case VOS_P2P_CLIENT_MODE:
10474 case VOS_P2P_GO_MODE:
10475 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010476 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010477 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 break;
10479 default:
10480 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010482 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10483 "Number of open sessions for mode %d = %d"),
10484 pHddCtx->concurrency_mode, mode,
10485 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010486}
10487
10488
10489void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10490{
10491 switch(mode)
10492 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010493 case VOS_STA_MODE:
10494 case VOS_P2P_CLIENT_MODE:
10495 case VOS_P2P_GO_MODE:
10496 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010497 pHddCtx->no_of_open_sessions[mode]--;
10498 if (!(pHddCtx->no_of_open_sessions[mode]))
10499 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010500 break;
10501 default:
10502 break;
10503 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010504 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10505 "Number of open sessions for mode %d = %d"),
10506 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10507
10508}
10509/**---------------------------------------------------------------------------
10510 *
10511 * \brief wlan_hdd_incr_active_session()
10512 *
10513 * This function increments the number of active sessions
10514 * maintained per device mode
10515 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10516 * Incase of SAP/P2P GO upon bss start it is incremented
10517 *
10518 * \param pHddCtx - HDD Context
10519 * \param mode - device mode
10520 *
10521 * \return - None
10522 *
10523 * --------------------------------------------------------------------------*/
10524void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10525{
10526 switch (mode) {
10527 case VOS_STA_MODE:
10528 case VOS_P2P_CLIENT_MODE:
10529 case VOS_P2P_GO_MODE:
10530 case VOS_STA_SAP_MODE:
10531 pHddCtx->no_of_active_sessions[mode]++;
10532 break;
10533 default:
10534 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10535 break;
10536 }
10537 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10538 mode,
10539 pHddCtx->no_of_active_sessions[mode]);
10540}
10541
10542/**---------------------------------------------------------------------------
10543 *
10544 * \brief wlan_hdd_decr_active_session()
10545 *
10546 * This function decrements the number of active sessions
10547 * maintained per device mode
10548 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10549 * Incase of SAP/P2P GO upon bss stop it is decremented
10550 *
10551 * \param pHddCtx - HDD Context
10552 * \param mode - device mode
10553 *
10554 * \return - None
10555 *
10556 * --------------------------------------------------------------------------*/
10557void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10558{
10559 switch (mode) {
10560 case VOS_STA_MODE:
10561 case VOS_P2P_CLIENT_MODE:
10562 case VOS_P2P_GO_MODE:
10563 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010564 if (pHddCtx->no_of_active_sessions[mode] > 0)
10565 pHddCtx->no_of_active_sessions[mode]--;
10566 else
10567 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10568 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010569 break;
10570 default:
10571 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10572 break;
10573 }
10574 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10575 mode,
10576 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010577}
10578
Jeff Johnsone7245742012-09-05 17:12:55 -070010579/**---------------------------------------------------------------------------
10580 *
10581 * \brief wlan_hdd_restart_init
10582 *
10583 * This function initalizes restart timer/flag. An internal function.
10584 *
10585 * \param - pHddCtx
10586 *
10587 * \return - None
10588 *
10589 * --------------------------------------------------------------------------*/
10590
10591static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10592{
10593 /* Initialize */
10594 pHddCtx->hdd_restart_retries = 0;
10595 atomic_set(&pHddCtx->isRestartInProgress, 0);
10596 vos_timer_init(&pHddCtx->hdd_restart_timer,
10597 VOS_TIMER_TYPE_SW,
10598 wlan_hdd_restart_timer_cb,
10599 pHddCtx);
10600}
10601/**---------------------------------------------------------------------------
10602 *
10603 * \brief wlan_hdd_restart_deinit
10604 *
10605 * This function cleans up the resources used. An internal function.
10606 *
10607 * \param - pHddCtx
10608 *
10609 * \return - None
10610 *
10611 * --------------------------------------------------------------------------*/
10612
10613static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10614{
10615
10616 VOS_STATUS vos_status;
10617 /* Block any further calls */
10618 atomic_set(&pHddCtx->isRestartInProgress, 1);
10619 /* Cleanup */
10620 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10621 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010622 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010623 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10624 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010625 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010626
10627}
10628
10629/**---------------------------------------------------------------------------
10630 *
10631 * \brief wlan_hdd_framework_restart
10632 *
10633 * This function uses a cfg80211 API to start a framework initiated WLAN
10634 * driver module unload/load.
10635 *
10636 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10637 *
10638 *
10639 * \param - pHddCtx
10640 *
10641 * \return - VOS_STATUS_SUCCESS: Success
10642 * VOS_STATUS_E_EMPTY: Adapter is Empty
10643 * VOS_STATUS_E_NOMEM: No memory
10644
10645 * --------------------------------------------------------------------------*/
10646
10647static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10648{
10649 VOS_STATUS status = VOS_STATUS_SUCCESS;
10650 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010651 int len = (sizeof (struct ieee80211_mgmt));
10652 struct ieee80211_mgmt *mgmt = NULL;
10653
10654 /* Prepare the DEAUTH managment frame with reason code */
10655 mgmt = kzalloc(len, GFP_KERNEL);
10656 if(mgmt == NULL)
10657 {
10658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10659 "%s: memory allocation failed (%d bytes)", __func__, len);
10660 return VOS_STATUS_E_NOMEM;
10661 }
10662 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010663
10664 /* Iterate over all adapters/devices */
10665 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10666 do
10667 {
10668 if( (status == VOS_STATUS_SUCCESS) &&
10669 pAdapterNode &&
10670 pAdapterNode->pAdapter)
10671 {
10672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10673 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10674 pAdapterNode->pAdapter->dev->name,
10675 pAdapterNode->pAdapter->device_mode,
10676 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010677 /*
10678 * CFG80211 event to restart the driver
10679 *
10680 * 'cfg80211_send_unprot_deauth' sends a
10681 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10682 * of SME(Linux Kernel) state machine.
10683 *
10684 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10685 * the driver.
10686 *
10687 */
10688
10689 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010690 }
10691 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10692 pAdapterNode = pNext;
10693 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10694
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010695
10696 /* Free the allocated management frame */
10697 kfree(mgmt);
10698
Jeff Johnsone7245742012-09-05 17:12:55 -070010699 /* Retry until we unload or reach max count */
10700 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10701 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10702
10703 return status;
10704
10705}
10706/**---------------------------------------------------------------------------
10707 *
10708 * \brief wlan_hdd_restart_timer_cb
10709 *
10710 * Restart timer callback. An internal function.
10711 *
10712 * \param - User data:
10713 *
10714 * \return - None
10715 *
10716 * --------------------------------------------------------------------------*/
10717
10718void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10719{
10720 hdd_context_t *pHddCtx = usrDataForCallback;
10721 wlan_hdd_framework_restart(pHddCtx);
10722 return;
10723
10724}
10725
10726
10727/**---------------------------------------------------------------------------
10728 *
10729 * \brief wlan_hdd_restart_driver
10730 *
10731 * This function sends an event to supplicant to restart the WLAN driver.
10732 *
10733 * This function is called from vos_wlanRestart.
10734 *
10735 * \param - pHddCtx
10736 *
10737 * \return - VOS_STATUS_SUCCESS: Success
10738 * VOS_STATUS_E_EMPTY: Adapter is Empty
10739 * VOS_STATUS_E_ALREADY: Request already in progress
10740
10741 * --------------------------------------------------------------------------*/
10742VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10743{
10744 VOS_STATUS status = VOS_STATUS_SUCCESS;
10745
10746 /* A tight check to make sure reentrancy */
10747 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10748 {
Mihir Shetefd528652014-06-23 19:07:50 +053010749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010750 "%s: WLAN restart is already in progress", __func__);
10751
10752 return VOS_STATUS_E_ALREADY;
10753 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010754 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010755#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010756 wcnss_reset_intr();
10757#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010758
Jeff Johnsone7245742012-09-05 17:12:55 -070010759 return status;
10760}
10761
Mihir Shetee1093ba2014-01-21 20:13:32 +053010762/**---------------------------------------------------------------------------
10763 *
10764 * \brief wlan_hdd_init_channels
10765 *
10766 * This function is used to initialize the channel list in CSR
10767 *
10768 * This function is called from hdd_wlan_startup
10769 *
10770 * \param - pHddCtx: HDD context
10771 *
10772 * \return - VOS_STATUS_SUCCESS: Success
10773 * VOS_STATUS_E_FAULT: Failure reported by SME
10774
10775 * --------------------------------------------------------------------------*/
10776static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10777{
10778 eHalStatus status;
10779
10780 status = sme_InitChannels(pHddCtx->hHal);
10781 if (HAL_STATUS_SUCCESS(status))
10782 {
10783 return VOS_STATUS_SUCCESS;
10784 }
10785 else
10786 {
10787 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10788 __func__, status);
10789 return VOS_STATUS_E_FAULT;
10790 }
10791}
10792
Mihir Shete04206452014-11-20 17:50:58 +053010793#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010794VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010795{
10796 eHalStatus status;
10797
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010798 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010799 if (HAL_STATUS_SUCCESS(status))
10800 {
10801 return VOS_STATUS_SUCCESS;
10802 }
10803 else
10804 {
10805 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10806 __func__, status);
10807 return VOS_STATUS_E_FAULT;
10808 }
10809}
Mihir Shete04206452014-11-20 17:50:58 +053010810#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010811/*
10812 * API to find if there is any STA or P2P-Client is connected
10813 */
10814VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10815{
10816 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10817}
Jeff Johnsone7245742012-09-05 17:12:55 -070010818
Agarwal Ashish57e84372014-12-05 18:26:53 +053010819/*
10820 * API to find if there is any session connected
10821 */
10822VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
10823{
10824 return sme_is_any_session_connected(pHddCtx->hHal);
10825}
10826
10827
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010828int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10829{
10830 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10831 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010832 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053010833 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010834
10835 pScanInfo = &pHddCtx->scan_info;
10836 if (pScanInfo->mScanPending)
10837 {
c_hpothua3d45d52015-01-05 14:11:17 +053010838 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
10839 eCSR_SCAN_ABORT_DEFAULT);
10840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10841 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010842
c_hpothua3d45d52015-01-05 14:11:17 +053010843 /* If there is active scan command lets wait for the completion else
10844 * there is no need to wait as scan command might be in the SME pending
10845 * command list.
10846 */
10847 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
10848 {
10849 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10850 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010851 &pScanInfo->abortscan_event_var,
10852 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053010853 if (0 >= status)
10854 {
10855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010856 "%s: Timeout or Interrupt occurred while waiting for abort"
10857 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053010858 return -ETIMEDOUT;
10859 }
10860 }
10861 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
10862 {
10863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10864 FL("hdd_abort_mac_scan failed"));
10865 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010866 }
10867 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010868 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010869}
10870
c_hpothu225aa7c2014-10-22 17:45:13 +053010871VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10872{
10873 hdd_adapter_t *pAdapter;
10874 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10875 VOS_STATUS vosStatus;
10876
10877 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10878 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10879 {
10880 pAdapter = pAdapterNode->pAdapter;
10881 if (NULL != pAdapter)
10882 {
10883 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10884 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10885 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10886 {
10887 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10888 pAdapter->device_mode);
10889 if (VOS_STATUS_SUCCESS !=
10890 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10891 {
10892 hddLog(LOGE, FL("failed to abort ROC"));
10893 return VOS_STATUS_E_FAILURE;
10894 }
10895 }
10896 }
10897 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10898 pAdapterNode = pNext;
10899 }
10900 return VOS_STATUS_SUCCESS;
10901}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053010902
Mihir Shete0be28772015-02-17 18:42:14 +053010903hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
10904{
10905 hdd_adapter_t *pAdapter;
10906 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10907 hdd_cfg80211_state_t *cfgState;
10908 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
10909 VOS_STATUS vosStatus;
10910
10911 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
10912 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10913 {
10914 pAdapter = pAdapterNode->pAdapter;
10915 if (NULL != pAdapter)
10916 {
10917 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
10918 pRemainChanCtx = cfgState->remain_on_chan_ctx;
10919 if (pRemainChanCtx)
10920 break;
10921 }
10922 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
10923 pAdapterNode = pNext;
10924 }
10925 return pRemainChanCtx;
10926}
10927
Jeff Johnson295189b2012-06-20 16:38:30 -070010928//Register the module init/exit functions
10929module_init(hdd_module_init);
10930module_exit(hdd_module_exit);
10931
10932MODULE_LICENSE("Dual BSD/GPL");
10933MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10934MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10935
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010936module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10937 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010938
Jeff Johnson76052702013-04-16 13:55:05 -070010939module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010940 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010941
10942module_param(enable_dfs_chan_scan, int,
10943 S_IRUSR | S_IRGRP | S_IROTH);
10944
10945module_param(enable_11d, int,
10946 S_IRUSR | S_IRGRP | S_IROTH);
10947
10948module_param(country_code, charp,
10949 S_IRUSR | S_IRGRP | S_IROTH);