blob: 2036505bfa3c4be3449fa5756829fc4adaa83da2 [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
Katya Nigam1fd24402015-02-16 14:52:19 +05306035void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
6036{
6037 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6038 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
6039 #else
6040 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
6041 #endif
6042}
6043
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006044static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006045{
6046 struct net_device *pWlanDev = NULL;
6047 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006048 /*
6049 * cfg80211 initialization and registration....
6050 */
6051 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6052
Jeff Johnson295189b2012-06-20 16:38:30 -07006053 if(pWlanDev != NULL)
6054 {
6055
6056 //Save the pointer to the net_device in the HDD adapter
6057 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6058
Jeff Johnson295189b2012-06-20 16:38:30 -07006059 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6060
6061 pAdapter->dev = pWlanDev;
6062 pAdapter->pHddCtx = pHddCtx;
6063 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306064 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006065
6066 init_completion(&pAdapter->session_open_comp_var);
6067 init_completion(&pAdapter->session_close_comp_var);
6068 init_completion(&pAdapter->disconnect_comp_var);
6069 init_completion(&pAdapter->linkup_event_var);
6070 init_completion(&pAdapter->cancel_rem_on_chan_var);
6071 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306072 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006073#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6074 init_completion(&pAdapter->offchannel_tx_event);
6075#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006076 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006077#ifdef FEATURE_WLAN_TDLS
6078 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006079 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006080 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306081 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006082#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006083 init_completion(&pHddCtx->mc_sus_event_var);
6084 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306085 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006086 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006087 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006088
Rajeev79dbe4c2013-10-05 11:03:42 +05306089#ifdef FEATURE_WLAN_BATCH_SCAN
6090 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6091 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6092 pAdapter->pBatchScanRsp = NULL;
6093 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006094 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006095 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306096 mutex_init(&pAdapter->hdd_batch_scan_lock);
6097#endif
6098
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 pAdapter->isLinkUpSvcNeeded = FALSE;
6100 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6101 //Init the net_device structure
6102 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6103
6104 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6105 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6106 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6107 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6108
6109 hdd_set_station_ops( pAdapter->dev );
6110
6111 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006112 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6113 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6114 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 /* set pWlanDev's parent to underlying device */
6116 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006117
6118 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 }
6120
6121 return pAdapter;
6122}
6123
6124VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6125{
6126 struct net_device *pWlanDev = pAdapter->dev;
6127 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6128 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6129 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6130
6131 if( rtnl_lock_held )
6132 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006133 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006134 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6135 {
6136 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6137 return VOS_STATUS_E_FAILURE;
6138 }
6139 }
6140 if (register_netdevice(pWlanDev))
6141 {
6142 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6143 return VOS_STATUS_E_FAILURE;
6144 }
6145 }
6146 else
6147 {
6148 if(register_netdev(pWlanDev))
6149 {
6150 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6151 return VOS_STATUS_E_FAILURE;
6152 }
6153 }
6154 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6155
6156 return VOS_STATUS_SUCCESS;
6157}
6158
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006159static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006160{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006161 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006162
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006163 if (NULL == pAdapter)
6164 {
6165 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6166 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006168
6169 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6170 {
6171 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6172 return eHAL_STATUS_NOT_INITIALIZED;
6173 }
6174
6175 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6176
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006177#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006178 /* need to make sure all of our scheduled work has completed.
6179 * This callback is called from MC thread context, so it is safe to
6180 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006181 *
6182 * Even though this is called from MC thread context, if there is a faulty
6183 * work item in the system, that can hang this call forever. So flushing
6184 * this global work queue is not safe; and now we make sure that
6185 * individual work queues are stopped correctly. But the cancel work queue
6186 * is a GPL only API, so the proprietary version of the driver would still
6187 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006188 */
6189 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006190#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006191
6192 /* We can be blocked while waiting for scheduled work to be
6193 * flushed, and the adapter structure can potentially be freed, in
6194 * which case the magic will have been reset. So make sure the
6195 * magic is still good, and hence the adapter structure is still
6196 * valid, before signaling completion */
6197 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6198 {
6199 complete(&pAdapter->session_close_comp_var);
6200 }
6201
Jeff Johnson295189b2012-06-20 16:38:30 -07006202 return eHAL_STATUS_SUCCESS;
6203}
6204
6205VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6206{
6207 struct net_device *pWlanDev = pAdapter->dev;
6208 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6209 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6210 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6211 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306212 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006213
6214 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006215 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 //Open a SME session for future operation
6217 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006218 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006219 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6220 {
6221 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006222 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 halStatus, halStatus );
6224 status = VOS_STATUS_E_FAILURE;
6225 goto error_sme_open;
6226 }
6227
6228 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306229 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006230 &pAdapter->session_open_comp_var,
6231 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306232 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006233 {
6234 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306235 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 status = VOS_STATUS_E_FAILURE;
6237 goto error_sme_open;
6238 }
6239
6240 // Register wireless extensions
6241 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6242 {
6243 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006244 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006245 halStatus, halStatus );
6246 status = VOS_STATUS_E_FAILURE;
6247 goto error_register_wext;
6248 }
Katya Nigam1fd24402015-02-16 14:52:19 +05306249
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05306251 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6252 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6253 #else
6254 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6255 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006256
6257 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306258 hddLog(VOS_TRACE_LEVEL_INFO,
6259 "%s: Set HDD connState to eConnectionState_NotConnected",
6260 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006261 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6262
6263 //Set the default operation channel
6264 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6265
6266 /* Make the default Auth Type as OPEN*/
6267 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6268
6269 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6270 {
6271 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006272 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 status, status );
6274 goto error_init_txrx;
6275 }
6276
6277 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6278
6279 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6280 {
6281 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006282 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006283 status, status );
6284 goto error_wmm_init;
6285 }
6286
6287 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6288
6289 return VOS_STATUS_SUCCESS;
6290
6291error_wmm_init:
6292 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6293 hdd_deinit_tx_rx(pAdapter);
6294error_init_txrx:
6295 hdd_UnregisterWext(pWlanDev);
6296error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006297 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 {
6299 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006300 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006301 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006302 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306304 unsigned long rc;
6305
Jeff Johnson295189b2012-06-20 16:38:30 -07006306 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306307 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006309 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306310 if (rc <= 0)
6311 hddLog(VOS_TRACE_LEVEL_ERROR,
6312 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 }
6314}
6315error_sme_open:
6316 return status;
6317}
6318
Jeff Johnson295189b2012-06-20 16:38:30 -07006319void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6320{
6321 hdd_cfg80211_state_t *cfgState;
6322
6323 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6324
6325 if( NULL != cfgState->buf )
6326 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306327 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6329 rc = wait_for_completion_interruptible_timeout(
6330 &pAdapter->tx_action_cnf_event,
6331 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306332 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306335 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6336 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 }
6338 }
6339 return;
6340}
Jeff Johnson295189b2012-06-20 16:38:30 -07006341
c_hpothu002231a2015-02-05 14:58:51 +05306342void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006343{
6344 ENTER();
6345 switch ( pAdapter->device_mode )
6346 {
Katya Nigam1fd24402015-02-16 14:52:19 +05306347 case WLAN_HDD_IBSS:
6348 {
6349 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6350 {
6351 hdd_ibss_deinit_tx_rx( pAdapter );
6352 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6353 }
6354 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 case WLAN_HDD_INFRA_STATION:
6356 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006357 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 {
6359 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6360 {
6361 hdd_deinit_tx_rx( pAdapter );
6362 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6363 }
6364
6365 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6366 {
6367 hdd_wmm_adapter_close( pAdapter );
6368 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6369 }
6370
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 break;
6373 }
6374
6375 case WLAN_HDD_SOFTAP:
6376 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306378
6379 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6380 {
6381 hdd_wmm_adapter_close( pAdapter );
6382 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6383 }
6384
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006386
c_hpothu002231a2015-02-05 14:58:51 +05306387 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006388 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 break;
6391 }
6392
6393 case WLAN_HDD_MONITOR:
6394 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006396 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6397 {
6398 hdd_deinit_tx_rx( pAdapter );
6399 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6400 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006401 if(NULL != pAdapterforTx)
6402 {
6403 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6404 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 break;
6406 }
6407
6408
6409 default:
6410 break;
6411 }
6412
6413 EXIT();
6414}
6415
6416void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6417{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006418 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306419
6420 ENTER();
6421 if (NULL == pAdapter)
6422 {
6423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6424 "%s: HDD adapter is Null", __func__);
6425 return;
6426 }
6427
6428 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006429
Rajeev79dbe4c2013-10-05 11:03:42 +05306430#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306431 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6432 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006433 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306434 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6435 )
6436 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006437 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306438 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006439 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6440 {
6441 hdd_deinit_batch_scan(pAdapter);
6442 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306443 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006444 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306445#endif
6446
Jeff Johnson295189b2012-06-20 16:38:30 -07006447 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6448 if( rtnl_held )
6449 {
6450 unregister_netdevice(pWlanDev);
6451 }
6452 else
6453 {
6454 unregister_netdev(pWlanDev);
6455 }
6456 // note that the pAdapter is no longer valid at this point
6457 // since the memory has been reclaimed
6458 }
6459
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306460 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006461}
6462
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006463void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6464{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306465 VOS_STATUS status;
6466 hdd_adapter_t *pAdapter = NULL;
6467 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006468
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306469 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006470
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306471 /*loop through all adapters.*/
6472 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006473 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306474 pAdapter = pAdapterNode->pAdapter;
6475 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6476 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006477
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306478 { // we skip this registration for modes other than STA and P2P client modes.
6479 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6480 pAdapterNode = pNext;
6481 continue;
6482 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006483
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306484 //Apply Dynamic DTIM For P2P
6485 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6486 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6487 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6488 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6489 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6490 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6491 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6492 (eConnectionState_Associated ==
6493 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6494 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6495 {
6496 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006497
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306498 powerRequest.uIgnoreDTIM = 1;
6499 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6500
6501 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6502 {
6503 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6504 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6505 }
6506 else
6507 {
6508 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6509 }
6510
6511 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6512 * specified during Enter/Exit BMPS when LCD off*/
6513 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6514 NULL, eANI_BOOLEAN_FALSE);
6515 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6516 NULL, eANI_BOOLEAN_FALSE);
6517
6518 /* switch to the DTIM specified in cfg.ini */
6519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6520 "Switch to DTIM %d", powerRequest.uListenInterval);
6521 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6522 break;
6523
6524 }
6525
6526 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6527 pAdapterNode = pNext;
6528 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006529}
6530
6531void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6532{
6533 /*Switch back to DTIM 1*/
6534 tSirSetPowerParamsReq powerRequest = { 0 };
6535
6536 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6537 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006538 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006539
6540 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6541 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6542 NULL, eANI_BOOLEAN_FALSE);
6543 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6544 NULL, eANI_BOOLEAN_FALSE);
6545
6546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6547 "Switch to DTIM%d",powerRequest.uListenInterval);
6548 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6549
6550}
6551
Jeff Johnson295189b2012-06-20 16:38:30 -07006552VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6553{
6554 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306555 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6556 {
6557 hddLog( LOGE, FL("Wlan Unload in progress"));
6558 return VOS_STATUS_E_PERM;
6559 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6561 {
6562 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6563 }
6564
6565 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6566 {
6567 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6568 }
6569
6570 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6571 {
6572 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6573 }
6574
6575 return status;
6576}
6577
6578VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6579{
6580 hdd_adapter_t *pAdapter = NULL;
6581 eHalStatus halStatus;
6582 VOS_STATUS status = VOS_STATUS_E_INVAL;
6583 v_BOOL_t disableBmps = FALSE;
6584 v_BOOL_t disableImps = FALSE;
6585
6586 switch(session_type)
6587 {
6588 case WLAN_HDD_INFRA_STATION:
6589 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006590 case WLAN_HDD_P2P_CLIENT:
6591 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 //Exit BMPS -> Is Sta/P2P Client is already connected
6593 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6594 if((NULL != pAdapter)&&
6595 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6596 {
6597 disableBmps = TRUE;
6598 }
6599
6600 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6601 if((NULL != pAdapter)&&
6602 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6603 {
6604 disableBmps = TRUE;
6605 }
6606
6607 //Exit both Bmps and Imps incase of Go/SAP Mode
6608 if((WLAN_HDD_SOFTAP == session_type) ||
6609 (WLAN_HDD_P2P_GO == session_type))
6610 {
6611 disableBmps = TRUE;
6612 disableImps = TRUE;
6613 }
6614
6615 if(TRUE == disableImps)
6616 {
6617 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6618 {
6619 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6620 }
6621 }
6622
6623 if(TRUE == disableBmps)
6624 {
6625 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6626 {
6627 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6628
6629 if(eHAL_STATUS_SUCCESS != halStatus)
6630 {
6631 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006632 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006633 VOS_ASSERT(0);
6634 return status;
6635 }
6636 }
6637
6638 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6639 {
6640 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6641
6642 if(eHAL_STATUS_SUCCESS != halStatus)
6643 {
6644 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006645 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006646 VOS_ASSERT(0);
6647 return status;
6648 }
6649 }
6650 }
6651
6652 if((TRUE == disableBmps) ||
6653 (TRUE == disableImps))
6654 {
6655 /* Now, get the chip into Full Power now */
6656 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6657 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6658 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6659
6660 if(halStatus != eHAL_STATUS_SUCCESS)
6661 {
6662 if(halStatus == eHAL_STATUS_PMC_PENDING)
6663 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306664 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006665 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306666 ret = wait_for_completion_interruptible_timeout(
6667 &pHddCtx->full_pwr_comp_var,
6668 msecs_to_jiffies(1000));
6669 if (ret <= 0)
6670 {
6671 hddLog(VOS_TRACE_LEVEL_ERROR,
6672 "%s: wait on full_pwr_comp_var failed %ld",
6673 __func__, ret);
6674 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006675 }
6676 else
6677 {
6678 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006679 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006680 VOS_ASSERT(0);
6681 return status;
6682 }
6683 }
6684
6685 status = VOS_STATUS_SUCCESS;
6686 }
6687
6688 break;
6689 }
6690 return status;
6691}
6692
6693hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006694 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 tANI_U8 rtnl_held )
6696{
6697 hdd_adapter_t *pAdapter = NULL;
6698 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6699 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6700 VOS_STATUS exitbmpsStatus;
6701
Arif Hussain6d2a3322013-11-17 19:50:10 -08006702 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006703
Nirav Shah436658f2014-02-28 17:05:45 +05306704 if(macAddr == NULL)
6705 {
6706 /* Not received valid macAddr */
6707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6708 "%s:Unable to add virtual intf: Not able to get"
6709 "valid mac address",__func__);
6710 return NULL;
6711 }
6712
Jeff Johnson295189b2012-06-20 16:38:30 -07006713 //Disable BMPS incase of Concurrency
6714 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6715
6716 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6717 {
6718 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306719 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006720 VOS_ASSERT(0);
6721 return NULL;
6722 }
6723
6724 switch(session_type)
6725 {
6726 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006727 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006728 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006729 {
6730 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6731
6732 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306733 {
6734 hddLog(VOS_TRACE_LEVEL_FATAL,
6735 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006736 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306737 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006738
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306739#ifdef FEATURE_WLAN_TDLS
6740 /* A Mutex Lock is introduced while changing/initializing the mode to
6741 * protect the concurrent access for the Adapters by TDLS module.
6742 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306743 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306744#endif
6745
Jeff Johnsone7245742012-09-05 17:12:55 -07006746 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6747 NL80211_IFTYPE_P2P_CLIENT:
6748 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006749
Jeff Johnson295189b2012-06-20 16:38:30 -07006750 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306751#ifdef FEATURE_WLAN_TDLS
6752 mutex_unlock(&pHddCtx->tdls_lock);
6753#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306754
6755 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006756 if( VOS_STATUS_SUCCESS != status )
6757 goto err_free_netdev;
6758
6759 status = hdd_register_interface( pAdapter, rtnl_held );
6760 if( VOS_STATUS_SUCCESS != status )
6761 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306762#ifdef FEATURE_WLAN_TDLS
6763 mutex_lock(&pHddCtx->tdls_lock);
6764#endif
c_hpothu002231a2015-02-05 14:58:51 +05306765 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306766#ifdef FEATURE_WLAN_TDLS
6767 mutex_unlock(&pHddCtx->tdls_lock);
6768#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 goto err_free_netdev;
6770 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306771
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306772 // Workqueue which gets scheduled in IPv4 notification callback.
6773 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6774
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306775#ifdef WLAN_NS_OFFLOAD
6776 // Workqueue which gets scheduled in IPv6 notification callback.
6777 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6778#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306780 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006781 netif_tx_disable(pAdapter->dev);
6782 //netif_tx_disable(pWlanDev);
6783 netif_carrier_off(pAdapter->dev);
6784
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306785 if (WLAN_HDD_P2P_CLIENT == session_type ||
6786 WLAN_HDD_P2P_DEVICE == session_type)
6787 {
6788 /* Initialize the work queue to defer the
6789 * back to back RoC request */
6790 INIT_DELAYED_WORK(&pAdapter->roc_work,
6791 hdd_p2p_roc_work_queue);
6792 }
6793
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 break;
6795 }
6796
Jeff Johnson295189b2012-06-20 16:38:30 -07006797 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 case WLAN_HDD_SOFTAP:
6799 {
6800 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6801 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306802 {
6803 hddLog(VOS_TRACE_LEVEL_FATAL,
6804 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306806 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006807
Jeff Johnson295189b2012-06-20 16:38:30 -07006808 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6809 NL80211_IFTYPE_AP:
6810 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006811 pAdapter->device_mode = session_type;
6812
6813 status = hdd_init_ap_mode(pAdapter);
6814 if( VOS_STATUS_SUCCESS != status )
6815 goto err_free_netdev;
6816
6817 status = hdd_register_hostapd( pAdapter, rtnl_held );
6818 if( VOS_STATUS_SUCCESS != status )
6819 {
c_hpothu002231a2015-02-05 14:58:51 +05306820 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006821 goto err_free_netdev;
6822 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306823 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006824 netif_tx_disable(pAdapter->dev);
6825 netif_carrier_off(pAdapter->dev);
6826
6827 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306828
6829 if (WLAN_HDD_P2P_GO == session_type)
6830 {
6831 /* Initialize the work queue to
6832 * defer the back to back RoC request */
6833 INIT_DELAYED_WORK(&pAdapter->roc_work,
6834 hdd_p2p_roc_work_queue);
6835 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006836 break;
6837 }
6838 case WLAN_HDD_MONITOR:
6839 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006840 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6841 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306842 {
6843 hddLog(VOS_TRACE_LEVEL_FATAL,
6844 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006845 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306846 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006847
6848 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6849 pAdapter->device_mode = session_type;
6850 status = hdd_register_interface( pAdapter, rtnl_held );
6851#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6852 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6853#else
6854 pAdapter->dev->open = hdd_mon_open;
6855 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6856#endif
6857 hdd_init_tx_rx( pAdapter );
6858 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6859 //Set adapter to be used for data tx. It will use either GO or softap.
6860 pAdapter->sessionCtx.monitor.pAdapterForTx =
6861 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6863 {
6864 pAdapter->sessionCtx.monitor.pAdapterForTx =
6865 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6866 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006867 /* This workqueue will be used to transmit management packet over
6868 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006869 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6870 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6871 return NULL;
6872 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006873
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6875 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 }
6877 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 case WLAN_HDD_FTM:
6879 {
6880 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6881
6882 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306883 {
6884 hddLog(VOS_TRACE_LEVEL_FATAL,
6885 FL("failed to allocate adapter for session %d"), session_type);
6886 return NULL;
6887 }
6888
Jeff Johnson295189b2012-06-20 16:38:30 -07006889 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6890 * message while loading driver in FTM mode. */
6891 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6892 pAdapter->device_mode = session_type;
6893 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306894
6895 hdd_init_tx_rx( pAdapter );
6896
6897 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306899 netif_tx_disable(pAdapter->dev);
6900 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006901 }
6902 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006903 default:
6904 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306905 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6906 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 VOS_ASSERT(0);
6908 return NULL;
6909 }
6910 }
6911
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 if( VOS_STATUS_SUCCESS == status )
6913 {
6914 //Add it to the hdd's session list.
6915 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6916 if( NULL == pHddAdapterNode )
6917 {
6918 status = VOS_STATUS_E_NOMEM;
6919 }
6920 else
6921 {
6922 pHddAdapterNode->pAdapter = pAdapter;
6923 status = hdd_add_adapter_back ( pHddCtx,
6924 pHddAdapterNode );
6925 }
6926 }
6927
6928 if( VOS_STATUS_SUCCESS != status )
6929 {
6930 if( NULL != pAdapter )
6931 {
6932 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6933 pAdapter = NULL;
6934 }
6935 if( NULL != pHddAdapterNode )
6936 {
6937 vos_mem_free( pHddAdapterNode );
6938 }
6939
6940 goto resume_bmps;
6941 }
6942
6943 if(VOS_STATUS_SUCCESS == status)
6944 {
6945 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6946
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006947 //Initialize the WoWL service
6948 if(!hdd_init_wowl(pAdapter))
6949 {
6950 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6951 goto err_free_netdev;
6952 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 return pAdapter;
6955
6956err_free_netdev:
6957 free_netdev(pAdapter->dev);
6958 wlan_hdd_release_intf_addr( pHddCtx,
6959 pAdapter->macAddressCurrent.bytes );
6960
6961resume_bmps:
6962 //If bmps disabled enable it
6963 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6964 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306965 if (pHddCtx->hdd_wlan_suspended)
6966 {
6967 hdd_set_pwrparams(pHddCtx);
6968 }
6969 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 }
6971 return NULL;
6972}
6973
6974VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6975 tANI_U8 rtnl_held )
6976{
6977 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6978 VOS_STATUS status;
6979
6980 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6981 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306982 {
6983 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6984 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306986 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006987
6988 while ( pCurrent->pAdapter != pAdapter )
6989 {
6990 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6991 if( VOS_STATUS_SUCCESS != status )
6992 break;
6993
6994 pCurrent = pNext;
6995 }
6996 pAdapterNode = pCurrent;
6997 if( VOS_STATUS_SUCCESS == status )
6998 {
6999 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
7000 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307001
7002#ifdef FEATURE_WLAN_TDLS
7003
7004 /* A Mutex Lock is introduced while changing/initializing the mode to
7005 * protect the concurrent access for the Adapters by TDLS module.
7006 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05307007 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307008#endif
7009
Jeff Johnson295189b2012-06-20 16:38:30 -07007010 hdd_remove_adapter( pHddCtx, pAdapterNode );
7011 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08007012 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007013
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05307014#ifdef FEATURE_WLAN_TDLS
7015 mutex_unlock(&pHddCtx->tdls_lock);
7016#endif
7017
Jeff Johnson295189b2012-06-20 16:38:30 -07007018
7019 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307020 if ((!vos_concurrent_open_sessions_running()) &&
7021 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7022 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307024 if (pHddCtx->hdd_wlan_suspended)
7025 {
7026 hdd_set_pwrparams(pHddCtx);
7027 }
7028 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 }
7030
7031 return VOS_STATUS_SUCCESS;
7032 }
7033
7034 return VOS_STATUS_E_FAILURE;
7035}
7036
7037VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7038{
7039 hdd_adapter_list_node_t *pHddAdapterNode;
7040 VOS_STATUS status;
7041
7042 ENTER();
7043
7044 do
7045 {
7046 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7047 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7048 {
7049 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7050 vos_mem_free( pHddAdapterNode );
7051 }
7052 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7053
7054 EXIT();
7055
7056 return VOS_STATUS_SUCCESS;
7057}
7058
7059void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7060{
7061 v_U8_t addIE[1] = {0};
7062
7063 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7064 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7065 eANI_BOOLEAN_FALSE) )
7066 {
7067 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007068 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 }
7070
7071 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7072 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7073 eANI_BOOLEAN_FALSE) )
7074 {
7075 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007076 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 }
7078
7079 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7080 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7081 eANI_BOOLEAN_FALSE) )
7082 {
7083 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007084 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 }
7086}
7087
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307088VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7089 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007090{
7091 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7092 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307093 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007094 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307095 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307096 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007097
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307098 if (pHddCtx->isLogpInProgress) {
7099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7100 "%s:LOGP in Progress. Ignore!!!",__func__);
7101 return VOS_STATUS_E_FAILURE;
7102 }
7103
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307105
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307106 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007107 switch(pAdapter->device_mode)
7108 {
7109 case WLAN_HDD_INFRA_STATION:
7110 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007111 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307112 {
7113 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7114 if( hdd_connIsConnected(pstation) ||
7115 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307117#ifdef FEATURE_WLAN_TDLS
7118 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307119 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307120 mutex_unlock(&pHddCtx->tdls_lock);
7121#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007122 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7123 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7124 pAdapter->sessionId,
7125 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7126 else
7127 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7128 pAdapter->sessionId,
7129 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7130 //success implies disconnect command got queued up successfully
7131 if(halStatus == eHAL_STATUS_SUCCESS)
7132 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307133 ret = wait_for_completion_interruptible_timeout(
7134 &pAdapter->disconnect_comp_var,
7135 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7136 if (ret <= 0)
7137 {
7138 hddLog(VOS_TRACE_LEVEL_ERROR,
7139 "%s: wait on disconnect_comp_var failed %ld",
7140 __func__, ret);
7141 }
7142 }
7143 else
7144 {
7145 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7146 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 }
7148 memset(&wrqu, '\0', sizeof(wrqu));
7149 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7150 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7151 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7152 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307153 else if(pstation->conn_info.connState ==
7154 eConnectionState_Disconnecting)
7155 {
7156 ret = wait_for_completion_interruptible_timeout(
7157 &pAdapter->disconnect_comp_var,
7158 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7159 if (ret <= 0)
7160 {
7161 hddLog(VOS_TRACE_LEVEL_ERROR,
7162 FL("wait on disconnect_comp_var failed %ld"), ret);
7163 }
7164 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307165 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007166 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307167 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307168 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007169 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307170 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7171 {
7172 while (pAdapter->is_roc_inprogress)
7173 {
7174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7175 "%s: ROC in progress for session %d!!!",
7176 __func__, pAdapter->sessionId);
7177 // waiting for ROC to expire
7178 msleep(500);
7179 /* In GO present case , if retry exceeds 3,
7180 it means something went wrong. */
7181 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7182 {
7183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7184 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307185 if (eHAL_STATUS_SUCCESS !=
7186 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7187 pAdapter->sessionId ))
7188 {
7189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7190 FL("Failed to Cancel Remain on Channel"));
7191 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307192 wait_for_completion_interruptible_timeout(
7193 &pAdapter->cancel_rem_on_chan_var,
7194 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7195 break;
7196 }
7197 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307198#ifdef WLAN_OPEN_SOURCE
7199 cancel_delayed_work_sync(&pAdapter->roc_work);
7200#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307201 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307202#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307203#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307204 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7205#endif
7206#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307207
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307208#ifdef WLAN_OPEN_SOURCE
7209 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7210#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307211
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307212 /* It is possible that the caller of this function does not
7213 * wish to close the session
7214 */
7215 if (VOS_TRUE == bCloseSession &&
7216 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007217 {
7218 INIT_COMPLETION(pAdapter->session_close_comp_var);
7219 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307220 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7221 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307223 unsigned long ret;
7224
Jeff Johnson295189b2012-06-20 16:38:30 -07007225 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307226 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307227 &pAdapter->session_close_comp_var,
7228 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307229 if ( 0 >= ret)
7230 {
7231 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307232 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307233 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 }
7235 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307236 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 break;
7238
7239 case WLAN_HDD_SOFTAP:
7240 case WLAN_HDD_P2P_GO:
7241 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307242 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7243 while (pAdapter->is_roc_inprogress) {
7244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7245 "%s: ROC in progress for session %d!!!",
7246 __func__, pAdapter->sessionId);
7247 msleep(500);
7248 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7250 "%s: ROC completion is not received.!!!", __func__);
7251 WLANSAP_CancelRemainOnChannel(
7252 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7253 wait_for_completion_interruptible_timeout(
7254 &pAdapter->cancel_rem_on_chan_var,
7255 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7256 break;
7257 }
7258 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307259
7260#ifdef WLAN_OPEN_SOURCE
7261 cancel_delayed_work_sync(&pAdapter->roc_work);
7262#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307263 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007264 mutex_lock(&pHddCtx->sap_lock);
7265 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7266 {
7267 VOS_STATUS status;
7268 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7269
7270 //Stop Bss.
7271 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7272 if (VOS_IS_STATUS_SUCCESS(status))
7273 {
7274 hdd_hostapd_state_t *pHostapdState =
7275 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7276
7277 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7278
7279 if (!VOS_IS_STATUS_SUCCESS(status))
7280 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307281 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7282 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007283 }
7284 }
7285 else
7286 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007287 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007288 }
7289 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307290 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007291
7292 if (eHAL_STATUS_FAILURE ==
7293 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7294 0, NULL, eANI_BOOLEAN_FALSE))
7295 {
7296 hddLog(LOGE,
7297 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007298 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 }
7300
7301 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7302 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7303 eANI_BOOLEAN_FALSE) )
7304 {
7305 hddLog(LOGE,
7306 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7307 }
7308
7309 // Reset WNI_CFG_PROBE_RSP Flags
7310 wlan_hdd_reset_prob_rspies(pAdapter);
7311 kfree(pAdapter->sessionCtx.ap.beacon);
7312 pAdapter->sessionCtx.ap.beacon = NULL;
7313 }
7314 mutex_unlock(&pHddCtx->sap_lock);
7315 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007316
Jeff Johnson295189b2012-06-20 16:38:30 -07007317 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007318#ifdef WLAN_OPEN_SOURCE
7319 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7320#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007321 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007322
Jeff Johnson295189b2012-06-20 16:38:30 -07007323 default:
7324 break;
7325 }
7326
7327 EXIT();
7328 return VOS_STATUS_SUCCESS;
7329}
7330
7331VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7332{
7333 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7334 VOS_STATUS status;
7335 hdd_adapter_t *pAdapter;
7336
7337 ENTER();
7338
7339 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7340
7341 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7342 {
7343 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007344
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307345 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007346
7347 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7348 pAdapterNode = pNext;
7349 }
7350
7351 EXIT();
7352
7353 return VOS_STATUS_SUCCESS;
7354}
7355
Rajeev Kumarf999e582014-01-09 17:33:29 -08007356
7357#ifdef FEATURE_WLAN_BATCH_SCAN
7358/**---------------------------------------------------------------------------
7359
7360 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7361 structures
7362
7363 \param - pAdapter Pointer to HDD adapter
7364
7365 \return - None
7366
7367 --------------------------------------------------------------------------*/
7368void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7369{
7370 tHddBatchScanRsp *pNode;
7371 tHddBatchScanRsp *pPrev;
7372
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307373 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007374 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307375 hddLog(VOS_TRACE_LEVEL_ERROR,
7376 "%s: Adapter context is Null", __func__);
7377 return;
7378 }
7379
7380 pNode = pAdapter->pBatchScanRsp;
7381 while (pNode)
7382 {
7383 pPrev = pNode;
7384 pNode = pNode->pNext;
7385 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007386 }
7387
7388 pAdapter->pBatchScanRsp = NULL;
7389 pAdapter->numScanList = 0;
7390 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7391 pAdapter->prev_batch_id = 0;
7392
7393 return;
7394}
7395#endif
7396
7397
Jeff Johnson295189b2012-06-20 16:38:30 -07007398VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7399{
7400 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7401 VOS_STATUS status;
7402 hdd_adapter_t *pAdapter;
7403
7404 ENTER();
7405
7406 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7407
7408 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7409 {
7410 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307411 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007412 netif_tx_disable(pAdapter->dev);
7413 netif_carrier_off(pAdapter->dev);
7414
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007415 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7416
Jeff Johnson295189b2012-06-20 16:38:30 -07007417 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307418
Katya Nigam1fd24402015-02-16 14:52:19 +05307419 if(pAdapter->device_mode == WLAN_HDD_IBSS )
7420 hdd_ibss_deinit_tx_rx(pAdapter);
7421
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307422 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7423
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307424 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7425 {
7426 hdd_wmm_adapter_close( pAdapter );
7427 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7428 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007429
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307430 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7431 {
7432 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7433 }
7434
Rajeev Kumarf999e582014-01-09 17:33:29 -08007435#ifdef FEATURE_WLAN_BATCH_SCAN
7436 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7437 {
7438 hdd_deinit_batch_scan(pAdapter);
7439 }
7440#endif
7441
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307442#ifdef FEATURE_WLAN_TDLS
7443 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307444 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307445 mutex_unlock(&pHddCtx->tdls_lock);
7446#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007447 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7448 pAdapterNode = pNext;
7449 }
7450
7451 EXIT();
7452
7453 return VOS_STATUS_SUCCESS;
7454}
7455
7456VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7457{
7458 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7459 VOS_STATUS status;
7460 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307461 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007462
7463 ENTER();
7464
7465 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7466
7467 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7468 {
7469 pAdapter = pAdapterNode->pAdapter;
7470
Kumar Anand82c009f2014-05-29 00:29:42 -07007471 hdd_wmm_init( pAdapter );
7472
Jeff Johnson295189b2012-06-20 16:38:30 -07007473 switch(pAdapter->device_mode)
7474 {
7475 case WLAN_HDD_INFRA_STATION:
7476 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007477 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307478
7479 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7480
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 hdd_init_station_mode(pAdapter);
7482 /* Open the gates for HDD to receive Wext commands */
7483 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007484 pHddCtx->scan_info.mScanPending = FALSE;
7485 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007486
7487 //Trigger the initial scan
7488 hdd_wlan_initial_scan(pAdapter);
7489
7490 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307491 if (eConnectionState_Associated == connState ||
7492 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007493 {
7494 union iwreq_data wrqu;
7495 memset(&wrqu, '\0', sizeof(wrqu));
7496 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7497 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7498 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007499 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007500
Jeff Johnson295189b2012-06-20 16:38:30 -07007501 /* indicate disconnected event to nl80211 */
7502 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7503 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007504 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307505 else if (eConnectionState_Connecting == connState)
7506 {
7507 /*
7508 * Indicate connect failure to supplicant if we were in the
7509 * process of connecting
7510 */
7511 cfg80211_connect_result(pAdapter->dev, NULL,
7512 NULL, 0, NULL, 0,
7513 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7514 GFP_KERNEL);
7515 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007516 break;
7517
7518 case WLAN_HDD_SOFTAP:
7519 /* softAP can handle SSR */
7520 break;
7521
7522 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007524 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007525 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 break;
7527
7528 case WLAN_HDD_MONITOR:
7529 /* monitor interface start */
7530 break;
7531 default:
7532 break;
7533 }
7534
7535 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7536 pAdapterNode = pNext;
7537 }
7538
7539 EXIT();
7540
7541 return VOS_STATUS_SUCCESS;
7542}
7543
7544VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7545{
7546 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7547 hdd_adapter_t *pAdapter;
7548 VOS_STATUS status;
7549 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307550 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007551
7552 ENTER();
7553
7554 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7555
7556 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7557 {
7558 pAdapter = pAdapterNode->pAdapter;
7559
7560 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7561 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7562 {
7563 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7564 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7565
Abhishek Singhf4669da2014-05-26 15:07:49 +05307566 hddLog(VOS_TRACE_LEVEL_INFO,
7567 "%s: Set HDD connState to eConnectionState_NotConnected",
7568 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007569 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7570 init_completion(&pAdapter->disconnect_comp_var);
7571 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7572 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7573
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307574 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007575 &pAdapter->disconnect_comp_var,
7576 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307577 if (0 >= ret)
7578 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7579 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007580
7581 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7582 pHddCtx->isAmpAllowed = VOS_FALSE;
7583 sme_RoamConnect(pHddCtx->hHal,
7584 pAdapter->sessionId, &(pWextState->roamProfile),
7585 &roamId);
7586 }
7587
7588 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7589 pAdapterNode = pNext;
7590 }
7591
7592 EXIT();
7593
7594 return VOS_STATUS_SUCCESS;
7595}
7596
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007597void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7598{
7599 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7600 VOS_STATUS status;
7601 hdd_adapter_t *pAdapter;
7602 hdd_station_ctx_t *pHddStaCtx;
7603 hdd_ap_ctx_t *pHddApCtx;
7604 hdd_hostapd_state_t * pHostapdState;
7605 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7606 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7607 const char *p2pMode = "DEV";
7608 const char *ccMode = "Standalone";
7609 int n;
7610
7611 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7612 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7613 {
7614 pAdapter = pAdapterNode->pAdapter;
7615 switch (pAdapter->device_mode) {
7616 case WLAN_HDD_INFRA_STATION:
7617 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7618 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7619 staChannel = pHddStaCtx->conn_info.operationChannel;
7620 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7621 }
7622 break;
7623 case WLAN_HDD_P2P_CLIENT:
7624 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7625 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7626 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7627 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7628 p2pMode = "CLI";
7629 }
7630 break;
7631 case WLAN_HDD_P2P_GO:
7632 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7633 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7634 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7635 p2pChannel = pHddApCtx->operatingChannel;
7636 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7637 }
7638 p2pMode = "GO";
7639 break;
7640 case WLAN_HDD_SOFTAP:
7641 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7642 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7643 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7644 apChannel = pHddApCtx->operatingChannel;
7645 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7646 }
7647 break;
7648 default:
7649 break;
7650 }
7651 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7652 pAdapterNode = pNext;
7653 }
7654 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7655 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7656 }
7657 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7658 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7659 if (p2pChannel > 0) {
7660 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7661 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7662 }
7663 if (apChannel > 0) {
7664 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7665 apChannel, MAC_ADDR_ARRAY(apBssid));
7666 }
7667
7668 if (p2pChannel > 0 && apChannel > 0) {
7669 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7670 }
7671}
7672
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007673bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007674{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007675 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007676}
7677
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007678/* Once SSR is disabled then it cannot be set. */
7679void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007680{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007681 if (HDD_SSR_DISABLED == isSsrRequired)
7682 return;
7683
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 isSsrRequired = value;
7685}
7686
7687VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7688 hdd_adapter_list_node_t** ppAdapterNode)
7689{
7690 VOS_STATUS status;
7691 spin_lock(&pHddCtx->hddAdapters.lock);
7692 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7693 (hdd_list_node_t**) ppAdapterNode );
7694 spin_unlock(&pHddCtx->hddAdapters.lock);
7695 return status;
7696}
7697
7698VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7699 hdd_adapter_list_node_t* pAdapterNode,
7700 hdd_adapter_list_node_t** pNextAdapterNode)
7701{
7702 VOS_STATUS status;
7703 spin_lock(&pHddCtx->hddAdapters.lock);
7704 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7705 (hdd_list_node_t*) pAdapterNode,
7706 (hdd_list_node_t**)pNextAdapterNode );
7707
7708 spin_unlock(&pHddCtx->hddAdapters.lock);
7709 return status;
7710}
7711
7712VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7713 hdd_adapter_list_node_t* pAdapterNode)
7714{
7715 VOS_STATUS status;
7716 spin_lock(&pHddCtx->hddAdapters.lock);
7717 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7718 &pAdapterNode->node );
7719 spin_unlock(&pHddCtx->hddAdapters.lock);
7720 return status;
7721}
7722
7723VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7724 hdd_adapter_list_node_t** ppAdapterNode)
7725{
7726 VOS_STATUS status;
7727 spin_lock(&pHddCtx->hddAdapters.lock);
7728 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7729 (hdd_list_node_t**) ppAdapterNode );
7730 spin_unlock(&pHddCtx->hddAdapters.lock);
7731 return status;
7732}
7733
7734VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7735 hdd_adapter_list_node_t* pAdapterNode)
7736{
7737 VOS_STATUS status;
7738 spin_lock(&pHddCtx->hddAdapters.lock);
7739 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7740 (hdd_list_node_t*) pAdapterNode );
7741 spin_unlock(&pHddCtx->hddAdapters.lock);
7742 return status;
7743}
7744
7745VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7746 hdd_adapter_list_node_t* pAdapterNode)
7747{
7748 VOS_STATUS status;
7749 spin_lock(&pHddCtx->hddAdapters.lock);
7750 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7751 (hdd_list_node_t*) pAdapterNode );
7752 spin_unlock(&pHddCtx->hddAdapters.lock);
7753 return status;
7754}
7755
7756hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7757 tSirMacAddr macAddr )
7758{
7759 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7760 hdd_adapter_t *pAdapter;
7761 VOS_STATUS status;
7762
7763 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7764
7765 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7766 {
7767 pAdapter = pAdapterNode->pAdapter;
7768
7769 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7770 macAddr, sizeof(tSirMacAddr) ) )
7771 {
7772 return pAdapter;
7773 }
7774 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7775 pAdapterNode = pNext;
7776 }
7777
7778 return NULL;
7779
7780}
7781
7782hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7783{
7784 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7785 hdd_adapter_t *pAdapter;
7786 VOS_STATUS status;
7787
7788 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7789
7790 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7791 {
7792 pAdapter = pAdapterNode->pAdapter;
7793
7794 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7795 IFNAMSIZ ) )
7796 {
7797 return pAdapter;
7798 }
7799 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7800 pAdapterNode = pNext;
7801 }
7802
7803 return NULL;
7804
7805}
7806
7807hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7808{
7809 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7810 hdd_adapter_t *pAdapter;
7811 VOS_STATUS status;
7812
7813 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7814
7815 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7816 {
7817 pAdapter = pAdapterNode->pAdapter;
7818
7819 if( pAdapter && (mode == pAdapter->device_mode) )
7820 {
7821 return pAdapter;
7822 }
7823 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7824 pAdapterNode = pNext;
7825 }
7826
7827 return NULL;
7828
7829}
7830
7831//Remove this function later
7832hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7833{
7834 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7835 hdd_adapter_t *pAdapter;
7836 VOS_STATUS status;
7837
7838 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7839
7840 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7841 {
7842 pAdapter = pAdapterNode->pAdapter;
7843
7844 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7845 {
7846 return pAdapter;
7847 }
7848
7849 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7850 pAdapterNode = pNext;
7851 }
7852
7853 return NULL;
7854
7855}
7856
Jeff Johnson295189b2012-06-20 16:38:30 -07007857/**---------------------------------------------------------------------------
7858
7859 \brief hdd_set_monitor_tx_adapter() -
7860
7861 This API initializes the adapter to be used while transmitting on monitor
7862 adapter.
7863
7864 \param - pHddCtx - Pointer to the HDD context.
7865 pAdapter - Adapter that will used for TX. This can be NULL.
7866 \return - None.
7867 --------------------------------------------------------------------------*/
7868void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7869{
7870 hdd_adapter_t *pMonAdapter;
7871
7872 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7873
7874 if( NULL != pMonAdapter )
7875 {
7876 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7877 }
7878}
Jeff Johnson295189b2012-06-20 16:38:30 -07007879/**---------------------------------------------------------------------------
7880
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307881 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007882
7883 This API returns the operating channel of the requested device mode
7884
7885 \param - pHddCtx - Pointer to the HDD context.
7886 - mode - Device mode for which operating channel is required
7887 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7888 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7889 \return - channel number. "0" id the requested device is not found OR it is not connected.
7890 --------------------------------------------------------------------------*/
7891v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7892{
7893 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7894 VOS_STATUS status;
7895 hdd_adapter_t *pAdapter;
7896 v_U8_t operatingChannel = 0;
7897
7898 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7899
7900 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7901 {
7902 pAdapter = pAdapterNode->pAdapter;
7903
7904 if( mode == pAdapter->device_mode )
7905 {
7906 switch(pAdapter->device_mode)
7907 {
7908 case WLAN_HDD_INFRA_STATION:
7909 case WLAN_HDD_P2P_CLIENT:
7910 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7911 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7912 break;
7913 case WLAN_HDD_SOFTAP:
7914 case WLAN_HDD_P2P_GO:
7915 /*softap connection info */
7916 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7917 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7918 break;
7919 default:
7920 break;
7921 }
7922
7923 break; //Found the device of interest. break the loop
7924 }
7925
7926 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7927 pAdapterNode = pNext;
7928 }
7929 return operatingChannel;
7930}
7931
7932#ifdef WLAN_FEATURE_PACKET_FILTERING
7933/**---------------------------------------------------------------------------
7934
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307935 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007936
7937 This used to set the multicast address list.
7938
7939 \param - dev - Pointer to the WLAN device.
7940 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307941 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07007942
7943 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307944static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007945{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307946 hdd_adapter_t *pAdapter;
7947 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007948 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307949 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007950 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307951
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307952 ENTER();
7953
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307954 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307955 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007956 {
7957 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307958 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 return;
7960 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307961 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7962 ret = wlan_hdd_validate_context(pHddCtx);
7963 if (0 != ret)
7964 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307965 return;
7966 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007967 if (dev->flags & IFF_ALLMULTI)
7968 {
7969 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007970 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307971 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307973 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007974 {
7975 mc_count = netdev_mc_count(dev);
7976 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007977 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007978 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7979 {
7980 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007981 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307982 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 return;
7984 }
7985
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307986 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007987
7988 netdev_for_each_mc_addr(ha, dev) {
7989 if (i == mc_count)
7990 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307991 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7992 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007993 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307994 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307995 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 i++;
7997 }
7998 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307999
8000 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 return;
8002}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308003
8004static void hdd_set_multicast_list(struct net_device *dev)
8005{
8006 vos_ssr_protect(__func__);
8007 __hdd_set_multicast_list(dev);
8008 vos_ssr_unprotect(__func__);
8009}
Jeff Johnson295189b2012-06-20 16:38:30 -07008010#endif
8011
8012/**---------------------------------------------------------------------------
8013
8014 \brief hdd_select_queue() -
8015
8016 This function is registered with the Linux OS for network
8017 core to decide which queue to use first.
8018
8019 \param - dev - Pointer to the WLAN device.
8020 - skb - Pointer to OS packet (sk_buff).
8021 \return - ac, Queue Index/access category corresponding to UP in IP header
8022
8023 --------------------------------------------------------------------------*/
8024v_U16_t hdd_select_queue(struct net_device *dev,
8025 struct sk_buff *skb)
8026{
8027 return hdd_wmm_select_queue(dev, skb);
8028}
8029
8030
8031/**---------------------------------------------------------------------------
8032
8033 \brief hdd_wlan_initial_scan() -
8034
8035 This function triggers the initial scan
8036
8037 \param - pAdapter - Pointer to the HDD adapter.
8038
8039 --------------------------------------------------------------------------*/
8040void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8041{
8042 tCsrScanRequest scanReq;
8043 tCsrChannelInfo channelInfo;
8044 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008045 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008046 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8047
8048 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8049 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8050 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8051
8052 if(sme_Is11dSupported(pHddCtx->hHal))
8053 {
8054 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8055 if ( HAL_STATUS_SUCCESS( halStatus ) )
8056 {
8057 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8058 if( !scanReq.ChannelInfo.ChannelList )
8059 {
8060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8061 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008062 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 return;
8064 }
8065 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8066 channelInfo.numOfChannels);
8067 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8068 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008069 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008070 }
8071
8072 scanReq.scanType = eSIR_PASSIVE_SCAN;
8073 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8074 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8075 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8076 }
8077 else
8078 {
8079 scanReq.scanType = eSIR_ACTIVE_SCAN;
8080 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8081 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8082 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8083 }
8084
8085 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8086 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8087 {
8088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8089 __func__, halStatus );
8090 }
8091
8092 if(sme_Is11dSupported(pHddCtx->hHal))
8093 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8094}
8095
Jeff Johnson295189b2012-06-20 16:38:30 -07008096/**---------------------------------------------------------------------------
8097
8098 \brief hdd_full_power_callback() - HDD full power callback function
8099
8100 This is the function invoked by SME to inform the result of a full power
8101 request issued by HDD
8102
8103 \param - callbackcontext - Pointer to cookie
8104 \param - status - result of request
8105
8106 \return - None
8107
8108 --------------------------------------------------------------------------*/
8109static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8110{
Jeff Johnson72a40512013-12-19 10:14:15 -08008111 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008112
8113 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308114 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008115
8116 if (NULL == callbackContext)
8117 {
8118 hddLog(VOS_TRACE_LEVEL_ERROR,
8119 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008120 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008121 return;
8122 }
8123
Jeff Johnson72a40512013-12-19 10:14:15 -08008124 /* there is a race condition that exists between this callback
8125 function and the caller since the caller could time out either
8126 before or while this code is executing. we use a spinlock to
8127 serialize these actions */
8128 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008129
8130 if (POWER_CONTEXT_MAGIC != pContext->magic)
8131 {
8132 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008133 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 hddLog(VOS_TRACE_LEVEL_WARN,
8135 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008136 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008137 return;
8138 }
8139
Jeff Johnson72a40512013-12-19 10:14:15 -08008140 /* context is valid so caller is still waiting */
8141
8142 /* paranoia: invalidate the magic */
8143 pContext->magic = 0;
8144
8145 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008147
8148 /* serialization is complete */
8149 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008150}
8151
8152/**---------------------------------------------------------------------------
8153
8154 \brief hdd_wlan_exit() - HDD WLAN exit function
8155
8156 This is the driver exit point (invoked during rmmod)
8157
8158 \param - pHddCtx - Pointer to the HDD Context
8159
8160 \return - None
8161
8162 --------------------------------------------------------------------------*/
8163void hdd_wlan_exit(hdd_context_t *pHddCtx)
8164{
8165 eHalStatus halStatus;
8166 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8167 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308168 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008169 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008170 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008171 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308172 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008173
8174 ENTER();
8175
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308176#ifdef WLAN_NS_OFFLOAD
8177 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8178 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8179#endif
8180 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8181 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8182
Jeff Johnson88ba7742013-02-27 14:36:02 -08008183 if (VOS_FTM_MODE != hdd_get_conparam())
8184 {
Katya Nigamdc373382015-02-25 18:52:19 +05308185 /* This will issue a dump command which will clean up
8186 BTQM queues and unblock MC thread */
Mahesh A Saptasagar4f6d8622015-03-16 20:37:10 +05308187 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
Jeff Johnson88ba7742013-02-27 14:36:02 -08008188 // Unloading, restart logic is no more required.
8189 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008190
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308191#ifdef FEATURE_WLAN_TDLS
8192 /* At the time of driver unloading; if tdls connection is present;
8193 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8194 * wlan_hdd_tdls_find_peer always checks for valid context;
8195 * as load/unload in progress there can be a race condition.
8196 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8197 * when tdls state is enabled.
8198 * As soon as driver set load/unload flag; tdls flag also needs
8199 * to be disabled so that hdd_rx_packet_cbk won't call
8200 * wlan_hdd_tdls_find_peer.
8201 */
8202 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8203#endif
8204
c_hpothu5ab05e92014-06-13 17:34:05 +05308205 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8206 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308208 pAdapter = pAdapterNode->pAdapter;
8209 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008210 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308211 /* Disable TX on the interface, after this hard_start_xmit() will
8212 * not be called on that interface
8213 */
8214 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8215 netif_tx_disable(pAdapter->dev);
8216
8217 /* Mark the interface status as "down" for outside world */
8218 netif_carrier_off(pAdapter->dev);
8219
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308220 /* DeInit the adapter. This ensures that all data packets
8221 * are freed.
8222 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308223#ifdef FEATURE_WLAN_TDLS
8224 mutex_lock(&pHddCtx->tdls_lock);
8225#endif
c_hpothu002231a2015-02-05 14:58:51 +05308226 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308227#ifdef FEATURE_WLAN_TDLS
8228 mutex_unlock(&pHddCtx->tdls_lock);
8229#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308230
c_hpothu5ab05e92014-06-13 17:34:05 +05308231 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8232 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8233 {
8234 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8235 hdd_UnregisterWext(pAdapter->dev);
8236 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308237
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308239 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8240 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008241 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308242 // Cancel any outstanding scan requests. We are about to close all
8243 // of our adapters, but an adapter structure is what SME passes back
8244 // to our callback function. Hence if there are any outstanding scan
8245 // requests then there is a race condition between when the adapter
8246 // is closed and when the callback is invoked.We try to resolve that
8247 // race condition here by canceling any outstanding scans before we
8248 // close the adapters.
8249 // Note that the scans may be cancelled in an asynchronous manner,
8250 // so ideally there needs to be some kind of synchronization. Rather
8251 // than introduce a new synchronization here, we will utilize the
8252 // fact that we are about to Request Full Power, and since that is
8253 // synchronized, the expectation is that by the time Request Full
8254 // Power has completed all scans will be cancelled.
8255 if (pHddCtx->scan_info.mScanPending)
8256 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308257 if(NULL != pAdapter)
8258 {
8259 hddLog(VOS_TRACE_LEVEL_INFO,
8260 FL("abort scan mode: %d sessionId: %d"),
8261 pAdapter->device_mode,
8262 pAdapter->sessionId);
8263 }
8264 hdd_abort_mac_scan(pHddCtx,
8265 pHddCtx->scan_info.sessionId,
8266 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308269 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008270 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308271 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308272 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8273 {
8274 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8276 "%s: in middle of FTM START", __func__);
8277 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8278 msecs_to_jiffies(20000));
8279 if(!lrc)
8280 {
8281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8282 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8283 }
8284 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008285 wlan_hdd_ftm_close(pHddCtx);
8286 goto free_hdd_ctx;
8287 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308288
Jeff Johnson295189b2012-06-20 16:38:30 -07008289 /* DeRegister with platform driver as client for Suspend/Resume */
8290 vosStatus = hddDeregisterPmOps(pHddCtx);
8291 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8292 {
8293 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8294 VOS_ASSERT(0);
8295 }
8296
8297 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8298 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8299 {
8300 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8301 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008302
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008303 //Stop the traffic monitor timer
8304 if ( VOS_TIMER_STATE_RUNNING ==
8305 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8306 {
8307 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8308 }
8309
8310 // Destroy the traffic monitor timer
8311 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8312 &pHddCtx->tx_rx_trafficTmr)))
8313 {
8314 hddLog(VOS_TRACE_LEVEL_ERROR,
8315 "%s: Cannot deallocate Traffic monitor timer", __func__);
8316 }
8317
Jeff Johnson295189b2012-06-20 16:38:30 -07008318 //Disable IMPS/BMPS as we do not want the device to enter any power
8319 //save mode during shutdown
8320 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8321 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8322 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8323
8324 //Ensure that device is in full power as we will touch H/W during vos_Stop
8325 init_completion(&powerContext.completion);
8326 powerContext.magic = POWER_CONTEXT_MAGIC;
8327
8328 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8329 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8330
8331 if (eHAL_STATUS_SUCCESS != halStatus)
8332 {
8333 if (eHAL_STATUS_PMC_PENDING == halStatus)
8334 {
8335 /* request was sent -- wait for the response */
8336 lrc = wait_for_completion_interruptible_timeout(
8337 &powerContext.completion,
8338 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008339 if (lrc <= 0)
8340 {
8341 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008342 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 }
8344 }
8345 else
8346 {
8347 hddLog(VOS_TRACE_LEVEL_ERROR,
8348 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008349 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008350 /* continue -- need to clean up as much as possible */
8351 }
8352 }
8353
Jeff Johnson72a40512013-12-19 10:14:15 -08008354 /* either we never sent a request, we sent a request and received a
8355 response or we sent a request and timed out. if we never sent a
8356 request or if we sent a request and got a response, we want to
8357 clear the magic out of paranoia. if we timed out there is a
8358 race condition such that the callback function could be
8359 executing at the same time we are. of primary concern is if the
8360 callback function had already verified the "magic" but had not
8361 yet set the completion variable when a timeout occurred. we
8362 serialize these activities by invalidating the magic while
8363 holding a shared spinlock which will cause us to block if the
8364 callback is currently executing */
8365 spin_lock(&hdd_context_lock);
8366 powerContext.magic = 0;
8367 spin_unlock(&hdd_context_lock);
8368
Yue Ma0d4891e2013-08-06 17:01:45 -07008369 hdd_debugfs_exit(pHddCtx);
8370
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 // Unregister the Net Device Notifier
8372 unregister_netdevice_notifier(&hdd_netdev_notifier);
8373
Jeff Johnson295189b2012-06-20 16:38:30 -07008374 hdd_stop_all_adapters( pHddCtx );
8375
Jeff Johnson295189b2012-06-20 16:38:30 -07008376#ifdef WLAN_BTAMP_FEATURE
8377 vosStatus = WLANBAP_Stop(pVosContext);
8378 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8379 {
8380 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8381 "%s: Failed to stop BAP",__func__);
8382 }
8383#endif //WLAN_BTAMP_FEATURE
8384
8385 //Stop all the modules
8386 vosStatus = vos_stop( pVosContext );
8387 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8388 {
8389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8390 "%s: Failed to stop VOSS",__func__);
8391 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8392 }
8393
Jeff Johnson295189b2012-06-20 16:38:30 -07008394 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008395 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008396
8397 //Close the scheduler before calling vos_close to make sure no thread is
8398 // scheduled after the each module close is called i.e after all the data
8399 // structures are freed.
8400 vosStatus = vos_sched_close( pVosContext );
8401 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8402 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8403 "%s: Failed to close VOSS Scheduler",__func__);
8404 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8405 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008406#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008407#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8408 /* Destroy the wake lock */
8409 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8410#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008411 /* Destroy the wake lock */
8412 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008413#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008414
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308415#ifdef CONFIG_ENABLE_LINUX_REG
8416 vosStatus = vos_nv_close();
8417 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8418 {
8419 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8420 "%s: Failed to close NV", __func__);
8421 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8422 }
8423#endif
8424
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 //Close VOSS
8426 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8427 vos_close(pVosContext);
8428
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 //Close Watchdog
8430 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8431 vos_watchdog_close(pVosContext);
8432
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308433 //Clean up HDD Nlink Service
8434 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308435
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308436#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308437 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308438 {
8439 wlan_logging_sock_deactivate_svc();
8440 }
8441#endif
8442
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308443#ifdef WLAN_KD_READY_NOTIFIER
8444 nl_srv_exit(pHddCtx->ptt_pid);
8445#else
8446 nl_srv_exit();
8447#endif /* WLAN_KD_READY_NOTIFIER */
8448
8449
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 hdd_close_all_adapters( pHddCtx );
8451
Jeff Johnson295189b2012-06-20 16:38:30 -07008452 /* free the power on lock from platform driver */
8453 if (free_riva_power_on_lock("wlan"))
8454 {
8455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8456 __func__);
8457 }
8458
Jeff Johnson88ba7742013-02-27 14:36:02 -08008459free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308460
8461 //Free up dynamically allocated members inside HDD Adapter
8462 if (pHddCtx->cfg_ini)
8463 {
8464 kfree(pHddCtx->cfg_ini);
8465 pHddCtx->cfg_ini= NULL;
8466 }
8467
Leo Changf04ddad2013-09-18 13:46:38 -07008468 /* FTM mode, WIPHY did not registered
8469 If un-register here, system crash will happen */
8470 if (VOS_FTM_MODE != hdd_get_conparam())
8471 {
8472 wiphy_unregister(wiphy) ;
8473 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 if (hdd_is_ssr_required())
8476 {
8477 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008478 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 msleep(5000);
8480 }
8481 hdd_set_ssr_required (VOS_FALSE);
8482}
8483
8484
8485/**---------------------------------------------------------------------------
8486
8487 \brief hdd_update_config_from_nv() - Function to update the contents of
8488 the running configuration with parameters taken from NV storage
8489
8490 \param - pHddCtx - Pointer to the HDD global context
8491
8492 \return - VOS_STATUS_SUCCESS if successful
8493
8494 --------------------------------------------------------------------------*/
8495static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8496{
Jeff Johnson295189b2012-06-20 16:38:30 -07008497 v_BOOL_t itemIsValid = VOS_FALSE;
8498 VOS_STATUS status;
8499 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8500 v_U8_t macLoop;
8501
8502 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8503 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8504 if(status != VOS_STATUS_SUCCESS)
8505 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008506 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008507 return VOS_STATUS_E_FAILURE;
8508 }
8509
8510 if (itemIsValid == VOS_TRUE)
8511 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008512 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008513 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8514 VOS_MAX_CONCURRENCY_PERSONA);
8515 if(status != VOS_STATUS_SUCCESS)
8516 {
8517 /* Get MAC from NV fail, not update CFG info
8518 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008519 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008520 return VOS_STATUS_E_FAILURE;
8521 }
8522
8523 /* If first MAC is not valid, treat all others are not valid
8524 * Then all MACs will be got from ini file */
8525 if(vos_is_macaddr_zero(&macFromNV[0]))
8526 {
8527 /* MAC address in NV file is not configured yet */
8528 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8529 return VOS_STATUS_E_INVAL;
8530 }
8531
8532 /* Get MAC address from NV, update CFG info */
8533 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8534 {
8535 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8536 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308537 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008538 /* This MAC is not valid, skip it
8539 * This MAC will be got from ini file */
8540 }
8541 else
8542 {
8543 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8544 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8545 VOS_MAC_ADDR_SIZE);
8546 }
8547 }
8548 }
8549 else
8550 {
8551 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8552 return VOS_STATUS_E_FAILURE;
8553 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008554
Jeff Johnson295189b2012-06-20 16:38:30 -07008555
8556 return VOS_STATUS_SUCCESS;
8557}
8558
8559/**---------------------------------------------------------------------------
8560
8561 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8562
8563 \param - pAdapter - Pointer to the HDD
8564
8565 \return - None
8566
8567 --------------------------------------------------------------------------*/
8568VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8569{
8570 eHalStatus halStatus;
8571 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308572 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008573
Jeff Johnson295189b2012-06-20 16:38:30 -07008574
8575 // Send ready indication to the HDD. This will kick off the MAC
8576 // into a 'running' state and should kick off an initial scan.
8577 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8578 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8579 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308580 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008581 "code %08d [x%08x]",__func__, halStatus, halStatus );
8582 return VOS_STATUS_E_FAILURE;
8583 }
8584
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308585 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008586 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8587 // And RIVA will crash
8588 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8589 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308590 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8591 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8592
8593
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 return VOS_STATUS_SUCCESS;
8595}
8596
Jeff Johnson295189b2012-06-20 16:38:30 -07008597/* wake lock APIs for HDD */
8598void hdd_prevent_suspend(void)
8599{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008600#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008601 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008602#else
8603 wcnss_prevent_suspend();
8604#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008605}
8606
8607void hdd_allow_suspend(void)
8608{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008609#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008610 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008611#else
8612 wcnss_allow_suspend();
8613#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008614}
8615
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308616void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008617{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008618#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008619 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008620#else
8621 /* Do nothing as there is no API in wcnss for timeout*/
8622#endif
8623}
8624
Jeff Johnson295189b2012-06-20 16:38:30 -07008625/**---------------------------------------------------------------------------
8626
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008627 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8628 information between Host and Riva
8629
8630 This function gets reported version of FW
8631 It also finds the version of Riva headers used to compile the host
8632 It compares the above two and prints a warning if they are different
8633 It gets the SW and HW version string
8634 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8635 indicating the features they support through a bitmap
8636
8637 \param - pHddCtx - Pointer to HDD context
8638
8639 \return - void
8640
8641 --------------------------------------------------------------------------*/
8642
8643void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8644{
8645
8646 tSirVersionType versionCompiled;
8647 tSirVersionType versionReported;
8648 tSirVersionString versionString;
8649 tANI_U8 fwFeatCapsMsgSupported = 0;
8650 VOS_STATUS vstatus;
8651
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008652 memset(&versionCompiled, 0, sizeof(versionCompiled));
8653 memset(&versionReported, 0, sizeof(versionReported));
8654
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008655 /* retrieve and display WCNSS version information */
8656 do {
8657
8658 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8659 &versionCompiled);
8660 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8661 {
8662 hddLog(VOS_TRACE_LEVEL_FATAL,
8663 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008664 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008665 break;
8666 }
8667
8668 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8669 &versionReported);
8670 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8671 {
8672 hddLog(VOS_TRACE_LEVEL_FATAL,
8673 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008674 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008675 break;
8676 }
8677
8678 if ((versionCompiled.major != versionReported.major) ||
8679 (versionCompiled.minor != versionReported.minor) ||
8680 (versionCompiled.version != versionReported.version) ||
8681 (versionCompiled.revision != versionReported.revision))
8682 {
8683 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8684 "Host expected %u.%u.%u.%u\n",
8685 WLAN_MODULE_NAME,
8686 (int)versionReported.major,
8687 (int)versionReported.minor,
8688 (int)versionReported.version,
8689 (int)versionReported.revision,
8690 (int)versionCompiled.major,
8691 (int)versionCompiled.minor,
8692 (int)versionCompiled.version,
8693 (int)versionCompiled.revision);
8694 }
8695 else
8696 {
8697 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8698 WLAN_MODULE_NAME,
8699 (int)versionReported.major,
8700 (int)versionReported.minor,
8701 (int)versionReported.version,
8702 (int)versionReported.revision);
8703 }
8704
8705 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8706 versionString,
8707 sizeof(versionString));
8708 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8709 {
8710 hddLog(VOS_TRACE_LEVEL_FATAL,
8711 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008712 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008713 break;
8714 }
8715
8716 pr_info("%s: WCNSS software version %s\n",
8717 WLAN_MODULE_NAME, versionString);
8718
8719 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8720 versionString,
8721 sizeof(versionString));
8722 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8723 {
8724 hddLog(VOS_TRACE_LEVEL_FATAL,
8725 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008726 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008727 break;
8728 }
8729
8730 pr_info("%s: WCNSS hardware version %s\n",
8731 WLAN_MODULE_NAME, versionString);
8732
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008733 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8734 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008735 send the message only if it the riva is 1.1
8736 minor numbers for different riva branches:
8737 0 -> (1.0)Mainline Build
8738 1 -> (1.1)Mainline Build
8739 2->(1.04) Stability Build
8740 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008741 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008742 ((versionReported.minor>=1) && (versionReported.version>=1)))
8743 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8744 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008745
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008746 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008747 {
8748#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8749 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8750 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8751#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008752 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8753 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8754 {
8755 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8756 }
8757
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008758 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008759 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008760
8761 } while (0);
8762
8763}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308764void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8765{
8766 struct sk_buff *skb;
8767 struct nlmsghdr *nlh;
8768 tAniMsgHdr *ani_hdr;
8769
8770 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8771
8772 if(skb == NULL) {
8773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8774 "%s: alloc_skb failed", __func__);
8775 return;
8776 }
8777
8778 nlh = (struct nlmsghdr *)skb->data;
8779 nlh->nlmsg_pid = 0; /* from kernel */
8780 nlh->nlmsg_flags = 0;
8781 nlh->nlmsg_seq = 0;
8782 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8783
8784 ani_hdr = NLMSG_DATA(nlh);
8785 ani_hdr->type = type;
8786
8787 switch(type) {
8788 case WLAN_SVC_SAP_RESTART_IND:
8789 ani_hdr->length = 0;
8790 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8791 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8792 break;
8793 default:
8794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8795 "Attempt to send unknown nlink message %d", type);
8796 kfree_skb(skb);
8797 return;
8798 }
8799
8800 nl_srv_bcast(skb);
8801
8802 return;
8803}
8804
8805
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008806
8807/**---------------------------------------------------------------------------
8808
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308809 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8810
8811 \param - pHddCtx - Pointer to the hdd context
8812
8813 \return - true if hardware supports 5GHz
8814
8815 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308816boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308817{
8818 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8819 * then hardware support 5Ghz.
8820 */
8821 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8822 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308823 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308824 return true;
8825 }
8826 else
8827 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308829 __func__);
8830 return false;
8831 }
8832}
8833
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308834/**---------------------------------------------------------------------------
8835
8836 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8837 generate function
8838
8839 This is generate the random mac address for WLAN interface
8840
8841 \param - pHddCtx - Pointer to HDD context
8842 idx - Start interface index to get auto
8843 generated mac addr.
8844 mac_addr - Mac address
8845
8846 \return - 0 for success, < 0 for failure
8847
8848 --------------------------------------------------------------------------*/
8849
8850static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8851 int idx, v_MACADDR_t mac_addr)
8852{
8853 int i;
8854 unsigned int serialno;
8855 serialno = wcnss_get_serial_number();
8856
8857 if (0 != serialno)
8858 {
8859 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8860 bytes of the serial number that can be used to generate
8861 the other 3 bytes of the MAC address. Mask off all but
8862 the lower 3 bytes (this will also make sure we don't
8863 overflow in the next step) */
8864 serialno &= 0x00FFFFFF;
8865
8866 /* we need a unique address for each session */
8867 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8868
8869 /* autogen other Mac addresses */
8870 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8871 {
8872 /* start with the entire default address */
8873 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8874 /* then replace the lower 3 bytes */
8875 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8876 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8877 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8878
8879 serialno++;
8880 hddLog(VOS_TRACE_LEVEL_ERROR,
8881 "%s: Derived Mac Addr: "
8882 MAC_ADDRESS_STR, __func__,
8883 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8884 }
8885
8886 }
8887 else
8888 {
8889 hddLog(LOGE, FL("Failed to Get Serial NO"));
8890 return -1;
8891 }
8892 return 0;
8893}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308894
8895/**---------------------------------------------------------------------------
8896
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308897 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8898 completed to flush out the scan results
8899
8900 11d scan is done during driver load and is a passive scan on all
8901 channels supported by the device, 11d scans may find some APs on
8902 frequencies which are forbidden to be used in the regulatory domain
8903 the device is operating in. If these APs are notified to the supplicant
8904 it may try to connect to these APs, thus flush out all the scan results
8905 which are present in SME after 11d scan is done.
8906
8907 \return - eHalStatus
8908
8909 --------------------------------------------------------------------------*/
8910static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8911 tANI_U32 scanId, eCsrScanStatus status)
8912{
8913 ENTER();
8914
8915 sme_ScanFlushResult(halHandle, 0);
8916
8917 EXIT();
8918
8919 return eHAL_STATUS_SUCCESS;
8920}
8921
8922/**---------------------------------------------------------------------------
8923
Jeff Johnson295189b2012-06-20 16:38:30 -07008924 \brief hdd_wlan_startup() - HDD init function
8925
8926 This is the driver startup code executed once a WLAN device has been detected
8927
8928 \param - dev - Pointer to the underlying device
8929
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008930 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008931
8932 --------------------------------------------------------------------------*/
8933
8934int hdd_wlan_startup(struct device *dev )
8935{
8936 VOS_STATUS status;
8937 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008938 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 hdd_context_t *pHddCtx = NULL;
8940 v_CONTEXT_t pVosContext= NULL;
8941#ifdef WLAN_BTAMP_FEATURE
8942 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8943 WLANBAP_ConfigType btAmpConfig;
8944 hdd_config_t *pConfig;
8945#endif
8946 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308948 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008949
8950 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008951 /*
8952 * cfg80211: wiphy allocation
8953 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308954 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008955
8956 if(wiphy == NULL)
8957 {
8958 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008959 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008960 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 pHddCtx = wiphy_priv(wiphy);
8962
Jeff Johnson295189b2012-06-20 16:38:30 -07008963 //Initialize the adapter context to zeros.
8964 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8965
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308968 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008969
8970 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8971
8972 /*Get vos context here bcoz vos_open requires it*/
8973 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8974
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008975 if(pVosContext == NULL)
8976 {
8977 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8978 goto err_free_hdd_context;
8979 }
8980
Jeff Johnson295189b2012-06-20 16:38:30 -07008981 //Save the Global VOSS context in adapter context for future.
8982 pHddCtx->pvosContext = pVosContext;
8983
8984 //Save the adapter context in global context for future.
8985 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8986
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 pHddCtx->parent_dev = dev;
8988
8989 init_completion(&pHddCtx->full_pwr_comp_var);
8990 init_completion(&pHddCtx->standby_comp_var);
8991 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008992 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008993 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308994 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308995 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008996
8997#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008998 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008999#else
9000 init_completion(&pHddCtx->driver_crda_req);
9001#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009002
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309003 spin_lock_init(&pHddCtx->schedScan_lock);
9004
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
9006
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309007#ifdef FEATURE_WLAN_TDLS
9008 /* tdls_lock is initialized before an hdd_open_adapter ( which is
9009 * invoked by other instances also) to protect the concurrent
9010 * access for the Adapters by TDLS module.
9011 */
9012 mutex_init(&pHddCtx->tdls_lock);
9013#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05309014 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05309015 mutex_init(&pHddCtx->wmmLock);
9016
Agarwal Ashish1f422872014-07-22 00:11:55 +05309017 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309018
Agarwal Ashish1f422872014-07-22 00:11:55 +05309019 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 // Load all config first as TL config is needed during vos_open
9021 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9022 if(pHddCtx->cfg_ini == NULL)
9023 {
9024 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9025 goto err_free_hdd_context;
9026 }
9027
9028 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9029
9030 // Read and parse the qcom_cfg.ini file
9031 status = hdd_parse_config_ini( pHddCtx );
9032 if ( VOS_STATUS_SUCCESS != status )
9033 {
9034 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9035 __func__, WLAN_INI_FILE);
9036 goto err_config;
9037 }
Arif Hussaind5218912013-12-05 01:10:55 -08009038#ifdef MEMORY_DEBUG
9039 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9040 vos_mem_init();
9041
9042 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9043 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9044#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009045
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309046 /* INI has been read, initialise the configuredMcastBcastFilter with
9047 * INI value as this will serve as the default value
9048 */
9049 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9050 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9051 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309052
9053 if (false == hdd_is_5g_supported(pHddCtx))
9054 {
9055 //5Ghz is not supported.
9056 if (1 != pHddCtx->cfg_ini->nBandCapability)
9057 {
9058 hddLog(VOS_TRACE_LEVEL_INFO,
9059 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9060 pHddCtx->cfg_ini->nBandCapability = 1;
9061 }
9062 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309063
9064 /* If SNR Monitoring is enabled, FW has to parse all beacons
9065 * for calcaluting and storing the average SNR, so set Nth beacon
9066 * filter to 1 to enable FW to parse all the beaocons
9067 */
9068 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9069 {
9070 /* The log level is deliberately set to WARN as overriding
9071 * nthBeaconFilter to 1 will increase power cosumption and this
9072 * might just prove helpful to detect the power issue.
9073 */
9074 hddLog(VOS_TRACE_LEVEL_WARN,
9075 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9076 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9077 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009078 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309079 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009080 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009081 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009082 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009083 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9084 {
9085 hddLog(VOS_TRACE_LEVEL_FATAL,
9086 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9087 goto err_config;
9088 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009089 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009090
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009091 // Update VOS trace levels based upon the cfg.ini
9092 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9093 pHddCtx->cfg_ini->vosTraceEnableBAP);
9094 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9095 pHddCtx->cfg_ini->vosTraceEnableTL);
9096 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9097 pHddCtx->cfg_ini->vosTraceEnableWDI);
9098 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9099 pHddCtx->cfg_ini->vosTraceEnableHDD);
9100 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9101 pHddCtx->cfg_ini->vosTraceEnableSME);
9102 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9103 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309104 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9105 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009106 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9107 pHddCtx->cfg_ini->vosTraceEnableWDA);
9108 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9109 pHddCtx->cfg_ini->vosTraceEnableSYS);
9110 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9111 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009112 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9113 pHddCtx->cfg_ini->vosTraceEnableSAP);
9114 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9115 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009116
Jeff Johnson295189b2012-06-20 16:38:30 -07009117 // Update WDI trace levels based upon the cfg.ini
9118 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9119 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9120 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9121 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9122 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9123 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9124 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9125 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009126
Jeff Johnson88ba7742013-02-27 14:36:02 -08009127 if (VOS_FTM_MODE == hdd_get_conparam())
9128 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009129 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9130 {
9131 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9132 goto err_free_hdd_context;
9133 }
9134 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309135 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309136 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009137 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009138 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009139
Jeff Johnson88ba7742013-02-27 14:36:02 -08009140 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9142 {
9143 status = vos_watchdog_open(pVosContext,
9144 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9145
9146 if(!VOS_IS_STATUS_SUCCESS( status ))
9147 {
9148 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309149 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 }
9151 }
9152
9153 pHddCtx->isLogpInProgress = FALSE;
9154 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9155
Amar Singhala49cbc52013-10-08 18:37:44 -07009156#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009157 /* initialize the NV module. This is required so that
9158 we can initialize the channel information in wiphy
9159 from the NV.bin data. The channel information in
9160 wiphy needs to be initialized before wiphy registration */
9161
9162 status = vos_nv_open();
9163 if (!VOS_IS_STATUS_SUCCESS(status))
9164 {
9165 /* NV module cannot be initialized */
9166 hddLog( VOS_TRACE_LEVEL_FATAL,
9167 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309168 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009169 }
9170
9171 status = vos_init_wiphy_from_nv_bin();
9172 if (!VOS_IS_STATUS_SUCCESS(status))
9173 {
9174 /* NV module cannot be initialized */
9175 hddLog( VOS_TRACE_LEVEL_FATAL,
9176 "%s: vos_init_wiphy failed", __func__);
9177 goto err_vos_nv_close;
9178 }
9179
Amar Singhala49cbc52013-10-08 18:37:44 -07009180#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309181 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309182 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009183 if ( !VOS_IS_STATUS_SUCCESS( status ))
9184 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009185 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309186 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009187 }
9188
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9190
9191 if ( NULL == pHddCtx->hHal )
9192 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009193 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 goto err_vosclose;
9195 }
9196
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009197 status = vos_preStart( pHddCtx->pvosContext );
9198 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9199 {
9200 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309201 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009202 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009203
Arif Hussaineaf68602013-12-30 23:10:44 -08009204 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9205 {
9206 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9207 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9208 __func__, enable_dfs_chan_scan);
9209 }
9210 if (0 == enable_11d || 1 == enable_11d)
9211 {
9212 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9213 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9214 __func__, enable_11d);
9215 }
9216
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009217 /* Note that the vos_preStart() sequence triggers the cfg download.
9218 The cfg download must occur before we update the SME config
9219 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 status = hdd_set_sme_config( pHddCtx );
9221
9222 if ( VOS_STATUS_SUCCESS != status )
9223 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009224 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309225 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009226 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009227
Jeff Johnson295189b2012-06-20 16:38:30 -07009228 /* In the integrated architecture we update the configuration from
9229 the INI file and from NV before vOSS has been started so that
9230 the final contents are available to send down to the cCPU */
9231
9232 // Apply the cfg.ini to cfg.dat
9233 if (FALSE == hdd_update_config_dat(pHddCtx))
9234 {
9235 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309236 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009237 }
9238
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309239 // Get mac addr from platform driver
9240 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9241
9242 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309244 /* Store the mac addr for first interface */
9245 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9246
9247 hddLog(VOS_TRACE_LEVEL_ERROR,
9248 "%s: WLAN Mac Addr: "
9249 MAC_ADDRESS_STR, __func__,
9250 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9251
9252 /* Here, passing Arg2 as 1 because we do not want to change the
9253 last 3 bytes (means non OUI bytes) of first interface mac
9254 addr.
9255 */
9256 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9257 {
9258 hddLog(VOS_TRACE_LEVEL_ERROR,
9259 "%s: Failed to generate wlan interface mac addr "
9260 "using MAC from ini file ", __func__);
9261 }
9262 }
9263 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9264 {
9265 // Apply the NV to cfg.dat
9266 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009267#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9268 /* There was not a valid set of MAC Addresses in NV. See if the
9269 default addresses were modified by the cfg.ini settings. If so,
9270 we'll use them, but if not, we'll autogenerate a set of MAC
9271 addresses based upon the device serial number */
9272
9273 static const v_MACADDR_t default_address =
9274 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009275
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309276 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9277 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 {
9279 /* cfg.ini has the default address, invoke autogen logic */
9280
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309281 /* Here, passing Arg2 as 0 because we want to change the
9282 last 3 bytes (means non OUI bytes) of all the interfaces
9283 mac addr.
9284 */
9285 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9286 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309288 hddLog(VOS_TRACE_LEVEL_ERROR,
9289 "%s: Failed to generate wlan interface mac addr "
9290 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9291 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009292 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 }
9294 else
9295#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9296 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009297 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 "%s: Invalid MAC address in NV, using MAC from ini file "
9299 MAC_ADDRESS_STR, __func__,
9300 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9301 }
9302 }
9303 {
9304 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309305
9306 /* Set the MAC Address Currently this is used by HAL to
9307 * add self sta. Remove this once self sta is added as
9308 * part of session open.
9309 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009310 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9311 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9312 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309313
Jeff Johnson295189b2012-06-20 16:38:30 -07009314 if (!HAL_STATUS_SUCCESS( halStatus ))
9315 {
9316 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9317 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309318 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 }
9320 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009321
9322 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9323 Note: Firmware image will be read and downloaded inside vos_start API */
9324 status = vos_start( pHddCtx->pvosContext );
9325 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9326 {
9327 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309328 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009329 }
9330
Leo Chang6cec3e22014-01-21 15:33:49 -08009331#ifdef FEATURE_WLAN_CH_AVOID
9332 /* Plug in avoid channel notification callback
9333 * This should happen before ADD_SELF_STA
9334 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309335
9336 /* check the Channel Avoidance is enabled */
9337 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9338 {
9339 sme_AddChAvoidCallback(pHddCtx->hHal,
9340 hdd_hostapd_ch_avoid_cb);
9341 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009342#endif /* FEATURE_WLAN_CH_AVOID */
9343
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009344 /* Exchange capability info between Host and FW and also get versioning info from FW */
9345 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009346
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309347#ifdef CONFIG_ENABLE_LINUX_REG
9348 status = wlan_hdd_init_channels(pHddCtx);
9349 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9350 {
9351 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9352 __func__);
9353 goto err_vosstop;
9354 }
9355#endif
9356
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 status = hdd_post_voss_start_config( pHddCtx );
9358 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9359 {
9360 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9361 __func__);
9362 goto err_vosstop;
9363 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009364
9365#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309366 wlan_hdd_cfg80211_update_reg_info( wiphy );
9367
9368 /* registration of wiphy dev with cfg80211 */
9369 if (0 > wlan_hdd_cfg80211_register(wiphy))
9370 {
9371 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9372 goto err_vosstop;
9373 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009374#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009375
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309376#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309377 /* registration of wiphy dev with cfg80211 */
9378 if (0 > wlan_hdd_cfg80211_register(wiphy))
9379 {
9380 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9381 goto err_vosstop;
9382 }
9383
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309384 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309385 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9386 {
9387 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9388 __func__);
9389 goto err_unregister_wiphy;
9390 }
9391#endif
9392
c_hpothu4a298be2014-12-22 21:12:51 +05309393 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9394
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9396 {
9397 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9398 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9399 }
9400 else
9401 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009402 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9403 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9404 if (pAdapter != NULL)
9405 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309406 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009407 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309408 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9409 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9410 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009411
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309412 /* Generate the P2P Device Address. This consists of the device's
9413 * primary MAC address with the locally administered bit set.
9414 */
9415 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009416 }
9417 else
9418 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309419 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9420 if (p2p_dev_addr != NULL)
9421 {
9422 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9423 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9424 }
9425 else
9426 {
9427 hddLog(VOS_TRACE_LEVEL_FATAL,
9428 "%s: Failed to allocate mac_address for p2p_device",
9429 __func__);
9430 goto err_close_adapter;
9431 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009432 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009433
9434 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9435 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9436 if ( NULL == pP2pAdapter )
9437 {
9438 hddLog(VOS_TRACE_LEVEL_FATAL,
9439 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009440 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009441 goto err_close_adapter;
9442 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009443 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009444 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009445
9446 if( pAdapter == NULL )
9447 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009448 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9449 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009451
Arif Hussain66559122013-11-21 10:11:40 -08009452 if (country_code)
9453 {
9454 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009455 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009456 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9457#ifndef CONFIG_ENABLE_LINUX_REG
9458 hdd_checkandupdate_phymode(pAdapter, country_code);
9459#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009460 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9461 (void *)(tSmeChangeCountryCallback)
9462 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009463 country_code,
9464 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309465 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009466 if (eHAL_STATUS_SUCCESS == ret)
9467 {
Arif Hussaincb607082013-12-20 11:57:42 -08009468 ret = wait_for_completion_interruptible_timeout(
9469 &pAdapter->change_country_code,
9470 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9471
9472 if (0 >= ret)
9473 {
9474 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9475 "%s: SME while setting country code timed out", __func__);
9476 }
Arif Hussain66559122013-11-21 10:11:40 -08009477 }
9478 else
9479 {
Arif Hussaincb607082013-12-20 11:57:42 -08009480 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9481 "%s: SME Change Country code from module param fail ret=%d",
9482 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009483 }
9484 }
9485
Jeff Johnson295189b2012-06-20 16:38:30 -07009486#ifdef WLAN_BTAMP_FEATURE
9487 vStatus = WLANBAP_Open(pVosContext);
9488 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9489 {
9490 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9491 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009492 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 }
9494
9495 vStatus = BSL_Init(pVosContext);
9496 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9497 {
9498 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9499 "%s: Failed to Init BSL",__func__);
9500 goto err_bap_close;
9501 }
9502 vStatus = WLANBAP_Start(pVosContext);
9503 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9504 {
9505 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9506 "%s: Failed to start TL",__func__);
9507 goto err_bap_close;
9508 }
9509
9510 pConfig = pHddCtx->cfg_ini;
9511 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9512 status = WLANBAP_SetConfig(&btAmpConfig);
9513
9514#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009515
Mihir Shete9c238772014-10-15 14:35:16 +05309516 /*
9517 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9518 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9519 * which is greater than 0xf. So the below check is safe to make
9520 * sure that there is no entry for UapsdMask in the ini
9521 */
9522 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9523 {
9524 if(IS_DYNAMIC_WMM_PS_ENABLED)
9525 {
9526 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9527 __func__);
9528 pHddCtx->cfg_ini->UapsdMask =
9529 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9530 }
9531 else
9532 {
9533 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9534 __func__);
9535 pHddCtx->cfg_ini->UapsdMask =
9536 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9537 }
9538 }
9539
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009540#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9541 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9542 {
9543 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9544 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9545 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9546 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9547 }
9548#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009549
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309550 wlan_hdd_tdls_init(pHddCtx);
9551
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309552 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9553
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 /* Register with platform driver as client for Suspend/Resume */
9555 status = hddRegisterPmOps(pHddCtx);
9556 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9557 {
9558 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9559#ifdef WLAN_BTAMP_FEATURE
9560 goto err_bap_stop;
9561#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009562 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009563#endif //WLAN_BTAMP_FEATURE
9564 }
9565
Yue Ma0d4891e2013-08-06 17:01:45 -07009566 /* Open debugfs interface */
9567 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9568 {
9569 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9570 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009571 }
9572
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 /* Register TM level change handler function to the platform */
9574 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9575 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9576 {
9577 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9578 goto err_unregister_pmops;
9579 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009580
9581 /* register for riva power on lock to platform driver */
9582 if (req_riva_power_on_lock("wlan"))
9583 {
9584 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9585 __func__);
9586 goto err_unregister_pmops;
9587 }
9588
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 // register net device notifier for device change notification
9590 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9591
9592 if(ret < 0)
9593 {
9594 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9595 goto err_free_power_on_lock;
9596 }
9597
9598 //Initialize the nlink service
9599 if(nl_srv_init() != 0)
9600 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309601 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009602 goto err_reg_netdev;
9603 }
9604
Leo Chang4ce1cc52013-10-21 18:27:15 -07009605#ifdef WLAN_KD_READY_NOTIFIER
9606 pHddCtx->kd_nl_init = 1;
9607#endif /* WLAN_KD_READY_NOTIFIER */
9608
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 //Initialize the BTC service
9610 if(btc_activate_service(pHddCtx) != 0)
9611 {
9612 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9613 goto err_nl_srv;
9614 }
9615
9616#ifdef PTT_SOCK_SVC_ENABLE
9617 //Initialize the PTT service
9618 if(ptt_sock_activate_svc(pHddCtx) != 0)
9619 {
9620 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9621 goto err_nl_srv;
9622 }
9623#endif
9624
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309625#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9626 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9627 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309628 if(wlan_logging_sock_activate_svc(
9629 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9630 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9631 {
9632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9633 " failed", __func__);
9634 goto err_nl_srv;
9635 }
9636 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9637 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309638 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9639 pHddCtx->cfg_ini->gEnableDebugLog =
9640 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309641 }
9642#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009646 /* Action frame registered in one adapter which will
9647 * applicable to all interfaces
9648 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309649 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009651
9652 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309653 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009654
Jeff Johnson295189b2012-06-20 16:38:30 -07009655
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009656#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009657#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9658 /* Initialize the wake lcok */
9659 wake_lock_init(&pHddCtx->rx_wake_lock,
9660 WAKE_LOCK_SUSPEND,
9661 "qcom_rx_wakelock");
9662#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009663 /* Initialize the wake lcok */
9664 wake_lock_init(&pHddCtx->sap_wake_lock,
9665 WAKE_LOCK_SUSPEND,
9666 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009667#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009668
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009669 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9670 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009671
Katya Nigam5c306ea2014-06-19 15:39:54 +05309672 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9674 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309675
9676#ifdef FEATURE_WLAN_SCAN_PNO
9677 /*SME must send channel update configuration to RIVA*/
9678 sme_UpdateChannelConfig(pHddCtx->hHal);
9679#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309680 /* Send the update default channel list to the FW*/
9681 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309682#ifndef CONFIG_ENABLE_LINUX_REG
9683 /*updating wiphy so that regulatory user hints can be processed*/
9684 if (wiphy)
9685 {
9686 regulatory_hint(wiphy, "00");
9687 }
9688#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009689 // Initialize the restart logic
9690 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309691
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009692 //Register the traffic monitor timer now
9693 if ( pHddCtx->cfg_ini->dynSplitscan)
9694 {
9695 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9696 VOS_TIMER_TYPE_SW,
9697 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9698 (void *)pHddCtx);
9699 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309700#ifdef WLAN_FEATURE_EXTSCAN
9701 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9702 wlan_hdd_cfg80211_extscan_callback,
9703 pHddCtx);
9704#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309705
9706#ifdef WLAN_NS_OFFLOAD
9707 // Register IPv6 notifier to notify if any change in IP
9708 // So that we can reconfigure the offload parameters
9709 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
9710 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
9711 if (ret)
9712 {
9713 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
9714 }
9715 else
9716 {
9717 hddLog(LOGE, FL("Registered IPv6 notifier"));
9718 }
9719#endif
9720
9721 // Register IPv4 notifier to notify if any change in IP
9722 // So that we can reconfigure the offload parameters
9723 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
9724 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
9725 if (ret)
9726 {
9727 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
9728 }
9729 else
9730 {
9731 hddLog(LOGE, FL("Registered IPv4 notifier"));
9732 }
9733
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 goto success;
9735
9736err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009737#ifdef WLAN_KD_READY_NOTIFIER
9738 nl_srv_exit(pHddCtx->ptt_pid);
9739#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009741#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009742err_reg_netdev:
9743 unregister_netdevice_notifier(&hdd_netdev_notifier);
9744
9745err_free_power_on_lock:
9746 free_riva_power_on_lock("wlan");
9747
9748err_unregister_pmops:
9749 hddDevTmUnregisterNotifyCallback(pHddCtx);
9750 hddDeregisterPmOps(pHddCtx);
9751
Yue Ma0d4891e2013-08-06 17:01:45 -07009752 hdd_debugfs_exit(pHddCtx);
9753
Jeff Johnson295189b2012-06-20 16:38:30 -07009754#ifdef WLAN_BTAMP_FEATURE
9755err_bap_stop:
9756 WLANBAP_Stop(pVosContext);
9757#endif
9758
9759#ifdef WLAN_BTAMP_FEATURE
9760err_bap_close:
9761 WLANBAP_Close(pVosContext);
9762#endif
9763
Jeff Johnson295189b2012-06-20 16:38:30 -07009764err_close_adapter:
9765 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309766#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309767err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309768#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309769 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009770err_vosstop:
9771 vos_stop(pVosContext);
9772
Amar Singhala49cbc52013-10-08 18:37:44 -07009773err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 status = vos_sched_close( pVosContext );
9775 if (!VOS_IS_STATUS_SUCCESS(status)) {
9776 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9777 "%s: Failed to close VOSS Scheduler", __func__);
9778 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9779 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009780 vos_close(pVosContext );
9781
Amar Singhal0a402232013-10-11 20:57:16 -07009782err_vos_nv_close:
9783
c_hpothue6a36282014-03-19 12:27:38 +05309784#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009785 vos_nv_close();
9786
c_hpothu70f8d812014-03-22 22:59:23 +05309787#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009788
9789err_wdclose:
9790 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9791 vos_watchdog_close(pVosContext);
9792
Jeff Johnson295189b2012-06-20 16:38:30 -07009793err_config:
9794 kfree(pHddCtx->cfg_ini);
9795 pHddCtx->cfg_ini= NULL;
9796
9797err_free_hdd_context:
9798 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 wiphy_free(wiphy) ;
9800 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 VOS_BUG(1);
9802
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009803 if (hdd_is_ssr_required())
9804 {
9805 /* WDI timeout had happened during load, so SSR is needed here */
9806 subsystem_restart("wcnss");
9807 msleep(5000);
9808 }
9809 hdd_set_ssr_required (VOS_FALSE);
9810
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009811 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009812
9813success:
9814 EXIT();
9815 return 0;
9816}
9817
9818/**---------------------------------------------------------------------------
9819
Jeff Johnson32d95a32012-09-10 13:15:23 -07009820 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009821
Jeff Johnson32d95a32012-09-10 13:15:23 -07009822 This is the driver entry point - called in different timeline depending
9823 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009824
9825 \param - None
9826
9827 \return - 0 for success, non zero for failure
9828
9829 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009830static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009831{
9832 VOS_STATUS status;
9833 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 struct device *dev = NULL;
9835 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009836#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9837 int max_retries = 0;
9838#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309839#ifdef HAVE_CBC_DONE
9840 int max_cbc_retries = 0;
9841#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009842
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309843#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9844 wlan_logging_sock_init_svc();
9845#endif
9846
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 ENTER();
9848
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009849#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009850 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009851#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009852
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309853 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009854 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9855 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9856
Jeff Johnson295189b2012-06-20 16:38:30 -07009857#ifdef ANI_BUS_TYPE_PCI
9858
9859 dev = wcnss_wlan_get_device();
9860
9861#endif // ANI_BUS_TYPE_PCI
9862
9863#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009864
9865#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9866 /* wait until WCNSS driver downloads NV */
9867 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9868 msleep(1000);
9869 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309870
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009871 if (max_retries >= 5) {
9872 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309873#ifdef WLAN_OPEN_SOURCE
9874 wake_lock_destroy(&wlan_wake_lock);
9875#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309876
9877#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9878 wlan_logging_sock_deinit_svc();
9879#endif
9880
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009881 return -ENODEV;
9882 }
9883#endif
9884
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309885#ifdef HAVE_CBC_DONE
9886 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
9887 msleep(1000);
9888 }
9889 if (max_cbc_retries >= 10) {
9890 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
9891 }
9892#endif
9893
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 dev = wcnss_wlan_get_device();
9895#endif // ANI_BUS_TYPE_PLATFORM
9896
9897
9898 do {
9899 if (NULL == dev) {
9900 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9901 ret_status = -1;
9902 break;
9903 }
9904
Jeff Johnson295189b2012-06-20 16:38:30 -07009905#ifdef TIMER_MANAGER
9906 vos_timer_manager_init();
9907#endif
9908
9909 /* Preopen VOSS so that it is ready to start at least SAL */
9910 status = vos_preOpen(&pVosContext);
9911
9912 if (!VOS_IS_STATUS_SUCCESS(status))
9913 {
9914 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9915 ret_status = -1;
9916 break;
9917 }
9918
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009919#ifndef MODULE
9920 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9921 */
9922 hdd_set_conparam((v_UINT_t)con_mode);
9923#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009924
9925 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009926 if (hdd_wlan_startup(dev))
9927 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009929 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 vos_preClose( &pVosContext );
9931 ret_status = -1;
9932 break;
9933 }
9934
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 } while (0);
9936
9937 if (0 != ret_status)
9938 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009939#ifdef TIMER_MANAGER
9940 vos_timer_exit();
9941#endif
9942#ifdef MEMORY_DEBUG
9943 vos_mem_exit();
9944#endif
9945
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009946#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009948#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309949
9950#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9951 wlan_logging_sock_deinit_svc();
9952#endif
9953
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9955 }
9956 else
9957 {
9958 //Send WLAN UP indication to Nlink Service
9959 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9960
9961 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009962 }
9963
9964 EXIT();
9965
9966 return ret_status;
9967}
9968
Jeff Johnson32d95a32012-09-10 13:15:23 -07009969/**---------------------------------------------------------------------------
9970
9971 \brief hdd_module_init() - Init Function
9972
9973 This is the driver entry point (invoked when module is loaded using insmod)
9974
9975 \param - None
9976
9977 \return - 0 for success, non zero for failure
9978
9979 --------------------------------------------------------------------------*/
9980#ifdef MODULE
9981static int __init hdd_module_init ( void)
9982{
9983 return hdd_driver_init();
9984}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009985#else /* #ifdef MODULE */
9986static int __init hdd_module_init ( void)
9987{
9988 /* Driver initialization is delayed to fwpath_changed_handler */
9989 return 0;
9990}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009991#endif /* #ifdef MODULE */
9992
Jeff Johnson295189b2012-06-20 16:38:30 -07009993
9994/**---------------------------------------------------------------------------
9995
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009996 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009997
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009998 This is the driver exit point (invoked when module is unloaded using rmmod
9999 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070010000
10001 \param - None
10002
10003 \return - None
10004
10005 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010006static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070010007{
10008 hdd_context_t *pHddCtx = NULL;
10009 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053010010 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053010011 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010012
10013 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
10014
10015 //Get the global vos context
10016 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
10017
10018 if(!pVosContext)
10019 {
10020 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10021 goto done;
10022 }
10023
10024 //Get the HDD context.
10025 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10026
10027 if(!pHddCtx)
10028 {
10029 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10030 }
10031 else
10032 {
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010033 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10034 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10035 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10036 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010038 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010039 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10040 msecs_to_jiffies(30000));
10041 if(!rc)
10042 {
10043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10044 "%s:SSR timedout, fatal error", __func__);
10045 VOS_BUG(0);
10046 }
10047 }
10048
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010049 rtnl_lock();
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010050 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10051 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010052 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -070010053
c_hpothu8adb97b2014-12-08 19:38:20 +053010054 /* Driver Need to send country code 00 in below condition
10055 * 1) If gCountryCodePriority is set to 1; and last country
10056 * code set is through 11d. This needs to be done in case
10057 * when NV country code is 00.
10058 * This Needs to be done as when kernel store last country
10059 * code and if stored country code is not through 11d,
10060 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10061 * in next load/unload as soon as we get any country through
10062 * 11d. In sme_HandleChangeCountryCodeByUser
10063 * pMsg->countryCode will be last countryCode and
10064 * pMac->scan.countryCode11d will be country through 11d so
10065 * due to mismatch driver will disable 11d.
10066 *
10067 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010068
c_hpothu8adb97b2014-12-08 19:38:20 +053010069 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010070 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010071 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010072 {
10073 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010074 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010075 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10076 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010077
c_hpothu8adb97b2014-12-08 19:38:20 +053010078 //Do all the cleanup before deregistering the driver
10079 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010080 }
10081
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 vos_preClose( &pVosContext );
10083
10084#ifdef TIMER_MANAGER
10085 vos_timer_exit();
10086#endif
10087#ifdef MEMORY_DEBUG
10088 vos_mem_exit();
10089#endif
10090
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010091#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10092 wlan_logging_sock_deinit_svc();
10093#endif
10094
Jeff Johnson295189b2012-06-20 16:38:30 -070010095done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010096#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010097 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010098#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010099
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10101}
10102
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010103/**---------------------------------------------------------------------------
10104
10105 \brief hdd_module_exit() - Exit function
10106
10107 This is the driver exit point (invoked when module is unloaded using rmmod)
10108
10109 \param - None
10110
10111 \return - None
10112
10113 --------------------------------------------------------------------------*/
10114static void __exit hdd_module_exit(void)
10115{
10116 hdd_driver_exit();
10117}
10118
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010119#ifdef MODULE
10120static int fwpath_changed_handler(const char *kmessage,
10121 struct kernel_param *kp)
10122{
Jeff Johnson76052702013-04-16 13:55:05 -070010123 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010124}
10125
10126static int con_mode_handler(const char *kmessage,
10127 struct kernel_param *kp)
10128{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010129 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010130}
10131#else /* #ifdef MODULE */
10132/**---------------------------------------------------------------------------
10133
Jeff Johnson76052702013-04-16 13:55:05 -070010134 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010135
Jeff Johnson76052702013-04-16 13:55:05 -070010136 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010137 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010138 - invoked when module parameter fwpath is modified from userspace to signal
10139 initializing the WLAN driver or when con_mode is modified from userspace
10140 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010141
10142 \return - 0 for success, non zero for failure
10143
10144 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010145static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010146{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010147 int ret_status;
10148
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010149 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010150 ret_status = hdd_driver_init();
10151 wlan_hdd_inited = ret_status ? 0 : 1;
10152 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010153 }
10154
10155 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010156
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010157 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010158
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010159 ret_status = hdd_driver_init();
10160 wlan_hdd_inited = ret_status ? 0 : 1;
10161 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010162}
10163
Jeff Johnson295189b2012-06-20 16:38:30 -070010164/**---------------------------------------------------------------------------
10165
Jeff Johnson76052702013-04-16 13:55:05 -070010166 \brief fwpath_changed_handler() - Handler Function
10167
10168 Handle changes to the fwpath parameter
10169
10170 \return - 0 for success, non zero for failure
10171
10172 --------------------------------------------------------------------------*/
10173static int fwpath_changed_handler(const char *kmessage,
10174 struct kernel_param *kp)
10175{
10176 int ret;
10177
10178 ret = param_set_copystring(kmessage, kp);
10179 if (0 == ret)
10180 ret = kickstart_driver();
10181 return ret;
10182}
10183
10184/**---------------------------------------------------------------------------
10185
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010186 \brief con_mode_handler() -
10187
10188 Handler function for module param con_mode when it is changed by userspace
10189 Dynamically linked - do nothing
10190 Statically linked - exit and init driver, as in rmmod and insmod
10191
Jeff Johnson76052702013-04-16 13:55:05 -070010192 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010193
Jeff Johnson76052702013-04-16 13:55:05 -070010194 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010195
10196 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010197static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010198{
Jeff Johnson76052702013-04-16 13:55:05 -070010199 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010200
Jeff Johnson76052702013-04-16 13:55:05 -070010201 ret = param_set_int(kmessage, kp);
10202 if (0 == ret)
10203 ret = kickstart_driver();
10204 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010205}
10206#endif /* #ifdef MODULE */
10207
10208/**---------------------------------------------------------------------------
10209
Jeff Johnson295189b2012-06-20 16:38:30 -070010210 \brief hdd_get_conparam() -
10211
10212 This is the driver exit point (invoked when module is unloaded using rmmod)
10213
10214 \param - None
10215
10216 \return - tVOS_CON_MODE
10217
10218 --------------------------------------------------------------------------*/
10219tVOS_CON_MODE hdd_get_conparam ( void )
10220{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010221#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010222 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010223#else
10224 return (tVOS_CON_MODE)curr_con_mode;
10225#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010226}
10227void hdd_set_conparam ( v_UINT_t newParam )
10228{
10229 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010230#ifndef MODULE
10231 curr_con_mode = con_mode;
10232#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010233}
10234/**---------------------------------------------------------------------------
10235
10236 \brief hdd_softap_sta_deauth() - function
10237
10238 This to take counter measure to handle deauth req from HDD
10239
10240 \param - pAdapter - Pointer to the HDD
10241
10242 \param - enable - boolean value
10243
10244 \return - None
10245
10246 --------------------------------------------------------------------------*/
10247
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010248VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10249 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010250{
Jeff Johnson295189b2012-06-20 16:38:30 -070010251 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010252 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010253
10254 ENTER();
10255
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010256 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10257 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010258
10259 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010260 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010261 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010262
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010263 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010264
10265 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010266 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010267}
10268
10269/**---------------------------------------------------------------------------
10270
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010271 \brief hdd_del_all_sta() - function
10272
10273 This function removes all the stations associated on stopping AP/P2P GO.
10274
10275 \param - pAdapter - Pointer to the HDD
10276
10277 \return - None
10278
10279 --------------------------------------------------------------------------*/
10280
10281int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10282{
10283 v_U16_t i;
10284 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010285 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10286 ptSapContext pSapCtx = NULL;
10287 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10288 if(pSapCtx == NULL){
10289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10290 FL("psapCtx is NULL"));
10291 return 1;
10292 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010293 ENTER();
10294
10295 hddLog(VOS_TRACE_LEVEL_INFO,
10296 "%s: Delete all STAs associated.",__func__);
10297 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10298 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10299 )
10300 {
10301 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10302 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010303 if ((pSapCtx->aStaInfo[i].isUsed) &&
10304 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010305 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010306 struct tagCsrDelStaParams delStaParams;
10307
10308 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010309 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010310 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10311 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010312 &delStaParams);
10313 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010314 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010315 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010316 }
10317 }
10318 }
10319
10320 EXIT();
10321 return 0;
10322}
10323
10324/**---------------------------------------------------------------------------
10325
Jeff Johnson295189b2012-06-20 16:38:30 -070010326 \brief hdd_softap_sta_disassoc() - function
10327
10328 This to take counter measure to handle deauth req from HDD
10329
10330 \param - pAdapter - Pointer to the HDD
10331
10332 \param - enable - boolean value
10333
10334 \return - None
10335
10336 --------------------------------------------------------------------------*/
10337
10338void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10339{
10340 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10341
10342 ENTER();
10343
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010344 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010345
10346 //Ignore request to disassoc bcmc station
10347 if( pDestMacAddress[0] & 0x1 )
10348 return;
10349
10350 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10351}
10352
10353void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10354{
10355 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10356
10357 ENTER();
10358
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010359 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010360
10361 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10362}
10363
Jeff Johnson295189b2012-06-20 16:38:30 -070010364/**---------------------------------------------------------------------------
10365 *
10366 * \brief hdd_get__concurrency_mode() -
10367 *
10368 *
10369 * \param - None
10370 *
10371 * \return - CONCURRENCY MODE
10372 *
10373 * --------------------------------------------------------------------------*/
10374tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10375{
10376 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10377 hdd_context_t *pHddCtx;
10378
10379 if (NULL != pVosContext)
10380 {
10381 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10382 if (NULL != pHddCtx)
10383 {
10384 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10385 }
10386 }
10387
10388 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010389 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010390 return VOS_STA;
10391}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010392v_BOOL_t
10393wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10394{
10395 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010396
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010397 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10398 if (pAdapter == NULL)
10399 {
10400 hddLog(VOS_TRACE_LEVEL_INFO,
10401 FL("GO doesn't exist"));
10402 return TRUE;
10403 }
10404 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10405 {
10406 hddLog(VOS_TRACE_LEVEL_INFO,
10407 FL("GO started"));
10408 return TRUE;
10409 }
10410 else
10411 /* wait till GO changes its interface to p2p device */
10412 hddLog(VOS_TRACE_LEVEL_INFO,
10413 FL("Del_bss called, avoid apps suspend"));
10414 return FALSE;
10415
10416}
Jeff Johnson295189b2012-06-20 16:38:30 -070010417/* Decide whether to allow/not the apps power collapse.
10418 * Allow apps power collapse if we are in connected state.
10419 * if not, allow only if we are in IMPS */
10420v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10421{
10422 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010423 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010424 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10426 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10427 hdd_adapter_t *pAdapter = NULL;
10428 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010429 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010430
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10432 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010433
Yathish9f22e662012-12-10 14:21:35 -080010434 concurrent_state = hdd_get_concurrency_mode();
10435
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010436 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10437 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10438 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010439#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010440
Yathish9f22e662012-12-10 14:21:35 -080010441 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010442 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010443 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10444 return TRUE;
10445#endif
10446
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 /*loop through all adapters. TBD fix for Concurrency */
10448 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10449 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10450 {
10451 pAdapter = pAdapterNode->pAdapter;
10452 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10453 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10454 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010455 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010456 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010457 && pmcState != STOPPED && pmcState != STANDBY &&
10458 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010459 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10460 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010461 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010462 if(pmcState == FULL_POWER &&
10463 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10464 {
10465 /*
10466 * When SCO indication comes from Coex module , host will
10467 * enter in to full power mode, but this should not prevent
10468 * apps processor power collapse.
10469 */
10470 hddLog(LOG1,
10471 FL("Allow apps power collapse"
10472 "even when sco indication is set"));
10473 return TRUE;
10474 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010475 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010476 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10477 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 return FALSE;
10479 }
10480 }
10481 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10482 pAdapterNode = pNext;
10483 }
10484 return TRUE;
10485}
10486
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010487/* Decides whether to send suspend notification to Riva
10488 * if any adapter is in BMPS; then it is required */
10489v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10490{
10491 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10492 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10493
10494 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10495 {
10496 return TRUE;
10497 }
10498 return FALSE;
10499}
10500
Jeff Johnson295189b2012-06-20 16:38:30 -070010501void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10502{
10503 switch(mode)
10504 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010505 case VOS_STA_MODE:
10506 case VOS_P2P_CLIENT_MODE:
10507 case VOS_P2P_GO_MODE:
10508 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010509 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010510 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010511 break;
10512 default:
10513 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010515 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10516 "Number of open sessions for mode %d = %d"),
10517 pHddCtx->concurrency_mode, mode,
10518 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010519}
10520
10521
10522void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10523{
10524 switch(mode)
10525 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010526 case VOS_STA_MODE:
10527 case VOS_P2P_CLIENT_MODE:
10528 case VOS_P2P_GO_MODE:
10529 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010530 pHddCtx->no_of_open_sessions[mode]--;
10531 if (!(pHddCtx->no_of_open_sessions[mode]))
10532 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 break;
10534 default:
10535 break;
10536 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010537 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10538 "Number of open sessions for mode %d = %d"),
10539 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10540
10541}
10542/**---------------------------------------------------------------------------
10543 *
10544 * \brief wlan_hdd_incr_active_session()
10545 *
10546 * This function increments the number of active sessions
10547 * maintained per device mode
10548 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10549 * Incase of SAP/P2P GO upon bss start it is incremented
10550 *
10551 * \param pHddCtx - HDD Context
10552 * \param mode - device mode
10553 *
10554 * \return - None
10555 *
10556 * --------------------------------------------------------------------------*/
10557void wlan_hdd_incr_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:
10564 pHddCtx->no_of_active_sessions[mode]++;
10565 break;
10566 default:
10567 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10568 break;
10569 }
10570 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10571 mode,
10572 pHddCtx->no_of_active_sessions[mode]);
10573}
10574
10575/**---------------------------------------------------------------------------
10576 *
10577 * \brief wlan_hdd_decr_active_session()
10578 *
10579 * This function decrements the number of active sessions
10580 * maintained per device mode
10581 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10582 * Incase of SAP/P2P GO upon bss stop it is decremented
10583 *
10584 * \param pHddCtx - HDD Context
10585 * \param mode - device mode
10586 *
10587 * \return - None
10588 *
10589 * --------------------------------------------------------------------------*/
10590void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10591{
10592 switch (mode) {
10593 case VOS_STA_MODE:
10594 case VOS_P2P_CLIENT_MODE:
10595 case VOS_P2P_GO_MODE:
10596 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010597 if (pHddCtx->no_of_active_sessions[mode] > 0)
10598 pHddCtx->no_of_active_sessions[mode]--;
10599 else
10600 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10601 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010602 break;
10603 default:
10604 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10605 break;
10606 }
10607 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10608 mode,
10609 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010610}
10611
Jeff Johnsone7245742012-09-05 17:12:55 -070010612/**---------------------------------------------------------------------------
10613 *
10614 * \brief wlan_hdd_restart_init
10615 *
10616 * This function initalizes restart timer/flag. An internal function.
10617 *
10618 * \param - pHddCtx
10619 *
10620 * \return - None
10621 *
10622 * --------------------------------------------------------------------------*/
10623
10624static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10625{
10626 /* Initialize */
10627 pHddCtx->hdd_restart_retries = 0;
10628 atomic_set(&pHddCtx->isRestartInProgress, 0);
10629 vos_timer_init(&pHddCtx->hdd_restart_timer,
10630 VOS_TIMER_TYPE_SW,
10631 wlan_hdd_restart_timer_cb,
10632 pHddCtx);
10633}
10634/**---------------------------------------------------------------------------
10635 *
10636 * \brief wlan_hdd_restart_deinit
10637 *
10638 * This function cleans up the resources used. An internal function.
10639 *
10640 * \param - pHddCtx
10641 *
10642 * \return - None
10643 *
10644 * --------------------------------------------------------------------------*/
10645
10646static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10647{
10648
10649 VOS_STATUS vos_status;
10650 /* Block any further calls */
10651 atomic_set(&pHddCtx->isRestartInProgress, 1);
10652 /* Cleanup */
10653 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10654 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010655 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010656 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10657 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010658 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010659
10660}
10661
10662/**---------------------------------------------------------------------------
10663 *
10664 * \brief wlan_hdd_framework_restart
10665 *
10666 * This function uses a cfg80211 API to start a framework initiated WLAN
10667 * driver module unload/load.
10668 *
10669 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10670 *
10671 *
10672 * \param - pHddCtx
10673 *
10674 * \return - VOS_STATUS_SUCCESS: Success
10675 * VOS_STATUS_E_EMPTY: Adapter is Empty
10676 * VOS_STATUS_E_NOMEM: No memory
10677
10678 * --------------------------------------------------------------------------*/
10679
10680static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10681{
10682 VOS_STATUS status = VOS_STATUS_SUCCESS;
10683 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010684 int len = (sizeof (struct ieee80211_mgmt));
10685 struct ieee80211_mgmt *mgmt = NULL;
10686
10687 /* Prepare the DEAUTH managment frame with reason code */
10688 mgmt = kzalloc(len, GFP_KERNEL);
10689 if(mgmt == NULL)
10690 {
10691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10692 "%s: memory allocation failed (%d bytes)", __func__, len);
10693 return VOS_STATUS_E_NOMEM;
10694 }
10695 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010696
10697 /* Iterate over all adapters/devices */
10698 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053010699 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
10700 {
10701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10702 FL("fail to get adapter: %p %d"), pAdapterNode, status);
10703 goto end;
10704 }
10705
Jeff Johnsone7245742012-09-05 17:12:55 -070010706 do
10707 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053010708 if(pAdapterNode->pAdapter &&
10709 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070010710 {
10711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10712 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10713 pAdapterNode->pAdapter->dev->name,
10714 pAdapterNode->pAdapter->device_mode,
10715 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010716 /*
10717 * CFG80211 event to restart the driver
10718 *
10719 * 'cfg80211_send_unprot_deauth' sends a
10720 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10721 * of SME(Linux Kernel) state machine.
10722 *
10723 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10724 * the driver.
10725 *
10726 */
10727
10728 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010729 }
10730 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10731 pAdapterNode = pNext;
10732 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10733
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053010734 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010735 /* Free the allocated management frame */
10736 kfree(mgmt);
10737
Jeff Johnsone7245742012-09-05 17:12:55 -070010738 /* Retry until we unload or reach max count */
10739 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10740 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10741
10742 return status;
10743
10744}
10745/**---------------------------------------------------------------------------
10746 *
10747 * \brief wlan_hdd_restart_timer_cb
10748 *
10749 * Restart timer callback. An internal function.
10750 *
10751 * \param - User data:
10752 *
10753 * \return - None
10754 *
10755 * --------------------------------------------------------------------------*/
10756
10757void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10758{
10759 hdd_context_t *pHddCtx = usrDataForCallback;
10760 wlan_hdd_framework_restart(pHddCtx);
10761 return;
10762
10763}
10764
10765
10766/**---------------------------------------------------------------------------
10767 *
10768 * \brief wlan_hdd_restart_driver
10769 *
10770 * This function sends an event to supplicant to restart the WLAN driver.
10771 *
10772 * This function is called from vos_wlanRestart.
10773 *
10774 * \param - pHddCtx
10775 *
10776 * \return - VOS_STATUS_SUCCESS: Success
10777 * VOS_STATUS_E_EMPTY: Adapter is Empty
10778 * VOS_STATUS_E_ALREADY: Request already in progress
10779
10780 * --------------------------------------------------------------------------*/
10781VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10782{
10783 VOS_STATUS status = VOS_STATUS_SUCCESS;
10784
10785 /* A tight check to make sure reentrancy */
10786 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10787 {
Mihir Shetefd528652014-06-23 19:07:50 +053010788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010789 "%s: WLAN restart is already in progress", __func__);
10790
10791 return VOS_STATUS_E_ALREADY;
10792 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010793 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010794#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010795 wcnss_reset_intr();
10796#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010797
Jeff Johnsone7245742012-09-05 17:12:55 -070010798 return status;
10799}
10800
Mihir Shetee1093ba2014-01-21 20:13:32 +053010801/**---------------------------------------------------------------------------
10802 *
10803 * \brief wlan_hdd_init_channels
10804 *
10805 * This function is used to initialize the channel list in CSR
10806 *
10807 * This function is called from hdd_wlan_startup
10808 *
10809 * \param - pHddCtx: HDD context
10810 *
10811 * \return - VOS_STATUS_SUCCESS: Success
10812 * VOS_STATUS_E_FAULT: Failure reported by SME
10813
10814 * --------------------------------------------------------------------------*/
10815static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10816{
10817 eHalStatus status;
10818
10819 status = sme_InitChannels(pHddCtx->hHal);
10820 if (HAL_STATUS_SUCCESS(status))
10821 {
10822 return VOS_STATUS_SUCCESS;
10823 }
10824 else
10825 {
10826 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10827 __func__, status);
10828 return VOS_STATUS_E_FAULT;
10829 }
10830}
10831
Mihir Shete04206452014-11-20 17:50:58 +053010832#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010833VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010834{
10835 eHalStatus status;
10836
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010837 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010838 if (HAL_STATUS_SUCCESS(status))
10839 {
10840 return VOS_STATUS_SUCCESS;
10841 }
10842 else
10843 {
10844 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10845 __func__, status);
10846 return VOS_STATUS_E_FAULT;
10847 }
10848}
Mihir Shete04206452014-11-20 17:50:58 +053010849#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010850/*
10851 * API to find if there is any STA or P2P-Client is connected
10852 */
10853VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10854{
10855 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10856}
Jeff Johnsone7245742012-09-05 17:12:55 -070010857
Agarwal Ashish57e84372014-12-05 18:26:53 +053010858/*
10859 * API to find if there is any session connected
10860 */
10861VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
10862{
10863 return sme_is_any_session_connected(pHddCtx->hHal);
10864}
10865
10866
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010867int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10868{
10869 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10870 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010871 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053010872 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010873
10874 pScanInfo = &pHddCtx->scan_info;
10875 if (pScanInfo->mScanPending)
10876 {
c_hpothua3d45d52015-01-05 14:11:17 +053010877 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
10878 eCSR_SCAN_ABORT_DEFAULT);
10879 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10880 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010881
c_hpothua3d45d52015-01-05 14:11:17 +053010882 /* If there is active scan command lets wait for the completion else
10883 * there is no need to wait as scan command might be in the SME pending
10884 * command list.
10885 */
10886 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
10887 {
10888 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10889 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010890 &pScanInfo->abortscan_event_var,
10891 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053010892 if (0 >= status)
10893 {
10894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010895 "%s: Timeout or Interrupt occurred while waiting for abort"
10896 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053010897 return -ETIMEDOUT;
10898 }
10899 }
10900 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
10901 {
10902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10903 FL("hdd_abort_mac_scan failed"));
10904 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010905 }
10906 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010907 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010908}
10909
c_hpothu225aa7c2014-10-22 17:45:13 +053010910VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10911{
10912 hdd_adapter_t *pAdapter;
10913 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10914 VOS_STATUS vosStatus;
10915
10916 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10917 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10918 {
10919 pAdapter = pAdapterNode->pAdapter;
10920 if (NULL != pAdapter)
10921 {
10922 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10923 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10924 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10925 {
10926 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10927 pAdapter->device_mode);
10928 if (VOS_STATUS_SUCCESS !=
10929 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10930 {
10931 hddLog(LOGE, FL("failed to abort ROC"));
10932 return VOS_STATUS_E_FAILURE;
10933 }
10934 }
10935 }
10936 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10937 pAdapterNode = pNext;
10938 }
10939 return VOS_STATUS_SUCCESS;
10940}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053010941
Mihir Shete0be28772015-02-17 18:42:14 +053010942hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
10943{
10944 hdd_adapter_t *pAdapter;
10945 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10946 hdd_cfg80211_state_t *cfgState;
10947 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
10948 VOS_STATUS vosStatus;
10949
10950 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
10951 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10952 {
10953 pAdapter = pAdapterNode->pAdapter;
10954 if (NULL != pAdapter)
10955 {
10956 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
10957 pRemainChanCtx = cfgState->remain_on_chan_ctx;
10958 if (pRemainChanCtx)
10959 break;
10960 }
10961 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
10962 pAdapterNode = pNext;
10963 }
10964 return pRemainChanCtx;
10965}
10966
Jeff Johnson295189b2012-06-20 16:38:30 -070010967//Register the module init/exit functions
10968module_init(hdd_module_init);
10969module_exit(hdd_module_exit);
10970
10971MODULE_LICENSE("Dual BSD/GPL");
10972MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10973MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10974
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010975module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10976 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010977
Jeff Johnson76052702013-04-16 13:55:05 -070010978module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010979 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010980
10981module_param(enable_dfs_chan_scan, int,
10982 S_IRUSR | S_IRGRP | S_IROTH);
10983
10984module_param(enable_11d, int,
10985 S_IRUSR | S_IRGRP | S_IROTH);
10986
10987module_param(country_code, charp,
10988 S_IRUSR | S_IRGRP | S_IROTH);