blob: 8f019c83caeaa09669c5f125df619ed57ca3df13 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
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
Jeff Johnson295189b2012-06-20 16:38:30 -0700251static int hdd_netdev_notifier_call(struct notifier_block * nb,
252 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
352struct notifier_block hdd_netdev_notifier = {
353 .notifier_call = hdd_netdev_notifier_call,
354};
355
356/*---------------------------------------------------------------------------
357 * Function definitions
358 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700359void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
360void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700362static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700363#ifndef MODULE
364/* current con_mode - used only for statically linked driver
365 * con_mode is changed by userspace to indicate a mode change which will
366 * result in calling the module exit and init functions. The module
367 * exit function will clean up based on the value of con_mode prior to it
368 * being changed by userspace. So curr_con_mode records the current con_mode
369 * for exit when con_mode becomes the next mode for init
370 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700371static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700372#endif
373
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800374/**---------------------------------------------------------------------------
375
376 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
377
378 Called immediately after the cfg.ini is read in order to configure
379 the desired trace levels.
380
381 \param - moduleId - module whose trace level is being configured
382 \param - bitmask - bitmask of log levels to be enabled
383
384 \return - void
385
386 --------------------------------------------------------------------------*/
387static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
388{
389 wpt_tracelevel level;
390
391 /* if the bitmask is the default value, then a bitmask was not
392 specified in cfg.ini, so leave the logging level alone (it
393 will remain at the "compiled in" default value) */
394 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
395 {
396 return;
397 }
398
399 /* a mask was specified. start by disabling all logging */
400 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
401
402 /* now cycle through the bitmask until all "set" bits are serviced */
403 level = VOS_TRACE_LEVEL_FATAL;
404 while (0 != bitmask)
405 {
406 if (bitmask & 1)
407 {
408 vos_trace_setValue(moduleId, level, 1);
409 }
410 level++;
411 bitmask >>= 1;
412 }
413}
414
415
Jeff Johnson295189b2012-06-20 16:38:30 -0700416/**---------------------------------------------------------------------------
417
418 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
419
420 Called immediately after the cfg.ini is read in order to configure
421 the desired trace levels in the WDI.
422
423 \param - moduleId - module whose trace level is being configured
424 \param - bitmask - bitmask of log levels to be enabled
425
426 \return - void
427
428 --------------------------------------------------------------------------*/
429static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
430{
431 wpt_tracelevel level;
432
433 /* if the bitmask is the default value, then a bitmask was not
434 specified in cfg.ini, so leave the logging level alone (it
435 will remain at the "compiled in" default value) */
436 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
437 {
438 return;
439 }
440
441 /* a mask was specified. start by disabling all logging */
442 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
443
444 /* now cycle through the bitmask until all "set" bits are serviced */
445 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
446 while (0 != bitmask)
447 {
448 if (bitmask & 1)
449 {
450 wpalTraceSetLevel(moduleId, level, 1);
451 }
452 level++;
453 bitmask >>= 1;
454 }
455}
Jeff Johnson295189b2012-06-20 16:38:30 -0700456
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530457/*
458 * FUNCTION: wlan_hdd_validate_context
459 * This function is used to check the HDD context
460 */
461int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
462{
463 ENTER();
464
465 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
466 {
467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
468 "%s: HDD context is Null", __func__);
469 return -ENODEV;
470 }
471
472 if (pHddCtx->isLogpInProgress)
473 {
474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu8adb97b2014-12-08 19:38:20 +0530475 "%s: LOGP %s. Ignore!!", __func__,
476 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
477 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530478 return -EAGAIN;
479 }
480
Mihir Shete18156292014-03-11 15:38:30 +0530481 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530482 {
483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
484 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
485 return -EAGAIN;
486 }
487 return 0;
488}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700489#ifdef CONFIG_ENABLE_LINUX_REG
490void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
491{
492 hdd_adapter_t *pAdapter = NULL;
493 hdd_station_ctx_t *pHddStaCtx = NULL;
494 eCsrPhyMode phyMode;
495 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530496
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700497 if (NULL == pHddCtx)
498 {
499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
500 "HDD Context is null !!");
501 return ;
502 }
503
504 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
505 if (NULL == pAdapter)
506 {
507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
508 "pAdapter is null !!");
509 return ;
510 }
511
512 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
513 if (NULL == pHddStaCtx)
514 {
515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
516 "pHddStaCtx is null !!");
517 return ;
518 }
519
520 cfg_param = pHddCtx->cfg_ini;
521 if (NULL == cfg_param)
522 {
523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
524 "cfg_params not available !!");
525 return ;
526 }
527
528 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
529
530 if (!pHddCtx->isVHT80Allowed)
531 {
532 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
533 (eCSR_DOT11_MODE_11ac == phyMode) ||
534 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
535 {
536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
537 "Setting phymode to 11n!!");
538 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
539 }
540 }
541 else
542 {
543 /*New country Supports 11ac as well resetting value back from .ini*/
544 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
545 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
546 return ;
547 }
548
549 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
550 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
551 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
552 {
553 VOS_STATUS vosStatus;
554
555 // need to issue a disconnect to CSR.
556 INIT_COMPLETION(pAdapter->disconnect_comp_var);
557 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
558 pAdapter->sessionId,
559 eCSR_DISCONNECT_REASON_UNSPECIFIED );
560
561 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530562 {
563 long ret;
564
565 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700566 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530567 if (0 >= ret)
568 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
569 ret);
570 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700571
572 }
573}
574#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530575void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
576{
577 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
578 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
579 hdd_config_t *cfg_param;
580 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530581 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530582
583 if (NULL == pHddCtx)
584 {
585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
586 "HDD Context is null !!");
587 return ;
588 }
589
590 cfg_param = pHddCtx->cfg_ini;
591
592 if (NULL == cfg_param)
593 {
594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
595 "cfg_params not available !!");
596 return ;
597 }
598
599 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
600
601 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
602 {
603 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
604 (eCSR_DOT11_MODE_11ac == phyMode) ||
605 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
606 {
607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
608 "Setting phymode to 11n!!");
609 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
610 }
611 }
612 else
613 {
614 /*New country Supports 11ac as well resetting value back from .ini*/
615 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
616 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
617 return ;
618 }
619
620 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
621 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
622 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
623 {
624 VOS_STATUS vosStatus;
625
626 // need to issue a disconnect to CSR.
627 INIT_COMPLETION(pAdapter->disconnect_comp_var);
628 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
629 pAdapter->sessionId,
630 eCSR_DISCONNECT_REASON_UNSPECIFIED );
631
632 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530633 {
634 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530635 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530636 if (ret <= 0)
637 {
638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
639 "wait on disconnect_comp_var is failed %ld", ret);
640 }
641 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530642
643 }
644}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700645#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530646
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700647void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
648{
649 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
650 hdd_config_t *cfg_param;
651
652 if (NULL == pHddCtx)
653 {
654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
655 "HDD Context is null !!");
656 return ;
657 }
658
659 cfg_param = pHddCtx->cfg_ini;
660
661 if (NULL == cfg_param)
662 {
663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
664 "cfg_params not available !!");
665 return ;
666 }
667
Agarwal Ashish738843c2014-09-25 12:27:56 +0530668 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
669 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700670 {
671 /*New country doesn't support DFS */
672 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
673 }
674 else
675 {
676 /*New country Supports DFS as well resetting value back from .ini*/
677 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
678 }
679
680}
681
Rajeev79dbe4c2013-10-05 11:03:42 +0530682#ifdef FEATURE_WLAN_BATCH_SCAN
683
684/**---------------------------------------------------------------------------
685
686 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
687 input string
688
689 This function extracts assigned integer from string in below format:
690 "STRING=10" : extracts integer 10 from this string
691
692 \param - pInPtr Pointer to input string
693 \param - base Base for string to int conversion(10 for decimal 16 for hex)
694 \param - pOutPtr Pointer to variable in which extracted integer needs to be
695 assigned
696 \param - pLastArg to tell whether it is last arguement in input string or
697 not
698
699 \return - NULL for failure cases
700 pointer to next arguement in input string for success cases
701 --------------------------------------------------------------------------*/
702static tANI_U8 *
703hdd_extract_assigned_int_from_str
704(
705 tANI_U8 *pInPtr,
706 tANI_U8 base,
707 tANI_U32 *pOutPtr,
708 tANI_U8 *pLastArg
709)
710{
711 int tempInt;
712 int v = 0;
713 char buf[32];
714 int val = 0;
715 *pLastArg = FALSE;
716
717 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
718 if (NULL == pInPtr)
719 {
720 return NULL;
721 }
722
723 pInPtr++;
724
725 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
726
727 val = sscanf(pInPtr, "%32s ", buf);
728 if (val < 0 && val > strlen(pInPtr))
729 {
730 return NULL;
731 }
732 pInPtr += val;
733 v = kstrtos32(buf, base, &tempInt);
734 if (v < 0)
735 {
736 return NULL;
737 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800738 if (tempInt < 0)
739 {
740 tempInt = 0;
741 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530742 *pOutPtr = tempInt;
743
744 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
745 if (NULL == pInPtr)
746 {
747 *pLastArg = TRUE;
748 return NULL;
749 }
750 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
751
752 return pInPtr;
753}
754
755/**---------------------------------------------------------------------------
756
757 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
758 input string
759
760 This function extracts assigned character from string in below format:
761 "STRING=A" : extracts char 'A' from this string
762
763 \param - pInPtr Pointer to input string
764 \param - pOutPtr Pointer to variable in which extracted char needs to be
765 assigned
766 \param - pLastArg to tell whether it is last arguement in input string or
767 not
768
769 \return - NULL for failure cases
770 pointer to next arguement in input string for success cases
771 --------------------------------------------------------------------------*/
772static tANI_U8 *
773hdd_extract_assigned_char_from_str
774(
775 tANI_U8 *pInPtr,
776 tANI_U8 *pOutPtr,
777 tANI_U8 *pLastArg
778)
779{
780 *pLastArg = FALSE;
781
782 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
783 if (NULL == pInPtr)
784 {
785 return NULL;
786 }
787
788 pInPtr++;
789
790 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
791
792 *pOutPtr = *pInPtr;
793
794 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
795 if (NULL == pInPtr)
796 {
797 *pLastArg = TRUE;
798 return NULL;
799 }
800 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
801
802 return pInPtr;
803}
804
805
806/**---------------------------------------------------------------------------
807
808 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
809
810 This function parses set batch scan command in below format:
811 WLS_BATCHING_SET <space> followed by below arguements
812 "SCANFREQ=XX" : Optional defaults to 30 sec
813 "MSCAN=XX" : Required number of scans to attempt to batch
814 "BESTN=XX" : Best Network (RSSI) defaults to 16
815 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
816 A. implies only 5 GHz , B. implies only 2.4GHz
817 "RTT=X" : optional defaults to 0
818 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
819 error
820
821 For example input commands:
822 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
823 translated into set batch scan with following parameters:
824 a) Frequence 60 seconds
825 b) Batch 10 scans together
826 c) Best RSSI to be 20
827 d) 5GHz band only
828 e) RTT is equal to 0
829
830 \param - pValue Pointer to input channel list
831 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
832
833 \return - 0 for success non-zero for failure
834
835 --------------------------------------------------------------------------*/
836static int
837hdd_parse_set_batchscan_command
838(
839 tANI_U8 *pValue,
840 tSirSetBatchScanReq *pHddSetBatchScanReq
841)
842{
843 tANI_U8 *inPtr = pValue;
844 tANI_U8 val = 0;
845 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800846 tANI_U32 nScanFreq;
847 tANI_U32 nMscan;
848 tANI_U32 nBestN;
849 tANI_U8 ucRfBand;
850 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800851 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530852
853 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800854 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
855 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
856 nRtt = 0;
857 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530858
859 /*go to space after WLS_BATCHING_SET command*/
860 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
861 /*no argument after the command*/
862 if (NULL == inPtr)
863 {
864 return -EINVAL;
865 }
866
867 /*no space after the command*/
868 else if (SPACE_ASCII_VALUE != *inPtr)
869 {
870 return -EINVAL;
871 }
872
873 /*removing empty spaces*/
874 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
875
876 /*no argument followed by spaces*/
877 if ('\0' == *inPtr)
878 {
879 return -EINVAL;
880 }
881
882 /*check and parse SCANFREQ*/
883 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
884 {
885 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800886 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800887
Rajeev Kumarc933d982013-11-18 20:04:20 -0800888 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800889 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800890 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800891 }
892
Rajeev79dbe4c2013-10-05 11:03:42 +0530893 if ( (NULL == inPtr) || (TRUE == lastArg))
894 {
895 return -EINVAL;
896 }
897 }
898
899 /*check and parse MSCAN*/
900 if ((strncmp(inPtr, "MSCAN", 5) == 0))
901 {
902 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800903 &nMscan, &lastArg);
904
905 if (0 == nMscan)
906 {
907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
908 "invalid MSCAN=%d", nMscan);
909 return -EINVAL;
910 }
911
Rajeev79dbe4c2013-10-05 11:03:42 +0530912 if (TRUE == lastArg)
913 {
914 goto done;
915 }
916 else if (NULL == inPtr)
917 {
918 return -EINVAL;
919 }
920 }
921 else
922 {
923 return -EINVAL;
924 }
925
926 /*check and parse BESTN*/
927 if ((strncmp(inPtr, "BESTN", 5) == 0))
928 {
929 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800930 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800931
Rajeev Kumarc933d982013-11-18 20:04:20 -0800932 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800933 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800934 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800935 }
936
Rajeev79dbe4c2013-10-05 11:03:42 +0530937 if (TRUE == lastArg)
938 {
939 goto done;
940 }
941 else if (NULL == inPtr)
942 {
943 return -EINVAL;
944 }
945 }
946
947 /*check and parse CHANNEL*/
948 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
949 {
950 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800951
Rajeev79dbe4c2013-10-05 11:03:42 +0530952 if (('A' == val) || ('a' == val))
953 {
c_hpothuebf89732014-02-25 13:00:24 +0530954 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530955 }
956 else if (('B' == val) || ('b' == val))
957 {
c_hpothuebf89732014-02-25 13:00:24 +0530958 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530959 }
960 else
961 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800962 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
963 }
964
965 if (TRUE == lastArg)
966 {
967 goto done;
968 }
969 else if (NULL == inPtr)
970 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530971 return -EINVAL;
972 }
973 }
974
975 /*check and parse RTT*/
976 if ((strncmp(inPtr, "RTT", 3) == 0))
977 {
978 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800979 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530980 if (TRUE == lastArg)
981 {
982 goto done;
983 }
984 if (NULL == inPtr)
985 {
986 return -EINVAL;
987 }
988 }
989
990
991done:
992
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800993 pHddSetBatchScanReq->scanFrequency = nScanFreq;
994 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
995 pHddSetBatchScanReq->bestNetwork = nBestN;
996 pHddSetBatchScanReq->rfBand = ucRfBand;
997 pHddSetBatchScanReq->rtt = nRtt;
998
Rajeev79dbe4c2013-10-05 11:03:42 +0530999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1000 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1001 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1002 pHddSetBatchScanReq->scanFrequency,
1003 pHddSetBatchScanReq->numberOfScansToBatch,
1004 pHddSetBatchScanReq->bestNetwork,
1005 pHddSetBatchScanReq->rfBand,
1006 pHddSetBatchScanReq->rtt);
1007
1008 return 0;
1009}/*End of hdd_parse_set_batchscan_command*/
1010
1011/**---------------------------------------------------------------------------
1012
1013 \brief hdd_set_batch_scan_req_callback () - This function is called after
1014 receiving set batch scan response from FW and it saves set batch scan
1015 response data FW to HDD context and sets the completion event on
1016 which hdd_ioctl is waiting
1017
1018 \param - callbackContext Pointer to HDD adapter
1019 \param - pRsp Pointer to set batch scan response data received from FW
1020
1021 \return - nothing
1022
1023 --------------------------------------------------------------------------*/
1024static void hdd_set_batch_scan_req_callback
1025(
1026 void *callbackContext,
1027 tSirSetBatchScanRsp *pRsp
1028)
1029{
1030 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1031 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1032
1033 /*sanity check*/
1034 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1035 {
1036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1037 "%s: Invalid pAdapter magic", __func__);
1038 VOS_ASSERT(0);
1039 return;
1040 }
1041 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1042
1043 /*save set batch scan response*/
1044 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1045
1046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1047 "Received set batch scan rsp from FW with nScansToBatch=%d",
1048 pHddSetBatchScanRsp->nScansToBatch);
1049
1050 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1051 complete(&pAdapter->hdd_set_batch_scan_req_var);
1052
1053 return;
1054}/*End of hdd_set_batch_scan_req_callback*/
1055
1056
1057/**---------------------------------------------------------------------------
1058
1059 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1060 info in hdd batch scan response queue
1061
1062 \param - pAdapter Pointer to hdd adapter
1063 \param - pAPMetaInfo Pointer to access point meta info
1064 \param - scanId scan ID of batch scan response
1065 \param - isLastAp tells whether AP is last AP in batch scan response or not
1066
1067 \return - nothing
1068
1069 --------------------------------------------------------------------------*/
1070static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1071 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1072{
1073 tHddBatchScanRsp *pHead;
1074 tHddBatchScanRsp *pNode;
1075 tHddBatchScanRsp *pPrev;
1076 tHddBatchScanRsp *pTemp;
1077 tANI_U8 ssidLen;
1078
1079 /*head of hdd batch scan response queue*/
1080 pHead = pAdapter->pBatchScanRsp;
1081
1082 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1083 if (NULL == pNode)
1084 {
1085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1086 "%s: Could not allocate memory", __func__);
1087 VOS_ASSERT(0);
1088 return;
1089 }
1090
1091 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1092 sizeof(pNode->ApInfo.bssid));
1093 ssidLen = strlen(pApMetaInfo->ssid);
1094 if (SIR_MAX_SSID_SIZE < ssidLen)
1095 {
1096 /*invalid scan result*/
1097 vos_mem_free(pNode);
1098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1099 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1100 return;
1101 }
1102 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1103 /*null terminate ssid*/
1104 pNode->ApInfo.ssid[ssidLen] = '\0';
1105 pNode->ApInfo.ch = pApMetaInfo->ch;
1106 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1107 pNode->ApInfo.age = pApMetaInfo->timestamp;
1108 pNode->ApInfo.batchId = scanId;
1109 pNode->ApInfo.isLastAp = isLastAp;
1110
1111 pNode->pNext = NULL;
1112 if (NULL == pHead)
1113 {
1114 pAdapter->pBatchScanRsp = pNode;
1115 }
1116 else
1117 {
1118 pTemp = pHead;
1119 while (NULL != pTemp)
1120 {
1121 pPrev = pTemp;
1122 pTemp = pTemp->pNext;
1123 }
1124 pPrev->pNext = pNode;
1125 }
1126
1127 return;
1128}/*End of hdd_populate_batch_scan_rsp_queue*/
1129
1130/**---------------------------------------------------------------------------
1131
1132 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1133 receiving batch scan response indication from FW. It saves get batch scan
1134 response data in HDD batch scan response queue. This callback sets the
1135 completion event on which hdd_ioctl is waiting only after getting complete
1136 batch scan response data from FW
1137
1138 \param - callbackContext Pointer to HDD adapter
1139 \param - pRsp Pointer to get batch scan response data received from FW
1140
1141 \return - nothing
1142
1143 --------------------------------------------------------------------------*/
1144static void hdd_batch_scan_result_ind_callback
1145(
1146 void *callbackContext,
1147 void *pRsp
1148)
1149{
1150 v_BOOL_t isLastAp;
1151 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001152 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301153 tANI_U32 numberScanList;
1154 tANI_U32 nextScanListOffset;
1155 tANI_U32 nextApMetaInfoOffset;
1156 hdd_adapter_t* pAdapter;
1157 tpSirBatchScanList pScanList;
1158 tpSirBatchScanNetworkInfo pApMetaInfo;
1159 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1160 tSirSetBatchScanReq *pReq;
1161
1162 pAdapter = (hdd_adapter_t *)callbackContext;
1163 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001164 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301165 {
1166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1167 "%s: Invalid pAdapter magic", __func__);
1168 VOS_ASSERT(0);
1169 return;
1170 }
1171
1172 /*initialize locals*/
1173 pReq = &pAdapter->hddSetBatchScanReq;
1174 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1175 isLastAp = FALSE;
1176 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001177 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301178 numberScanList = 0;
1179 nextScanListOffset = 0;
1180 nextApMetaInfoOffset = 0;
1181 pScanList = NULL;
1182 pApMetaInfo = NULL;
1183
1184 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1185 {
1186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1187 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1188 isLastAp = TRUE;
1189 goto done;
1190 }
1191
1192 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1194 "Batch scan rsp: numberScalList %d", numberScanList);
1195
1196 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1197 {
1198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1199 "%s: numberScanList %d", __func__, numberScanList);
1200 isLastAp = TRUE;
1201 goto done;
1202 }
1203
1204 while (numberScanList)
1205 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001206 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301207 nextScanListOffset);
1208 if (NULL == pScanList)
1209 {
1210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1211 "%s: pScanList is %p", __func__, pScanList);
1212 isLastAp = TRUE;
1213 goto done;
1214 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001215 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001217 "Batch scan rsp: numApMetaInfo %d scanId %d",
1218 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301219
1220 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1221 {
1222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1223 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1224 isLastAp = TRUE;
1225 goto done;
1226 }
1227
Rajeev Kumarce651e42013-10-21 18:57:15 -07001228 /*Initialize next AP meta info offset for next scan list*/
1229 nextApMetaInfoOffset = 0;
1230
Rajeev79dbe4c2013-10-05 11:03:42 +05301231 while (numApMetaInfo)
1232 {
1233 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1234 nextApMetaInfoOffset);
1235 if (NULL == pApMetaInfo)
1236 {
1237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1238 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1239 isLastAp = TRUE;
1240 goto done;
1241 }
1242 /*calculate AP age*/
1243 pApMetaInfo->timestamp =
1244 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1245
1246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001247 "%s: bssId "MAC_ADDRESS_STR
1248 " ch %d rssi %d timestamp %d", __func__,
1249 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1250 pApMetaInfo->ch, pApMetaInfo->rssi,
1251 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301252
1253 /*mark last AP in batch scan response*/
1254 if ((TRUE == pBatchScanRsp->isLastResult) &&
1255 (1 == numberScanList) && (1 == numApMetaInfo))
1256 {
1257 isLastAp = TRUE;
1258 }
1259
1260 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1261 /*store batch scan repsonse in hdd queue*/
1262 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1263 pScanList->scanId, isLastAp);
1264 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1265
1266 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1267 numApMetaInfo--;
1268 }
1269
Rajeev Kumarce651e42013-10-21 18:57:15 -07001270 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1271 + (sizeof(tSirBatchScanNetworkInfo)
1272 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301273 numberScanList--;
1274 }
1275
1276done:
1277
1278 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1279 requested from hdd_ioctl*/
1280 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1281 (TRUE == isLastAp))
1282 {
1283 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1284 complete(&pAdapter->hdd_get_batch_scan_req_var);
1285 }
1286
1287 return;
1288}/*End of hdd_batch_scan_result_ind_callback*/
1289
1290/**---------------------------------------------------------------------------
1291
1292 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1293 response as per batch scan FR request format by putting proper markers
1294
1295 \param - pDest pointer to destination buffer
1296 \param - cur_len current length
1297 \param - tot_len total remaining size which can be written to user space
1298 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1299 \param - pAdapter Pointer to HDD adapter
1300
1301 \return - ret no of characters written
1302
1303 --------------------------------------------------------------------------*/
1304static tANI_U32
1305hdd_format_batch_scan_rsp
1306(
1307 tANI_U8 *pDest,
1308 tANI_U32 cur_len,
1309 tANI_U32 tot_len,
1310 tHddBatchScanRsp *pApMetaInfo,
1311 hdd_adapter_t* pAdapter
1312)
1313{
1314 tANI_U32 ret = 0;
1315 tANI_U32 rem_len = 0;
1316 tANI_U8 temp_len = 0;
1317 tANI_U8 temp_total_len = 0;
1318 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1319 tANI_U8 *pTemp = temp;
1320
1321 /*Batch scan reponse needs to be returned to user space in
1322 following format:
1323 "scancount=X\n" where X is the number of scans in current batch
1324 batch
1325 "trunc\n" optional present if current scan truncated
1326 "bssid=XX:XX:XX:XX:XX:XX\n"
1327 "ssid=XXXX\n"
1328 "freq=X\n" frequency in Mhz
1329 "level=XX\n"
1330 "age=X\n" ms
1331 "dist=X\n" cm (-1 if not available)
1332 "errror=X\n" (-1if not available)
1333 "====\n" (end of ap marker)
1334 "####\n" (end of scan marker)
1335 "----\n" (end of results)*/
1336 /*send scan result in above format to user space based on
1337 available length*/
1338 /*The GET response may have more data than the driver can return in its
1339 buffer. In that case the buffer should be filled to the nearest complete
1340 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1341 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1342 The final buffer should end with "----\n"*/
1343
1344 /*sanity*/
1345 if (cur_len > tot_len)
1346 {
1347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1348 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1349 return 0;
1350 }
1351 else
1352 {
1353 rem_len = (tot_len - cur_len);
1354 }
1355
1356 /*end scan marker*/
1357 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1358 {
1359 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1360 pTemp += temp_len;
1361 temp_total_len += temp_len;
1362 }
1363
1364 /*bssid*/
1365 temp_len = snprintf(pTemp, sizeof(temp),
1366 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1367 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1368 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1369 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1370 pTemp += temp_len;
1371 temp_total_len += temp_len;
1372
1373 /*ssid*/
1374 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1375 pApMetaInfo->ApInfo.ssid);
1376 pTemp += temp_len;
1377 temp_total_len += temp_len;
1378
1379 /*freq*/
1380 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001381 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301382 pTemp += temp_len;
1383 temp_total_len += temp_len;
1384
1385 /*level*/
1386 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1387 pApMetaInfo->ApInfo.rssi);
1388 pTemp += temp_len;
1389 temp_total_len += temp_len;
1390
1391 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001392 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301393 pApMetaInfo->ApInfo.age);
1394 pTemp += temp_len;
1395 temp_total_len += temp_len;
1396
1397 /*dist*/
1398 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1399 pTemp += temp_len;
1400 temp_total_len += temp_len;
1401
1402 /*error*/
1403 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1404 pTemp += temp_len;
1405 temp_total_len += temp_len;
1406
1407 /*end AP marker*/
1408 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1409 pTemp += temp_len;
1410 temp_total_len += temp_len;
1411
1412 /*last AP in batch scan response*/
1413 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1414 {
1415 /*end scan marker*/
1416 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1417 pTemp += temp_len;
1418 temp_total_len += temp_len;
1419
1420 /*end batch scan result marker*/
1421 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1422 pTemp += temp_len;
1423 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001424
Rajeev79dbe4c2013-10-05 11:03:42 +05301425 }
1426
1427 if (temp_total_len < rem_len)
1428 {
1429 ret = temp_total_len + 1;
1430 strlcpy(pDest, temp, ret);
1431 pAdapter->isTruncated = FALSE;
1432 }
1433 else
1434 {
1435 pAdapter->isTruncated = TRUE;
1436 if (rem_len >= strlen("%%%%"))
1437 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001438 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301439 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001440 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301441 {
1442 ret = 0;
1443 }
1444 }
1445
1446 return ret;
1447
1448}/*End of hdd_format_batch_scan_rsp*/
1449
1450/**---------------------------------------------------------------------------
1451
1452 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1453 buffer starting with head of hdd batch scan response queue
1454
1455 \param - pAdapter Pointer to HDD adapter
1456 \param - pDest Pointer to user data buffer
1457 \param - cur_len current offset in user buffer
1458 \param - rem_len remaining no of bytes in user buffer
1459
1460 \return - number of bytes written in user buffer
1461
1462 --------------------------------------------------------------------------*/
1463
1464tANI_U32 hdd_populate_user_batch_scan_rsp
1465(
1466 hdd_adapter_t* pAdapter,
1467 tANI_U8 *pDest,
1468 tANI_U32 cur_len,
1469 tANI_U32 rem_len
1470)
1471{
1472 tHddBatchScanRsp *pHead;
1473 tHddBatchScanRsp *pPrev;
1474 tANI_U32 len;
1475
Rajeev79dbe4c2013-10-05 11:03:42 +05301476 pAdapter->isTruncated = FALSE;
1477
1478 /*head of hdd batch scan response queue*/
1479 pHead = pAdapter->pBatchScanRsp;
1480 while (pHead)
1481 {
1482 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1483 pAdapter);
1484 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001485 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301486 cur_len += len;
1487 if(TRUE == pAdapter->isTruncated)
1488 {
1489 /*result is truncated return rest of scan rsp in next req*/
1490 cur_len = rem_len;
1491 break;
1492 }
1493 pPrev = pHead;
1494 pHead = pHead->pNext;
1495 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001496 if (TRUE == pPrev->ApInfo.isLastAp)
1497 {
1498 pAdapter->prev_batch_id = 0;
1499 }
1500 else
1501 {
1502 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1503 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301504 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001505 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301506 }
1507
1508 return cur_len;
1509}/*End of hdd_populate_user_batch_scan_rsp*/
1510
1511/**---------------------------------------------------------------------------
1512
1513 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1514 scan response data from HDD queue to user space
1515 It does following in detail:
1516 a) if HDD has enough data in its queue then it 1st copies data to user
1517 space and then send get batch scan indication message to FW. In this
1518 case it does not wait on any event and batch scan response data will
1519 be populated in HDD response queue in MC thread context after receiving
1520 indication from FW
1521 b) else send get batch scan indication message to FW and wait on an event
1522 which will be set once HDD receives complete batch scan response from
1523 FW and then this function returns batch scan response to user space
1524
1525 \param - pAdapter Pointer to HDD adapter
1526 \param - pPrivData Pointer to priv_data
1527
1528 \return - 0 for success -EFAULT for failure
1529
1530 --------------------------------------------------------------------------*/
1531
1532int hdd_return_batch_scan_rsp_to_user
1533(
1534 hdd_adapter_t* pAdapter,
1535 hdd_priv_data_t *pPrivData,
1536 tANI_U8 *command
1537)
1538{
1539 tANI_U8 *pDest;
1540 tANI_U32 count = 0;
1541 tANI_U32 len = 0;
1542 tANI_U32 cur_len = 0;
1543 tANI_U32 rem_len = 0;
1544 eHalStatus halStatus;
1545 unsigned long rc;
1546 tSirTriggerBatchScanResultInd *pReq;
1547
1548 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1549 pReq->param = 0;/*batch scan client*/
1550 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1551 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1552
1553 cur_len = pPrivData->used_len;
1554 if (pPrivData->total_len > pPrivData->used_len)
1555 {
1556 rem_len = pPrivData->total_len - pPrivData->used_len;
1557 }
1558 else
1559 {
1560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1561 "%s: Invalid user data buffer total_len %d used_len %d",
1562 __func__, pPrivData->total_len, pPrivData->used_len);
1563 return -EFAULT;
1564 }
1565
1566 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1567 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1568 cur_len, rem_len);
1569 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1570
1571 /*enough scan result available in cache to return to user space or
1572 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001573 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301574 {
1575 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1576 halStatus = sme_TriggerBatchScanResultInd(
1577 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1578 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1579 pAdapter);
1580 if ( eHAL_STATUS_SUCCESS == halStatus )
1581 {
1582 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1583 {
1584 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1585 rc = wait_for_completion_timeout(
1586 &pAdapter->hdd_get_batch_scan_req_var,
1587 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1588 if (0 == rc)
1589 {
1590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1591 "%s: Timeout waiting to fetch batch scan rsp from fw",
1592 __func__);
1593 return -EFAULT;
1594 }
1595 }
1596
1597 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001598 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301599 pDest += len;
1600 cur_len += len;
1601
1602 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1603 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1604 cur_len, rem_len);
1605 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1606
1607 count = 0;
1608 len = (len - pPrivData->used_len);
1609 pDest = (command + pPrivData->used_len);
1610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001611 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301612 while(count < len)
1613 {
1614 printk("%c", *(pDest + count));
1615 count++;
1616 }
1617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1618 "%s: copy %d data to user buffer", __func__, len);
1619 if (copy_to_user(pPrivData->buf, pDest, len))
1620 {
1621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1622 "%s: failed to copy data to user buffer", __func__);
1623 return -EFAULT;
1624 }
1625 }
1626 else
1627 {
1628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1629 "sme_GetBatchScanScan returned failure halStatus %d",
1630 halStatus);
1631 return -EINVAL;
1632 }
1633 }
1634 else
1635 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301636 count = 0;
1637 len = (len - pPrivData->used_len);
1638 pDest = (command + pPrivData->used_len);
1639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001640 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301641 while(count < len)
1642 {
1643 printk("%c", *(pDest + count));
1644 count++;
1645 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1647 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301648 if (copy_to_user(pPrivData->buf, pDest, len))
1649 {
1650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1651 "%s: failed to copy data to user buffer", __func__);
1652 return -EFAULT;
1653 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301654 }
1655
1656 return 0;
1657} /*End of hdd_return_batch_scan_rsp_to_user*/
1658
Rajeev Kumar8b373292014-01-08 20:36:55 -08001659
1660/**---------------------------------------------------------------------------
1661
1662 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1663 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1664 WLS_BATCHING VERSION
1665 WLS_BATCHING SET
1666 WLS_BATCHING GET
1667 WLS_BATCHING STOP
1668
1669 \param - pAdapter Pointer to HDD adapter
1670 \param - pPrivdata Pointer to priv_data
1671 \param - command Pointer to command
1672
1673 \return - 0 for success -EFAULT for failure
1674
1675 --------------------------------------------------------------------------*/
1676
1677int hdd_handle_batch_scan_ioctl
1678(
1679 hdd_adapter_t *pAdapter,
1680 hdd_priv_data_t *pPrivdata,
1681 tANI_U8 *command
1682)
1683{
1684 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001685 hdd_context_t *pHddCtx;
1686
1687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1688 ret = wlan_hdd_validate_context(pHddCtx);
1689 if (ret)
1690 {
1691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1692 "%s: HDD context is not valid!", __func__);
1693 goto exit;
1694 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001695
1696 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1697 {
1698 char extra[32];
1699 tANI_U8 len = 0;
1700 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1701
1702 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1703 {
1704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1705 "%s: Batch scan feature is not supported by FW", __func__);
1706 ret = -EINVAL;
1707 goto exit;
1708 }
1709
1710 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1711 version);
1712 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1713 {
1714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1715 "%s: failed to copy data to user buffer", __func__);
1716 ret = -EFAULT;
1717 goto exit;
1718 }
1719 ret = HDD_BATCH_SCAN_VERSION;
1720 }
1721 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1722 {
1723 int status;
1724 tANI_U8 *value = (command + 16);
1725 eHalStatus halStatus;
1726 unsigned long rc;
1727 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1728 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1729
1730 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1731 {
1732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1733 "%s: Batch scan feature is not supported by FW", __func__);
1734 ret = -EINVAL;
1735 goto exit;
1736 }
1737
1738 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1739 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1740 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1741 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1742 {
1743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301744 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001745 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301746 hdd_device_modetoString(pAdapter->device_mode),
1747 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001748 ret = -EINVAL;
1749 goto exit;
1750 }
1751
1752 status = hdd_parse_set_batchscan_command(value, pReq);
1753 if (status)
1754 {
1755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1756 "Invalid WLS_BATCHING SET command");
1757 ret = -EINVAL;
1758 goto exit;
1759 }
1760
1761
1762 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1763 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1764 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1765 pAdapter);
1766
1767 if ( eHAL_STATUS_SUCCESS == halStatus )
1768 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301769 char extra[32];
1770 tANI_U8 len = 0;
1771 tANI_U8 mScan = 0;
1772
Rajeev Kumar8b373292014-01-08 20:36:55 -08001773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1774 "sme_SetBatchScanReq returned success halStatus %d",
1775 halStatus);
1776 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1777 {
1778 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1779 rc = wait_for_completion_timeout(
1780 &pAdapter->hdd_set_batch_scan_req_var,
1781 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1782 if (0 == rc)
1783 {
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1785 "%s: Timeout waiting for set batch scan to complete",
1786 __func__);
1787 ret = -EINVAL;
1788 goto exit;
1789 }
1790 }
1791 if ( !pRsp->nScansToBatch )
1792 {
1793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1794 "%s: Received set batch scan failure response from FW",
1795 __func__);
1796 ret = -EINVAL;
1797 goto exit;
1798 }
1799 /*As per the Batch Scan Framework API we should return the MIN of
1800 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301801 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001802
1803 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1804
1805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1806 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301807 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1808 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1809 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1810 {
1811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1812 "%s: failed to copy MSCAN value to user buffer", __func__);
1813 ret = -EFAULT;
1814 goto exit;
1815 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001816 }
1817 else
1818 {
1819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1820 "sme_SetBatchScanReq returned failure halStatus %d",
1821 halStatus);
1822 ret = -EINVAL;
1823 goto exit;
1824 }
1825 }
1826 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1827 {
1828 eHalStatus halStatus;
1829 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1830 pInd->param = 0;
1831
1832 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1833 {
1834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1835 "%s: Batch scan feature is not supported by FW", __func__);
1836 ret = -EINVAL;
1837 goto exit;
1838 }
1839
1840 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1841 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001843 "Batch scan is not yet enabled batch scan state %d",
1844 pAdapter->batchScanState);
1845 ret = -EINVAL;
1846 goto exit;
1847 }
1848
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001849 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1850 hdd_deinit_batch_scan(pAdapter);
1851 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1852
Rajeev Kumar8b373292014-01-08 20:36:55 -08001853 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1854
1855 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1856 pAdapter->sessionId);
1857 if ( eHAL_STATUS_SUCCESS == halStatus )
1858 {
1859 ret = 0;
1860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1861 "sme_StopBatchScanInd returned success halStatus %d",
1862 halStatus);
1863 }
1864 else
1865 {
1866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1867 "sme_StopBatchScanInd returned failure halStatus %d",
1868 halStatus);
1869 ret = -EINVAL;
1870 goto exit;
1871 }
1872 }
1873 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1874 {
1875 tANI_U32 remain_len;
1876
1877 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1878 {
1879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1880 "%s: Batch scan feature is not supported by FW", __func__);
1881 ret = -EINVAL;
1882 goto exit;
1883 }
1884
1885 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1886 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001888 "Batch scan is not yet enabled could not return results"
1889 "Batch Scan state %d",
1890 pAdapter->batchScanState);
1891 ret = -EINVAL;
1892 goto exit;
1893 }
1894
1895 pPrivdata->used_len = 16;
1896 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1897 if (remain_len < pPrivdata->total_len)
1898 {
1899 /*Clear previous batch scan response data if any*/
1900 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1901 }
1902 else
1903 {
1904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1905 "Invalid total length from user space can't fetch batch"
1906 " scan response total_len %d used_len %d remain len %d",
1907 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1908 ret = -EINVAL;
1909 goto exit;
1910 }
1911 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1912 }
1913
1914exit:
1915
1916 return ret;
1917}
1918
1919
Rajeev79dbe4c2013-10-05 11:03:42 +05301920#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1921
c_hpothu92367912014-05-01 15:18:17 +05301922static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1923{
c_hpothu39eb1e32014-06-26 16:31:50 +05301924 bcnMissRateContext_t *pCBCtx;
1925
1926 if (NULL == data)
1927 {
1928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1929 return;
1930 }
c_hpothu92367912014-05-01 15:18:17 +05301931
1932 /* there is a race condition that exists between this callback
1933 function and the caller since the caller could time out either
1934 before or while this code is executing. we use a spinlock to
1935 serialize these actions */
1936 spin_lock(&hdd_context_lock);
1937
c_hpothu39eb1e32014-06-26 16:31:50 +05301938 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301939 gbcnMissRate = -1;
1940
c_hpothu39eb1e32014-06-26 16:31:50 +05301941 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301942 {
1943 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301944 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301945 spin_unlock(&hdd_context_lock);
1946 return ;
1947 }
1948
1949 if (VOS_STATUS_SUCCESS == status)
1950 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301951 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301952 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301953 else
1954 {
1955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1956 }
1957
c_hpothu92367912014-05-01 15:18:17 +05301958 complete(&(pCBCtx->completion));
1959 spin_unlock(&hdd_context_lock);
1960
1961 return;
1962}
1963
Abhishek Singh08aa7762014-12-16 13:59:03 +05301964void hdd_FWStatisCB( VOS_STATUS status,
1965 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301966{
1967 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301968 hdd_adapter_t *pAdapter;
1969
1970 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1971
Abhishek Singh08aa7762014-12-16 13:59:03 +05301972 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301973 {
1974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1975 return;
1976 }
1977 /* there is a race condition that exists between this callback
1978 function and the caller since the caller could time out either
1979 before or while this code is executing. we use a spinlock to
1980 serialize these actions */
1981 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301982 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301983 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1984 {
1985 hddLog(VOS_TRACE_LEVEL_ERROR,
1986 FL("invalid context magic: %08x"), fwStatsCtx->magic);
1987 spin_unlock(&hdd_context_lock);
1988 return;
1989 }
1990 pAdapter = fwStatsCtx->pAdapter;
1991 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1992 {
1993 hddLog(VOS_TRACE_LEVEL_ERROR,
1994 FL("pAdapter returned is NULL or invalid"));
1995 spin_unlock(&hdd_context_lock);
1996 return;
1997 }
1998 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05301999 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302000 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302001 switch( fwStatsResult->type )
2002 {
2003 case FW_UBSP_STATS:
2004 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302005 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302006 hddLog(VOS_TRACE_LEVEL_INFO,
2007 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302008 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2009 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302010 }
2011 break;
2012 default:
2013 {
2014 hddLog(VOS_TRACE_LEVEL_ERROR,
2015 FL(" No handling for stats type %d"),fwStatsResult->type);
2016 }
2017 }
2018 }
2019 complete(&(fwStatsCtx->completion));
2020 spin_unlock(&hdd_context_lock);
2021 return;
2022}
2023
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302024static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2025{
2026 int ret = 0;
2027
2028 if (!pCfg || !command || !extra || !len)
2029 {
2030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2031 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2032 ret = -EINVAL;
2033 return ret;
2034 }
2035
2036 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2037 {
2038 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2039 (int)pCfg->nActiveMaxChnTime);
2040 return ret;
2041 }
2042 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2043 {
2044 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2045 (int)pCfg->nActiveMinChnTime);
2046 return ret;
2047 }
2048 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2049 {
2050 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2051 (int)pCfg->nPassiveMaxChnTime);
2052 return ret;
2053 }
2054 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2055 {
2056 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2057 (int)pCfg->nPassiveMinChnTime);
2058 return ret;
2059 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302060 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2061 {
2062 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2063 (int)pCfg->nActiveMaxChnTime);
2064 return ret;
2065 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302066 else
2067 {
2068 ret = -EINVAL;
2069 }
2070
2071 return ret;
2072}
2073
2074static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2075{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302076 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302077 hdd_config_t *pCfg;
2078 tANI_U8 *value = command;
2079 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302080 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302081
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302082 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2083 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302084 {
2085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2086 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2087 ret = -EINVAL;
2088 return ret;
2089 }
2090
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302091 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2092 sme_GetConfigParam(hHal, &smeConfig);
2093
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302094 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2095 {
2096 value = value + 24;
2097 temp = kstrtou32(value, 10, &val);
2098 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2099 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2100 {
2101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2102 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2103 ret = -EFAULT;
2104 return ret;
2105 }
2106 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302107 smeConfig.csrConfig.nActiveMaxChnTime = val;
2108 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302109 }
2110 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2111 {
2112 value = value + 24;
2113 temp = kstrtou32(value, 10, &val);
2114 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2115 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2116 {
2117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2118 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2119 ret = -EFAULT;
2120 return ret;
2121 }
2122 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302123 smeConfig.csrConfig.nActiveMinChnTime = val;
2124 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302125 }
2126 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2127 {
2128 value = value + 25;
2129 temp = kstrtou32(value, 10, &val);
2130 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2131 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2132 {
2133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2134 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2135 ret = -EFAULT;
2136 return ret;
2137 }
2138 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302139 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2140 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302141 }
2142 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2143 {
2144 value = value + 25;
2145 temp = kstrtou32(value, 10, &val);
2146 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2147 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2148 {
2149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2150 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2151 ret = -EFAULT;
2152 return ret;
2153 }
2154 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302155 smeConfig.csrConfig.nPassiveMinChnTime = val;
2156 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302157 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302158 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2159 {
2160 value = value + 13;
2161 temp = kstrtou32(value, 10, &val);
2162 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2163 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2164 {
2165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2166 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2167 ret = -EFAULT;
2168 return ret;
2169 }
2170 pCfg->nActiveMaxChnTime = val;
2171 smeConfig.csrConfig.nActiveMaxChnTime = val;
2172 sme_UpdateConfig(hHal, &smeConfig);
2173 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302174 else
2175 {
2176 ret = -EINVAL;
2177 }
2178
2179 return ret;
2180}
2181
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002182static int hdd_driver_command(hdd_adapter_t *pAdapter,
2183 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002184{
Jeff Johnson295189b2012-06-20 16:38:30 -07002185 hdd_priv_data_t priv_data;
2186 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302187 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2188 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002189 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302190 int status;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002191 /*
2192 * Note that valid pointers are provided by caller
2193 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002194
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002195 /* copy to local struct to avoid numerous changes to legacy code */
2196 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002197
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002198 if (priv_data.total_len <= 0 ||
2199 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002200 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002201 hddLog(VOS_TRACE_LEVEL_WARN,
2202 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2203 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002204 ret = -EINVAL;
2205 goto exit;
2206 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302207 status = wlan_hdd_validate_context(pHddCtx);
2208 if (0 != status)
2209 {
2210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2211 "%s: HDD context is not valid", __func__);
2212 return status;
2213 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002214 /* Allocate +1 for '\0' */
2215 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002216 if (!command)
2217 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002218 hddLog(VOS_TRACE_LEVEL_ERROR,
2219 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002220 ret = -ENOMEM;
2221 goto exit;
2222 }
2223
2224 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2225 {
2226 ret = -EFAULT;
2227 goto exit;
2228 }
2229
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002230 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002231 command[priv_data.total_len] = '\0';
2232
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002233 /* at one time the following block of code was conditional. braces
2234 * have been retained to avoid re-indenting the legacy code
2235 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002236 {
2237 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2238
2239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002240 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002241
2242 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2243 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302244 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2245 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2246 pAdapter->sessionId, (unsigned)
2247 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2248 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2249 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2250 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002251 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2252 sizeof(tSirMacAddr)))
2253 {
2254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002255 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002256 ret = -EFAULT;
2257 }
2258 }
Amar Singhal0974e402013-02-12 14:27:46 -08002259 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 {
Amar Singhal0974e402013-02-12 14:27:46 -08002261 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002262
Jeff Johnson295189b2012-06-20 16:38:30 -07002263 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002264
2265 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002266 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002268 "%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 -07002269 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002270 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302271 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302272 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002273 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002274 }
Kiet Lamf040f472013-11-20 21:15:23 +05302275 else if(strncmp(command, "SETWMMPS", 8) == 0)
2276 {
2277 tANI_U8 *ptr = command;
2278 ret = hdd_wmmps_helper(pAdapter, ptr);
2279 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302280
2281 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2282 {
2283 tANI_U8 *ptr = command;
2284 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2285 }
2286
Jeff Johnson32d95a32012-09-10 13:15:23 -07002287 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2288 {
2289 char *country_code;
2290
2291 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002292
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002293 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002294 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002295#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302296 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002297#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002298 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2299 (void *)(tSmeChangeCountryCallback)
2300 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302301 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002302 if (eHAL_STATUS_SUCCESS == ret)
2303 {
2304 ret = wait_for_completion_interruptible_timeout(
2305 &pAdapter->change_country_code,
2306 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2307 if (0 >= ret)
2308 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302310 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002311 }
2312 }
2313 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002314 {
2315 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002316 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002317 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002318 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002319
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002320 }
2321 /*
2322 command should be a string having format
2323 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2324 */
Amar Singhal0974e402013-02-12 14:27:46 -08002325 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002326 {
Amar Singhal0974e402013-02-12 14:27:46 -08002327 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002328
2329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002330 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002331
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002332 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002333 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002334 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2335 {
2336 int suspend = 0;
2337 tANI_U8 *ptr = (tANI_U8*)command + 15;
2338
2339 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302340 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2341 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2342 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002343 hdd_set_wlan_suspend_mode(suspend);
2344 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002345#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2346 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2347 {
2348 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002349 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002350 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2351 eHalStatus status = eHAL_STATUS_SUCCESS;
2352
2353 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2354 value = value + 15;
2355
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002356 /* Convert the value from ascii to integer */
2357 ret = kstrtos8(value, 10, &rssi);
2358 if (ret < 0)
2359 {
2360 /* If the input value is greater than max value of datatype, then also
2361 kstrtou8 fails */
2362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2363 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002364 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002365 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2366 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2367 ret = -EINVAL;
2368 goto exit;
2369 }
2370
Srinivas Girigowdade697412013-02-14 16:31:48 -08002371 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002372
Srinivas Girigowdade697412013-02-14 16:31:48 -08002373 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2374 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2375 {
2376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2377 "Neighbor lookup threshold value %d is out of range"
2378 " (Min: %d Max: %d)", lookUpThreshold,
2379 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2380 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2381 ret = -EINVAL;
2382 goto exit;
2383 }
2384
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302385 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2386 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2387 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2389 "%s: Received Command to Set Roam trigger"
2390 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2391
2392 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2393 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2394 if (eHAL_STATUS_SUCCESS != status)
2395 {
2396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2397 "%s: Failed to set roam trigger, try again", __func__);
2398 ret = -EPERM;
2399 goto exit;
2400 }
2401
2402 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302403 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002404 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2405 }
2406 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2407 {
2408 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2409 int rssi = (-1) * lookUpThreshold;
2410 char extra[32];
2411 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302412 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2413 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2414 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002415 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002416 if (copy_to_user(priv_data.buf, &extra, len + 1))
2417 {
2418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2419 "%s: failed to copy data to user buffer", __func__);
2420 ret = -EFAULT;
2421 goto exit;
2422 }
2423 }
2424 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2425 {
2426 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002427 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002428 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002429
Srinivas Girigowdade697412013-02-14 16:31:48 -08002430 /* input refresh period is in terms of seconds */
2431 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2432 value = value + 18;
2433 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002434 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002435 if (ret < 0)
2436 {
2437 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002438 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002440 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002441 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002442 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2443 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002444 ret = -EINVAL;
2445 goto exit;
2446 }
2447
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002448 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2449 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002450 {
2451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002452 "Roam scan period value %d is out of range"
2453 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002454 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2455 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002456 ret = -EINVAL;
2457 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302458 }
2459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2460 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2461 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002462 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002463
2464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2465 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002466 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002467
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002468 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2469 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002470 }
2471 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2472 {
2473 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2474 char extra[32];
2475 tANI_U8 len = 0;
2476
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302477 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2478 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2479 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002480 len = scnprintf(extra, sizeof(extra), "%s %d",
2481 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002482 /* Returned value is in units of seconds */
2483 if (copy_to_user(priv_data.buf, &extra, len + 1))
2484 {
2485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2486 "%s: failed to copy data to user buffer", __func__);
2487 ret = -EFAULT;
2488 goto exit;
2489 }
2490 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002491 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2492 {
2493 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002494 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002495 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002496
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002497 /* input refresh period is in terms of seconds */
2498 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2499 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002500
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002501 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002502 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002503 if (ret < 0)
2504 {
2505 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002506 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002508 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002509 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002510 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2511 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2512 ret = -EINVAL;
2513 goto exit;
2514 }
2515
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002516 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2517 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2518 {
2519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2520 "Neighbor scan results refresh period value %d is out of range"
2521 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2522 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2523 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2524 ret = -EINVAL;
2525 goto exit;
2526 }
2527 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2528
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2530 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002531 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002532
2533 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2534 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2535 }
2536 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2537 {
2538 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2539 char extra[32];
2540 tANI_U8 len = 0;
2541
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002542 len = scnprintf(extra, sizeof(extra), "%s %d",
2543 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002544 /* Returned value is in units of seconds */
2545 if (copy_to_user(priv_data.buf, &extra, len + 1))
2546 {
2547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2548 "%s: failed to copy data to user buffer", __func__);
2549 ret = -EFAULT;
2550 goto exit;
2551 }
2552 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002553#ifdef FEATURE_WLAN_LFR
2554 /* SETROAMMODE */
2555 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2556 {
2557 tANI_U8 *value = command;
2558 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2559
2560 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2561 value = value + SIZE_OF_SETROAMMODE + 1;
2562
2563 /* Convert the value from ascii to integer */
2564 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2565 if (ret < 0)
2566 {
2567 /* If the input value is greater than max value of datatype, then also
2568 kstrtou8 fails */
2569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2570 "%s: kstrtou8 failed range [%d - %d]", __func__,
2571 CFG_LFR_FEATURE_ENABLED_MIN,
2572 CFG_LFR_FEATURE_ENABLED_MAX);
2573 ret = -EINVAL;
2574 goto exit;
2575 }
2576 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2577 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2578 {
2579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2580 "Roam Mode value %d is out of range"
2581 " (Min: %d Max: %d)", roamMode,
2582 CFG_LFR_FEATURE_ENABLED_MIN,
2583 CFG_LFR_FEATURE_ENABLED_MAX);
2584 ret = -EINVAL;
2585 goto exit;
2586 }
2587
2588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2589 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2590 /*
2591 * Note that
2592 * SETROAMMODE 0 is to enable LFR while
2593 * SETROAMMODE 1 is to disable LFR, but
2594 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2595 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2596 */
2597 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2598 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2599 else
2600 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2601
2602 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2603 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2604 }
2605 /* GETROAMMODE */
2606 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2607 {
2608 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2609 char extra[32];
2610 tANI_U8 len = 0;
2611
2612 /*
2613 * roamMode value shall be inverted because the sementics is different.
2614 */
2615 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2616 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2617 else
2618 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2619
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002620 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002621 if (copy_to_user(priv_data.buf, &extra, len + 1))
2622 {
2623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2624 "%s: failed to copy data to user buffer", __func__);
2625 ret = -EFAULT;
2626 goto exit;
2627 }
2628 }
2629#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002630#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002631#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002632 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2633 {
2634 tANI_U8 *value = command;
2635 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2636
2637 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2638 value = value + 13;
2639 /* Convert the value from ascii to integer */
2640 ret = kstrtou8(value, 10, &roamRssiDiff);
2641 if (ret < 0)
2642 {
2643 /* If the input value is greater than max value of datatype, then also
2644 kstrtou8 fails */
2645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2646 "%s: kstrtou8 failed range [%d - %d]", __func__,
2647 CFG_ROAM_RSSI_DIFF_MIN,
2648 CFG_ROAM_RSSI_DIFF_MAX);
2649 ret = -EINVAL;
2650 goto exit;
2651 }
2652
2653 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2654 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2655 {
2656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2657 "Roam rssi diff value %d is out of range"
2658 " (Min: %d Max: %d)", roamRssiDiff,
2659 CFG_ROAM_RSSI_DIFF_MIN,
2660 CFG_ROAM_RSSI_DIFF_MAX);
2661 ret = -EINVAL;
2662 goto exit;
2663 }
2664
2665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2666 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2667
2668 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2669 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2670 }
2671 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2672 {
2673 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2674 char extra[32];
2675 tANI_U8 len = 0;
2676
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302677 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2678 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2679 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002680 len = scnprintf(extra, sizeof(extra), "%s %d",
2681 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002682 if (copy_to_user(priv_data.buf, &extra, len + 1))
2683 {
2684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2685 "%s: failed to copy data to user buffer", __func__);
2686 ret = -EFAULT;
2687 goto exit;
2688 }
2689 }
2690#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002691#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002692 else if (strncmp(command, "GETBAND", 7) == 0)
2693 {
2694 int band = -1;
2695 char extra[32];
2696 tANI_U8 len = 0;
2697 hdd_getBand_helper(pHddCtx, &band);
2698
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302699 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2700 TRACE_CODE_HDD_GETBAND_IOCTL,
2701 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002702 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002703 if (copy_to_user(priv_data.buf, &extra, len + 1))
2704 {
2705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2706 "%s: failed to copy data to user buffer", __func__);
2707 ret = -EFAULT;
2708 goto exit;
2709 }
2710 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002711 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2712 {
2713 tANI_U8 *value = command;
2714 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2715 tANI_U8 numChannels = 0;
2716 eHalStatus status = eHAL_STATUS_SUCCESS;
2717
2718 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2719 if (eHAL_STATUS_SUCCESS != status)
2720 {
2721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2722 "%s: Failed to parse channel list information", __func__);
2723 ret = -EINVAL;
2724 goto exit;
2725 }
2726
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302727 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2728 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2729 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002730 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2734 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2735 ret = -EINVAL;
2736 goto exit;
2737 }
2738 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2739 numChannels);
2740 if (eHAL_STATUS_SUCCESS != status)
2741 {
2742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2743 "%s: Failed to update channel list information", __func__);
2744 ret = -EINVAL;
2745 goto exit;
2746 }
2747 }
2748 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2749 {
2750 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2751 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002752 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002753 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002754 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002755
2756 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2757 ChannelList, &numChannels ))
2758 {
2759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2760 "%s: failed to get roam scan channel list", __func__);
2761 ret = -EFAULT;
2762 goto exit;
2763 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302764 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2765 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2766 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002767 /* output channel list is of the format
2768 [Number of roam scan channels][Channel1][Channel2]... */
2769 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002770 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002771 for (j = 0; (j < numChannels); j++)
2772 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002773 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2774 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002775 }
2776
2777 if (copy_to_user(priv_data.buf, &extra, len + 1))
2778 {
2779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2780 "%s: failed to copy data to user buffer", __func__);
2781 ret = -EFAULT;
2782 goto exit;
2783 }
2784 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002785 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2786 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002787 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002788 char extra[32];
2789 tANI_U8 len = 0;
2790
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002791 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002792 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002793 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002794 hdd_is_okc_mode_enabled(pHddCtx) &&
2795 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2796 {
2797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002798 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002799 " hence this operation is not permitted!", __func__);
2800 ret = -EPERM;
2801 goto exit;
2802 }
2803
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002804 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002805 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002806 if (copy_to_user(priv_data.buf, &extra, len + 1))
2807 {
2808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2809 "%s: failed to copy data to user buffer", __func__);
2810 ret = -EFAULT;
2811 goto exit;
2812 }
2813 }
2814 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2815 {
2816 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2817 char extra[32];
2818 tANI_U8 len = 0;
2819
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002820 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002821 then this operation is not permitted (return FAILURE) */
2822 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002823 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002824 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2825 {
2826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002827 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002828 " hence this operation is not permitted!", __func__);
2829 ret = -EPERM;
2830 goto exit;
2831 }
2832
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002833 len = scnprintf(extra, sizeof(extra), "%s %d",
2834 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002835 if (copy_to_user(priv_data.buf, &extra, len + 1))
2836 {
2837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2838 "%s: failed to copy data to user buffer", __func__);
2839 ret = -EFAULT;
2840 goto exit;
2841 }
2842 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002843 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002844 {
2845 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2846 char extra[32];
2847 tANI_U8 len = 0;
2848
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002849 len = scnprintf(extra, sizeof(extra), "%s %d",
2850 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002851 if (copy_to_user(priv_data.buf, &extra, len + 1))
2852 {
2853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2854 "%s: failed to copy data to user buffer", __func__);
2855 ret = -EFAULT;
2856 goto exit;
2857 }
2858 }
2859 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2860 {
2861 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2862 char extra[32];
2863 tANI_U8 len = 0;
2864
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002865 len = scnprintf(extra, sizeof(extra), "%s %d",
2866 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002867 if (copy_to_user(priv_data.buf, &extra, len + 1))
2868 {
2869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2870 "%s: failed to copy data to user buffer", __func__);
2871 ret = -EFAULT;
2872 goto exit;
2873 }
2874 }
2875 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2876 {
2877 tANI_U8 *value = command;
2878 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2879
2880 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2881 value = value + 26;
2882 /* Convert the value from ascii to integer */
2883 ret = kstrtou8(value, 10, &minTime);
2884 if (ret < 0)
2885 {
2886 /* If the input value is greater than max value of datatype, then also
2887 kstrtou8 fails */
2888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2889 "%s: kstrtou8 failed range [%d - %d]", __func__,
2890 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2891 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2892 ret = -EINVAL;
2893 goto exit;
2894 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002895 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2896 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2897 {
2898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2899 "scan min channel time value %d is out of range"
2900 " (Min: %d Max: %d)", minTime,
2901 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2902 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2903 ret = -EINVAL;
2904 goto exit;
2905 }
2906
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302907 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2908 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2909 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2911 "%s: Received Command to change channel min time = %d", __func__, minTime);
2912
2913 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2914 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2915 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002916 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2917 {
2918 tANI_U8 *value = command;
2919 tANI_U8 channel = 0;
2920 tANI_U8 dwellTime = 0;
2921 tANI_U8 bufLen = 0;
2922 tANI_U8 *buf = NULL;
2923 tSirMacAddr targetApBssid;
2924 eHalStatus status = eHAL_STATUS_SUCCESS;
2925 struct ieee80211_channel chan;
2926 tANI_U8 finalLen = 0;
2927 tANI_U8 *finalBuf = NULL;
2928 tANI_U8 temp = 0;
2929 u64 cookie;
2930 hdd_station_ctx_t *pHddStaCtx = NULL;
2931 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2932
2933 /* if not associated, no need to send action frame */
2934 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2935 {
2936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2937 ret = -EINVAL;
2938 goto exit;
2939 }
2940
2941 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2942 &dwellTime, &buf, &bufLen);
2943 if (eHAL_STATUS_SUCCESS != status)
2944 {
2945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2946 "%s: Failed to parse send action frame data", __func__);
2947 ret = -EINVAL;
2948 goto exit;
2949 }
2950
2951 /* if the target bssid is different from currently associated AP,
2952 then no need to send action frame */
2953 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2954 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2955 {
2956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2957 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002958 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002959 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002960 goto exit;
2961 }
2962
2963 /* if the channel number is different from operating channel then
2964 no need to send action frame */
2965 if (channel != pHddStaCtx->conn_info.operationChannel)
2966 {
2967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2968 "%s: channel(%d) is different from operating channel(%d)",
2969 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2970 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002971 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002972 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002973 goto exit;
2974 }
2975 chan.center_freq = sme_ChnToFreq(channel);
2976
2977 finalLen = bufLen + 24;
2978 finalBuf = vos_mem_malloc(finalLen);
2979 if (NULL == finalBuf)
2980 {
2981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2982 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002983 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002984 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002985 goto exit;
2986 }
2987 vos_mem_zero(finalBuf, finalLen);
2988
2989 /* Fill subtype */
2990 temp = SIR_MAC_MGMT_ACTION << 4;
2991 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
2992
2993 /* Fill type */
2994 temp = SIR_MAC_MGMT_FRAME;
2995 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
2996
2997 /* Fill destination address (bssid of the AP) */
2998 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
2999
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003000 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003001 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3002
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003003 /* Fill BSSID (AP mac address) */
3004 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003005
3006 /* Fill received buffer from 24th address */
3007 vos_mem_copy(finalBuf + 24, buf, bufLen);
3008
Jeff Johnson11c33152013-04-16 17:52:40 -07003009 /* done with the parsed buffer */
3010 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003011 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003012
DARAM SUDHA39eede62014-02-12 11:16:40 +05303013 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3015 &(pAdapter->wdev),
3016#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003017 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003018#endif
3019 &chan, 0,
3020#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3021 NL80211_CHAN_HT20, 1,
3022#endif
3023 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003024 1, &cookie );
3025 vos_mem_free(finalBuf);
3026 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003027 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3028 {
3029 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3030 char extra[32];
3031 tANI_U8 len = 0;
3032
3033 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003034 len = scnprintf(extra, sizeof(extra), "%s %d",
3035 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303036 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3037 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3038 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003039 if (copy_to_user(priv_data.buf, &extra, len + 1))
3040 {
3041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3042 "%s: failed to copy data to user buffer", __func__);
3043 ret = -EFAULT;
3044 goto exit;
3045 }
3046 }
3047 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3048 {
3049 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003050 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003051
3052 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3053 value = value + 19;
3054 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003055 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003056 if (ret < 0)
3057 {
3058 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003059 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003061 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003062 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3063 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3064 ret = -EINVAL;
3065 goto exit;
3066 }
3067
3068 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3069 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3070 {
3071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3072 "lfr mode value %d is out of range"
3073 " (Min: %d Max: %d)", maxTime,
3074 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3075 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3076 ret = -EINVAL;
3077 goto exit;
3078 }
3079
3080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3081 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3082
3083 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3084 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3085 }
3086 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3087 {
3088 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3089 char extra[32];
3090 tANI_U8 len = 0;
3091
3092 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003093 len = scnprintf(extra, sizeof(extra), "%s %d",
3094 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003095 if (copy_to_user(priv_data.buf, &extra, len + 1))
3096 {
3097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3098 "%s: failed to copy data to user buffer", __func__);
3099 ret = -EFAULT;
3100 goto exit;
3101 }
3102 }
3103 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3104 {
3105 tANI_U8 *value = command;
3106 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3107
3108 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3109 value = value + 16;
3110 /* Convert the value from ascii to integer */
3111 ret = kstrtou16(value, 10, &val);
3112 if (ret < 0)
3113 {
3114 /* If the input value is greater than max value of datatype, then also
3115 kstrtou16 fails */
3116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3117 "%s: kstrtou16 failed range [%d - %d]", __func__,
3118 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3119 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3120 ret = -EINVAL;
3121 goto exit;
3122 }
3123
3124 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3125 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3126 {
3127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3128 "scan home time value %d is out of range"
3129 " (Min: %d Max: %d)", val,
3130 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3131 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3132 ret = -EINVAL;
3133 goto exit;
3134 }
3135
3136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3137 "%s: Received Command to change scan home time = %d", __func__, val);
3138
3139 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3140 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3141 }
3142 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3143 {
3144 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3145 char extra[32];
3146 tANI_U8 len = 0;
3147
3148 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003149 len = scnprintf(extra, sizeof(extra), "%s %d",
3150 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003151 if (copy_to_user(priv_data.buf, &extra, len + 1))
3152 {
3153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3154 "%s: failed to copy data to user buffer", __func__);
3155 ret = -EFAULT;
3156 goto exit;
3157 }
3158 }
3159 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3160 {
3161 tANI_U8 *value = command;
3162 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3163
3164 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3165 value = value + 17;
3166 /* Convert the value from ascii to integer */
3167 ret = kstrtou8(value, 10, &val);
3168 if (ret < 0)
3169 {
3170 /* If the input value is greater than max value of datatype, then also
3171 kstrtou8 fails */
3172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3173 "%s: kstrtou8 failed range [%d - %d]", __func__,
3174 CFG_ROAM_INTRA_BAND_MIN,
3175 CFG_ROAM_INTRA_BAND_MAX);
3176 ret = -EINVAL;
3177 goto exit;
3178 }
3179
3180 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3181 (val > CFG_ROAM_INTRA_BAND_MAX))
3182 {
3183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3184 "intra band mode value %d is out of range"
3185 " (Min: %d Max: %d)", val,
3186 CFG_ROAM_INTRA_BAND_MIN,
3187 CFG_ROAM_INTRA_BAND_MAX);
3188 ret = -EINVAL;
3189 goto exit;
3190 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3192 "%s: Received Command to change intra band = %d", __func__, val);
3193
3194 pHddCtx->cfg_ini->nRoamIntraBand = val;
3195 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3196 }
3197 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3198 {
3199 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3200 char extra[32];
3201 tANI_U8 len = 0;
3202
3203 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003204 len = scnprintf(extra, sizeof(extra), "%s %d",
3205 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003206 if (copy_to_user(priv_data.buf, &extra, len + 1))
3207 {
3208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3209 "%s: failed to copy data to user buffer", __func__);
3210 ret = -EFAULT;
3211 goto exit;
3212 }
3213 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003214 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3215 {
3216 tANI_U8 *value = command;
3217 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3218
3219 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3220 value = value + 15;
3221 /* Convert the value from ascii to integer */
3222 ret = kstrtou8(value, 10, &nProbes);
3223 if (ret < 0)
3224 {
3225 /* If the input value is greater than max value of datatype, then also
3226 kstrtou8 fails */
3227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3228 "%s: kstrtou8 failed range [%d - %d]", __func__,
3229 CFG_ROAM_SCAN_N_PROBES_MIN,
3230 CFG_ROAM_SCAN_N_PROBES_MAX);
3231 ret = -EINVAL;
3232 goto exit;
3233 }
3234
3235 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3236 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3237 {
3238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3239 "NProbes value %d is out of range"
3240 " (Min: %d Max: %d)", nProbes,
3241 CFG_ROAM_SCAN_N_PROBES_MIN,
3242 CFG_ROAM_SCAN_N_PROBES_MAX);
3243 ret = -EINVAL;
3244 goto exit;
3245 }
3246
3247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3248 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3249
3250 pHddCtx->cfg_ini->nProbes = nProbes;
3251 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3252 }
3253 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3254 {
3255 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3256 char extra[32];
3257 tANI_U8 len = 0;
3258
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003259 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003260 if (copy_to_user(priv_data.buf, &extra, len + 1))
3261 {
3262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3263 "%s: failed to copy data to user buffer", __func__);
3264 ret = -EFAULT;
3265 goto exit;
3266 }
3267 }
3268 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3269 {
3270 tANI_U8 *value = command;
3271 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3272
3273 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3274 /* input value is in units of msec */
3275 value = value + 20;
3276 /* Convert the value from ascii to integer */
3277 ret = kstrtou16(value, 10, &homeAwayTime);
3278 if (ret < 0)
3279 {
3280 /* If the input value is greater than max value of datatype, then also
3281 kstrtou8 fails */
3282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3283 "%s: kstrtou8 failed range [%d - %d]", __func__,
3284 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3285 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3286 ret = -EINVAL;
3287 goto exit;
3288 }
3289
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003290 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3291 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3292 {
3293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3294 "homeAwayTime value %d is out of range"
3295 " (Min: %d Max: %d)", homeAwayTime,
3296 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3297 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3298 ret = -EINVAL;
3299 goto exit;
3300 }
3301
3302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3303 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003304 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3305 {
3306 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3307 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3308 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003309 }
3310 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3311 {
3312 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3313 char extra[32];
3314 tANI_U8 len = 0;
3315
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003316 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003317 if (copy_to_user(priv_data.buf, &extra, len + 1))
3318 {
3319 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3320 "%s: failed to copy data to user buffer", __func__);
3321 ret = -EFAULT;
3322 goto exit;
3323 }
3324 }
3325 else if (strncmp(command, "REASSOC", 7) == 0)
3326 {
3327 tANI_U8 *value = command;
3328 tANI_U8 channel = 0;
3329 tSirMacAddr targetApBssid;
3330 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003331#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3332 tCsrHandoffRequest handoffInfo;
3333#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003334 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003335 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3336
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003337 /* if not associated, no need to proceed with reassoc */
3338 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3339 {
3340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3341 ret = -EINVAL;
3342 goto exit;
3343 }
3344
3345 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3346 if (eHAL_STATUS_SUCCESS != status)
3347 {
3348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3349 "%s: Failed to parse reassoc command data", __func__);
3350 ret = -EINVAL;
3351 goto exit;
3352 }
3353
3354 /* if the target bssid is same as currently associated AP,
3355 then no need to proceed with reassoc */
3356 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3357 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3358 {
3359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3360 ret = -EINVAL;
3361 goto exit;
3362 }
3363
3364 /* Check channel number is a valid channel number */
3365 if(VOS_STATUS_SUCCESS !=
3366 wlan_hdd_validate_operation_channel(pAdapter, channel))
3367 {
3368 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003369 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003370 return -EINVAL;
3371 }
3372
3373 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003374#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3375 handoffInfo.channel = channel;
3376 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3377 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3378#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003379 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003380 else if (strncmp(command, "SETWESMODE", 10) == 0)
3381 {
3382 tANI_U8 *value = command;
3383 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3384
3385 /* Move pointer to ahead of SETWESMODE<delimiter> */
3386 value = value + 11;
3387 /* Convert the value from ascii to integer */
3388 ret = kstrtou8(value, 10, &wesMode);
3389 if (ret < 0)
3390 {
3391 /* If the input value is greater than max value of datatype, then also
3392 kstrtou8 fails */
3393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3394 "%s: kstrtou8 failed range [%d - %d]", __func__,
3395 CFG_ENABLE_WES_MODE_NAME_MIN,
3396 CFG_ENABLE_WES_MODE_NAME_MAX);
3397 ret = -EINVAL;
3398 goto exit;
3399 }
3400
3401 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3402 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3403 {
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3405 "WES Mode value %d is out of range"
3406 " (Min: %d Max: %d)", wesMode,
3407 CFG_ENABLE_WES_MODE_NAME_MIN,
3408 CFG_ENABLE_WES_MODE_NAME_MAX);
3409 ret = -EINVAL;
3410 goto exit;
3411 }
3412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3413 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3414
3415 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3416 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3417 }
3418 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3419 {
3420 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3421 char extra[32];
3422 tANI_U8 len = 0;
3423
Arif Hussain826d9412013-11-12 16:44:54 -08003424 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003425 if (copy_to_user(priv_data.buf, &extra, len + 1))
3426 {
3427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3428 "%s: failed to copy data to user buffer", __func__);
3429 ret = -EFAULT;
3430 goto exit;
3431 }
3432 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003433#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003434#ifdef FEATURE_WLAN_LFR
3435 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3436 {
3437 tANI_U8 *value = command;
3438 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3439
3440 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3441 value = value + 12;
3442 /* Convert the value from ascii to integer */
3443 ret = kstrtou8(value, 10, &lfrMode);
3444 if (ret < 0)
3445 {
3446 /* If the input value is greater than max value of datatype, then also
3447 kstrtou8 fails */
3448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3449 "%s: kstrtou8 failed range [%d - %d]", __func__,
3450 CFG_LFR_FEATURE_ENABLED_MIN,
3451 CFG_LFR_FEATURE_ENABLED_MAX);
3452 ret = -EINVAL;
3453 goto exit;
3454 }
3455
3456 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3457 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3458 {
3459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3460 "lfr mode value %d is out of range"
3461 " (Min: %d Max: %d)", lfrMode,
3462 CFG_LFR_FEATURE_ENABLED_MIN,
3463 CFG_LFR_FEATURE_ENABLED_MAX);
3464 ret = -EINVAL;
3465 goto exit;
3466 }
3467
3468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3469 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3470
3471 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3472 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3473 }
3474#endif
3475#ifdef WLAN_FEATURE_VOWIFI_11R
3476 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3477 {
3478 tANI_U8 *value = command;
3479 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3480
3481 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3482 value = value + 18;
3483 /* Convert the value from ascii to integer */
3484 ret = kstrtou8(value, 10, &ft);
3485 if (ret < 0)
3486 {
3487 /* If the input value is greater than max value of datatype, then also
3488 kstrtou8 fails */
3489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3490 "%s: kstrtou8 failed range [%d - %d]", __func__,
3491 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3492 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3493 ret = -EINVAL;
3494 goto exit;
3495 }
3496
3497 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3498 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3499 {
3500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3501 "ft mode value %d is out of range"
3502 " (Min: %d Max: %d)", ft,
3503 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3504 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3505 ret = -EINVAL;
3506 goto exit;
3507 }
3508
3509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3510 "%s: Received Command to change ft mode = %d", __func__, ft);
3511
3512 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3513 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3514 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303515
3516 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3517 {
3518 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303519 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303520 tSirMacAddr targetApBssid;
3521 tANI_U8 trigger = 0;
3522 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303523 tHalHandle hHal;
3524 v_U32_t roamId = 0;
3525 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303526 hdd_station_ctx_t *pHddStaCtx = NULL;
3527 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303528 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303529
3530 /* if not associated, no need to proceed with reassoc */
3531 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3532 {
3533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3534 ret = -EINVAL;
3535 goto exit;
3536 }
3537
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303538 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303539 if (eHAL_STATUS_SUCCESS != status)
3540 {
3541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3542 "%s: Failed to parse reassoc command data", __func__);
3543 ret = -EINVAL;
3544 goto exit;
3545 }
3546
3547 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303548 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303549 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3550 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3551 {
3552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3553 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3554 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303555 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3556 &modProfileFields);
3557 sme_RoamReassoc(hHal, pAdapter->sessionId,
3558 NULL, modProfileFields, &roamId, 1);
3559 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303560 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303561
3562 /* Check channel number is a valid channel number */
3563 if(VOS_STATUS_SUCCESS !=
3564 wlan_hdd_validate_operation_channel(pAdapter, channel))
3565 {
3566 hddLog(VOS_TRACE_LEVEL_ERROR,
3567 "%s: Invalid Channel [%d]", __func__, channel);
3568 return -EINVAL;
3569 }
3570
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303571 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303572
3573 /* Proceed with scan/roam */
3574 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3575 &targetApBssid[0],
3576 (tSmeFastRoamTrigger)(trigger));
3577 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003578#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003579#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003580 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3581 {
3582 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003583 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003584
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003585 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003586 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003587 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003588 hdd_is_okc_mode_enabled(pHddCtx) &&
3589 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3590 {
3591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003592 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003593 " hence this operation is not permitted!", __func__);
3594 ret = -EPERM;
3595 goto exit;
3596 }
3597
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003598 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3599 value = value + 11;
3600 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003601 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003602 if (ret < 0)
3603 {
3604 /* If the input value is greater than max value of datatype, then also
3605 kstrtou8 fails */
3606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3607 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003608 CFG_ESE_FEATURE_ENABLED_MIN,
3609 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003610 ret = -EINVAL;
3611 goto exit;
3612 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003613 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3614 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003615 {
3616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003617 "Ese mode value %d is out of range"
3618 " (Min: %d Max: %d)", eseMode,
3619 CFG_ESE_FEATURE_ENABLED_MIN,
3620 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003621 ret = -EINVAL;
3622 goto exit;
3623 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003625 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003626
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003627 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3628 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003629 }
3630#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003631 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3632 {
3633 tANI_U8 *value = command;
3634 tANI_BOOLEAN roamScanControl = 0;
3635
3636 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3637 value = value + 19;
3638 /* Convert the value from ascii to integer */
3639 ret = kstrtou8(value, 10, &roamScanControl);
3640 if (ret < 0)
3641 {
3642 /* If the input value is greater than max value of datatype, then also
3643 kstrtou8 fails */
3644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3645 "%s: kstrtou8 failed ", __func__);
3646 ret = -EINVAL;
3647 goto exit;
3648 }
3649
3650 if (0 != roamScanControl)
3651 {
3652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3653 "roam scan control invalid value = %d",
3654 roamScanControl);
3655 ret = -EINVAL;
3656 goto exit;
3657 }
3658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3659 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3660
3661 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3662 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003663#ifdef FEATURE_WLAN_OKC
3664 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3665 {
3666 tANI_U8 *value = command;
3667 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3668
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003669 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003670 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003671 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003672 hdd_is_okc_mode_enabled(pHddCtx) &&
3673 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3674 {
3675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003676 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003677 " hence this operation is not permitted!", __func__);
3678 ret = -EPERM;
3679 goto exit;
3680 }
3681
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003682 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3683 value = value + 11;
3684 /* Convert the value from ascii to integer */
3685 ret = kstrtou8(value, 10, &okcMode);
3686 if (ret < 0)
3687 {
3688 /* If the input value is greater than max value of datatype, then also
3689 kstrtou8 fails */
3690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3691 "%s: kstrtou8 failed range [%d - %d]", __func__,
3692 CFG_OKC_FEATURE_ENABLED_MIN,
3693 CFG_OKC_FEATURE_ENABLED_MAX);
3694 ret = -EINVAL;
3695 goto exit;
3696 }
3697
3698 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3699 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3700 {
3701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3702 "Okc mode value %d is out of range"
3703 " (Min: %d Max: %d)", okcMode,
3704 CFG_OKC_FEATURE_ENABLED_MIN,
3705 CFG_OKC_FEATURE_ENABLED_MAX);
3706 ret = -EINVAL;
3707 goto exit;
3708 }
3709
3710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3711 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3712
3713 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3714 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003715#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003716 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3717 {
3718 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3719 char extra[32];
3720 tANI_U8 len = 0;
3721
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003722 len = scnprintf(extra, sizeof(extra), "%s %d",
3723 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003724 if (copy_to_user(priv_data.buf, &extra, len + 1))
3725 {
3726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3727 "%s: failed to copy data to user buffer", __func__);
3728 ret = -EFAULT;
3729 goto exit;
3730 }
3731 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303732#ifdef WLAN_FEATURE_PACKET_FILTERING
3733 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3734 {
3735 tANI_U8 filterType = 0;
3736 tANI_U8 *value = command;
3737
3738 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3739 value = value + 22;
3740
3741 /* Convert the value from ascii to integer */
3742 ret = kstrtou8(value, 10, &filterType);
3743 if (ret < 0)
3744 {
3745 /* If the input value is greater than max value of datatype,
3746 * then also kstrtou8 fails
3747 */
3748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3749 "%s: kstrtou8 failed range ", __func__);
3750 ret = -EINVAL;
3751 goto exit;
3752 }
3753
3754 if (filterType != 0 && filterType != 1)
3755 {
3756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3757 "%s: Accepted Values are 0 and 1 ", __func__);
3758 ret = -EINVAL;
3759 goto exit;
3760 }
3761 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3762 pAdapter->sessionId);
3763 }
3764#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303765 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3766 {
Kiet Lamad161252014-07-22 11:23:32 -07003767 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303768 int ret;
3769
Kiet Lamad161252014-07-22 11:23:32 -07003770 dhcpPhase = command + 11;
3771 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303772 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003774 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303775
3776 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003777
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303778 ret = wlan_hdd_scan_abort(pAdapter);
3779 if (ret < 0)
3780 {
3781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3782 FL("failed to abort existing scan %d"), ret);
3783 }
3784
Kiet Lamad161252014-07-22 11:23:32 -07003785 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3786 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303787 }
Kiet Lamad161252014-07-22 11:23:32 -07003788 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303789 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003791 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303792
3793 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003794
3795 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3796 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303797 }
3798 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003799 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3800 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3802 FL("making default scan to ACTIVE"));
3803 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003804 }
3805 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3806 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3808 FL("making default scan to PASSIVE"));
3809 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003810 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303811 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3812 {
3813 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3814 char extra[32];
3815 tANI_U8 len = 0;
3816
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303817 memset(extra, 0, sizeof(extra));
3818 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3819 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303820 {
3821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3822 "%s: failed to copy data to user buffer", __func__);
3823 ret = -EFAULT;
3824 goto exit;
3825 }
3826 ret = len;
3827 }
3828 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3829 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303830 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303831 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003832 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3833 {
3834 tANI_U8 filterType = 0;
3835 tANI_U8 *value;
3836 value = command + 9;
3837
3838 /* Convert the value from ascii to integer */
3839 ret = kstrtou8(value, 10, &filterType);
3840 if (ret < 0)
3841 {
3842 /* If the input value is greater than max value of datatype,
3843 * then also kstrtou8 fails
3844 */
3845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3846 "%s: kstrtou8 failed range ", __func__);
3847 ret = -EINVAL;
3848 goto exit;
3849 }
3850 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3851 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3852 {
3853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3854 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3855 " 2-Sink ", __func__);
3856 ret = -EINVAL;
3857 goto exit;
3858 }
3859 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3860 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303861 pScanInfo = &pHddCtx->scan_info;
3862 if (filterType && pScanInfo != NULL &&
3863 pHddCtx->scan_info.mScanPending)
3864 {
3865 /*Miracast Session started. Abort Scan */
3866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3867 "%s, Aborting Scan For Miracast",__func__);
3868 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3869 eCSR_SCAN_ABORT_DEFAULT);
3870 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003871 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303872 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003873 }
Leo Chang614d2072013-08-22 14:59:44 -07003874 else if (strncmp(command, "SETMCRATE", 9) == 0)
3875 {
Leo Chang614d2072013-08-22 14:59:44 -07003876 tANI_U8 *value = command;
3877 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003878 tSirRateUpdateInd *rateUpdate;
3879 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003880
3881 /* Only valid for SAP mode */
3882 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3883 {
3884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3885 "%s: SAP mode is not running", __func__);
3886 ret = -EFAULT;
3887 goto exit;
3888 }
3889
3890 /* Move pointer to ahead of SETMCRATE<delimiter> */
3891 /* input value is in units of hundred kbps */
3892 value = value + 10;
3893 /* Convert the value from ascii to integer, decimal base */
3894 ret = kstrtouint(value, 10, &targetRate);
3895
Leo Chang1f98cbd2013-10-17 15:03:52 -07003896 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3897 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003898 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003899 hddLog(VOS_TRACE_LEVEL_ERROR,
3900 "%s: SETMCRATE indication alloc fail", __func__);
3901 ret = -EFAULT;
3902 goto exit;
3903 }
3904 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3905
3906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3907 "MC Target rate %d", targetRate);
3908 /* Ignore unicast */
3909 rateUpdate->ucastDataRate = -1;
3910 rateUpdate->mcastDataRate24GHz = targetRate;
3911 rateUpdate->mcastDataRate5GHz = targetRate;
3912 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3913 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3914 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3915 if (eHAL_STATUS_SUCCESS != status)
3916 {
3917 hddLog(VOS_TRACE_LEVEL_ERROR,
3918 "%s: SET_MC_RATE failed", __func__);
3919 vos_mem_free(rateUpdate);
3920 ret = -EFAULT;
3921 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003922 }
3923 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303924#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003925 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303926 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003927 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303928 }
3929#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003930#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003931 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3932 {
3933 tANI_U8 *value = command;
3934 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3935 tANI_U8 numChannels = 0;
3936 eHalStatus status = eHAL_STATUS_SUCCESS;
3937
3938 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3939 if (eHAL_STATUS_SUCCESS != status)
3940 {
3941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3942 "%s: Failed to parse channel list information", __func__);
3943 ret = -EINVAL;
3944 goto exit;
3945 }
3946
3947 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3948 {
3949 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3950 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3951 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3952 ret = -EINVAL;
3953 goto exit;
3954 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003955 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003956 ChannelList,
3957 numChannels);
3958 if (eHAL_STATUS_SUCCESS != status)
3959 {
3960 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3961 "%s: Failed to update channel list information", __func__);
3962 ret = -EINVAL;
3963 goto exit;
3964 }
3965 }
3966 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3967 {
3968 tANI_U8 *value = command;
3969 char extra[128] = {0};
3970 int len = 0;
3971 tANI_U8 tid = 0;
3972 hdd_station_ctx_t *pHddStaCtx = NULL;
3973 tAniTrafStrmMetrics tsmMetrics;
3974 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3975
3976 /* if not associated, return error */
3977 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3978 {
3979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3980 ret = -EINVAL;
3981 goto exit;
3982 }
3983
3984 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3985 value = value + 12;
3986 /* Convert the value from ascii to integer */
3987 ret = kstrtou8(value, 10, &tid);
3988 if (ret < 0)
3989 {
3990 /* If the input value is greater than max value of datatype, then also
3991 kstrtou8 fails */
3992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3993 "%s: kstrtou8 failed range [%d - %d]", __func__,
3994 TID_MIN_VALUE,
3995 TID_MAX_VALUE);
3996 ret = -EINVAL;
3997 goto exit;
3998 }
3999
4000 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4001 {
4002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4003 "tid value %d is out of range"
4004 " (Min: %d Max: %d)", tid,
4005 TID_MIN_VALUE,
4006 TID_MAX_VALUE);
4007 ret = -EINVAL;
4008 goto exit;
4009 }
4010
4011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4012 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4013
4014 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4015 {
4016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4017 "%s: failed to get tsm stats", __func__);
4018 ret = -EFAULT;
4019 goto exit;
4020 }
4021
4022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4023 "UplinkPktQueueDly(%d)\n"
4024 "UplinkPktQueueDlyHist[0](%d)\n"
4025 "UplinkPktQueueDlyHist[1](%d)\n"
4026 "UplinkPktQueueDlyHist[2](%d)\n"
4027 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304028 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004029 "UplinkPktLoss(%d)\n"
4030 "UplinkPktCount(%d)\n"
4031 "RoamingCount(%d)\n"
4032 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4033 tsmMetrics.UplinkPktQueueDlyHist[0],
4034 tsmMetrics.UplinkPktQueueDlyHist[1],
4035 tsmMetrics.UplinkPktQueueDlyHist[2],
4036 tsmMetrics.UplinkPktQueueDlyHist[3],
4037 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4038 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4039
4040 /* Output TSM stats is of the format
4041 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4042 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004043 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004044 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4045 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4046 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4047 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4048 tsmMetrics.RoamingDly);
4049
4050 if (copy_to_user(priv_data.buf, &extra, len + 1))
4051 {
4052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4053 "%s: failed to copy data to user buffer", __func__);
4054 ret = -EFAULT;
4055 goto exit;
4056 }
4057 }
4058 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4059 {
4060 tANI_U8 *value = command;
4061 tANI_U8 *cckmIe = NULL;
4062 tANI_U8 cckmIeLen = 0;
4063 eHalStatus status = eHAL_STATUS_SUCCESS;
4064
4065 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4066 if (eHAL_STATUS_SUCCESS != status)
4067 {
4068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4069 "%s: Failed to parse cckm ie data", __func__);
4070 ret = -EINVAL;
4071 goto exit;
4072 }
4073
4074 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4075 {
4076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4077 "%s: CCKM Ie input length is more than max[%d]", __func__,
4078 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004079 vos_mem_free(cckmIe);
4080 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004081 ret = -EINVAL;
4082 goto exit;
4083 }
4084 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004085 vos_mem_free(cckmIe);
4086 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004087 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004088 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4089 {
4090 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004091 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004092 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004093
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004094 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004095 if (eHAL_STATUS_SUCCESS != status)
4096 {
4097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004098 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004099 ret = -EINVAL;
4100 goto exit;
4101 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004102 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4103 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4104 hdd_indicateEseBcnReportNoResults (pAdapter,
4105 eseBcnReq.bcnReq[0].measurementToken,
4106 0x02, //BIT(1) set for measurement done
4107 0); // no BSS
4108 goto exit;
4109 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004110
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004111 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4112 if (eHAL_STATUS_SUCCESS != status)
4113 {
4114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4115 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4116 ret = -EINVAL;
4117 goto exit;
4118 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004119 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004120#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304121 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4122 {
4123 eHalStatus status;
4124 char buf[32], len;
4125 long waitRet;
4126 bcnMissRateContext_t getBcnMissRateCtx;
4127
4128 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4129
4130 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4131 {
4132 hddLog(VOS_TRACE_LEVEL_WARN,
4133 FL("GETBCNMISSRATE: STA is not in connected state"));
4134 ret = -1;
4135 goto exit;
4136 }
4137
4138 init_completion(&(getBcnMissRateCtx.completion));
4139 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4140
4141 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4142 pAdapter->sessionId,
4143 (void *)getBcnMissRateCB,
4144 (void *)(&getBcnMissRateCtx));
4145 if( eHAL_STATUS_SUCCESS != status)
4146 {
4147 hddLog(VOS_TRACE_LEVEL_INFO,
4148 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4149 ret = -EINVAL;
4150 goto exit;
4151 }
4152
4153 waitRet = wait_for_completion_interruptible_timeout
4154 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4155 if(waitRet <= 0)
4156 {
4157 hddLog(VOS_TRACE_LEVEL_ERROR,
4158 FL("failed to wait on bcnMissRateComp %d"), ret);
4159
4160 //Make magic number to zero so that callback is not called.
4161 spin_lock(&hdd_context_lock);
4162 getBcnMissRateCtx.magic = 0x0;
4163 spin_unlock(&hdd_context_lock);
4164 ret = -EINVAL;
4165 goto exit;
4166 }
4167
4168 hddLog(VOS_TRACE_LEVEL_INFO,
4169 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4170
4171 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4172 if (copy_to_user(priv_data.buf, &buf, len + 1))
4173 {
4174 hddLog(VOS_TRACE_LEVEL_ERROR,
4175 "%s: failed to copy data to user buffer", __func__);
4176 ret = -EFAULT;
4177 goto exit;
4178 }
4179 ret = len;
4180 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304181#ifdef FEATURE_WLAN_TDLS
4182 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4183 tANI_U8 *value = command;
4184 int set_value;
4185 /* Move pointer to ahead of TDLSOFFCH*/
4186 value += 26;
4187 sscanf(value, "%d", &set_value);
4188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4189 "%s: Tdls offchannel offset:%d",
4190 __func__, set_value);
4191 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4192 if (ret < 0)
4193 {
4194 ret = -EINVAL;
4195 goto exit;
4196 }
4197
4198 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4199 tANI_U8 *value = command;
4200 int set_value;
4201 /* Move pointer to ahead of tdlsoffchnmode*/
4202 value += 18;
4203 sscanf(value, "%d", &set_value);
4204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4205 "%s: Tdls offchannel mode:%d",
4206 __func__, set_value);
4207 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4208 if (ret < 0)
4209 {
4210 ret = -EINVAL;
4211 goto exit;
4212 }
4213 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4214 tANI_U8 *value = command;
4215 int set_value;
4216 /* Move pointer to ahead of TDLSOFFCH*/
4217 value += 14;
4218 sscanf(value, "%d", &set_value);
4219 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4220 "%s: Tdls offchannel num: %d",
4221 __func__, set_value);
4222 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4223 if (ret < 0)
4224 {
4225 ret = -EINVAL;
4226 goto exit;
4227 }
4228 }
4229#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304230 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4231 {
4232 eHalStatus status;
4233 char *buf = NULL;
4234 char len;
4235 long waitRet;
4236 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304237 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304238 tANI_U8 *ptr = command;
4239 int stats = *(ptr + 11) - '0';
4240
4241 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4242 if (!IS_FEATURE_FW_STATS_ENABLE)
4243 {
4244 hddLog(VOS_TRACE_LEVEL_INFO,
4245 FL("Get Firmware stats feature not supported"));
4246 ret = -EINVAL;
4247 goto exit;
4248 }
4249
4250 if (FW_STATS_MAX <= stats || 0 >= stats)
4251 {
4252 hddLog(VOS_TRACE_LEVEL_INFO,
4253 FL(" stats %d not supported"),stats);
4254 ret = -EINVAL;
4255 goto exit;
4256 }
4257
4258 init_completion(&(fwStatsCtx.completion));
4259 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4260 fwStatsCtx.pAdapter = pAdapter;
4261 fwStatsRsp->type = 0;
4262 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304263 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304264 if (eHAL_STATUS_SUCCESS != status)
4265 {
4266 hddLog(VOS_TRACE_LEVEL_ERROR,
4267 FL(" fail to post WDA cmd status = %d"), status);
4268 ret = -EINVAL;
4269 goto exit;
4270 }
4271 waitRet = wait_for_completion_timeout
4272 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4273 if (waitRet <= 0)
4274 {
4275 hddLog(VOS_TRACE_LEVEL_ERROR,
4276 FL("failed to wait on GwtFwstats"));
4277 //Make magic number to zero so that callback is not executed.
4278 spin_lock(&hdd_context_lock);
4279 fwStatsCtx.magic = 0x0;
4280 spin_unlock(&hdd_context_lock);
4281 ret = -EINVAL;
4282 goto exit;
4283 }
4284 if (fwStatsRsp->type)
4285 {
4286 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4287 if (!buf)
4288 {
4289 hddLog(VOS_TRACE_LEVEL_ERROR,
4290 FL(" failed to allocate memory"));
4291 ret = -ENOMEM;
4292 goto exit;
4293 }
4294 switch( fwStatsRsp->type )
4295 {
4296 case FW_UBSP_STATS:
4297 {
4298 len = snprintf(buf, FW_STATE_RSP_LEN,
4299 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304300 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4301 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304302 }
4303 break;
4304 default:
4305 {
4306 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4307 ret = -EFAULT;
4308 kfree(buf);
4309 goto exit;
4310 }
4311 }
4312 if (copy_to_user(priv_data.buf, buf, len + 1))
4313 {
4314 hddLog(VOS_TRACE_LEVEL_ERROR,
4315 FL(" failed to copy data to user buffer"));
4316 ret = -EFAULT;
4317 kfree(buf);
4318 goto exit;
4319 }
4320 ret = len;
4321 kfree(buf);
4322 }
4323 else
4324 {
4325 hddLog(VOS_TRACE_LEVEL_ERROR,
4326 FL("failed to fetch the stats"));
4327 ret = -EFAULT;
4328 goto exit;
4329 }
4330
4331 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004332 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304333 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4334 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4335 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304336 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4337 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004338 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004339 }
4340exit:
4341 if (command)
4342 {
4343 kfree(command);
4344 }
4345 return ret;
4346}
4347
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004348#ifdef CONFIG_COMPAT
4349static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4350{
4351 struct {
4352 compat_uptr_t buf;
4353 int used_len;
4354 int total_len;
4355 } compat_priv_data;
4356 hdd_priv_data_t priv_data;
4357 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004358
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004359 /*
4360 * Note that pAdapter and ifr have already been verified by caller,
4361 * and HDD context has also been validated
4362 */
4363 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4364 sizeof(compat_priv_data))) {
4365 ret = -EFAULT;
4366 goto exit;
4367 }
4368 priv_data.buf = compat_ptr(compat_priv_data.buf);
4369 priv_data.used_len = compat_priv_data.used_len;
4370 priv_data.total_len = compat_priv_data.total_len;
4371 ret = hdd_driver_command(pAdapter, &priv_data);
4372 exit:
4373 return ret;
4374}
4375#else /* CONFIG_COMPAT */
4376static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4377{
4378 /* will never be invoked */
4379 return 0;
4380}
4381#endif /* CONFIG_COMPAT */
4382
4383static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4384{
4385 hdd_priv_data_t priv_data;
4386 int ret = 0;
4387
4388 /*
4389 * Note that pAdapter and ifr have already been verified by caller,
4390 * and HDD context has also been validated
4391 */
4392 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4393 ret = -EFAULT;
4394 } else {
4395 ret = hdd_driver_command(pAdapter, &priv_data);
4396 }
4397 return ret;
4398}
4399
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304400int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004401{
4402 hdd_adapter_t *pAdapter;
4403 hdd_context_t *pHddCtx;
4404 int ret;
4405
4406 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4407 if (NULL == pAdapter) {
4408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4409 "%s: HDD adapter context is Null", __func__);
4410 ret = -ENODEV;
4411 goto exit;
4412 }
4413 if (dev != pAdapter->dev) {
4414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4415 "%s: HDD adapter/dev inconsistency", __func__);
4416 ret = -ENODEV;
4417 goto exit;
4418 }
4419
4420 if ((!ifr) || (!ifr->ifr_data)) {
4421 ret = -EINVAL;
4422 goto exit;
4423 }
4424
4425 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4426 ret = wlan_hdd_validate_context(pHddCtx);
4427 if (ret) {
Mahesh A Saptasagar5b16d0a2014-11-03 17:55:29 +05304428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004429 "%s: invalid context", __func__);
4430 ret = -EBUSY;
4431 goto exit;
4432 }
4433
4434 switch (cmd) {
4435 case (SIOCDEVPRIVATE + 1):
4436 if (is_compat_task())
4437 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4438 else
4439 ret = hdd_driver_ioctl(pAdapter, ifr);
4440 break;
4441 default:
4442 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4443 __func__, cmd);
4444 ret = -EINVAL;
4445 break;
4446 }
4447 exit:
4448 return ret;
4449}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004450
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304451int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4452{
4453 int ret;
4454
4455 vos_ssr_protect(__func__);
4456 ret = __hdd_ioctl(dev, ifr, cmd);
4457 vos_ssr_unprotect(__func__);
4458
4459 return ret;
4460}
4461
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004462#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004463/**---------------------------------------------------------------------------
4464
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004465 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004466
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004467 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004468 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4469 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4470 <space>Scan Mode N<space>Meas Duration N
4471 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4472 then take N.
4473 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4474 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4475 This function does not take care of removing duplicate channels from the list
4476
4477 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004478 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004479
4480 \return - 0 for success non-zero for failure
4481
4482 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004483static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4484 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004485{
4486 tANI_U8 *inPtr = pValue;
4487 int tempInt = 0;
4488 int j = 0, i = 0, v = 0;
4489 char buf[32];
4490
4491 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4492 /*no argument after the command*/
4493 if (NULL == inPtr)
4494 {
4495 return -EINVAL;
4496 }
4497 /*no space after the command*/
4498 else if (SPACE_ASCII_VALUE != *inPtr)
4499 {
4500 return -EINVAL;
4501 }
4502
4503 /*removing empty spaces*/
4504 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4505
4506 /*no argument followed by spaces*/
4507 if ('\0' == *inPtr) return -EINVAL;
4508
4509 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004510 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004511 if (1 != v) return -EINVAL;
4512
4513 v = kstrtos32(buf, 10, &tempInt);
4514 if ( v < 0) return -EINVAL;
4515
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004516 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004517
4518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004519 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004520
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004521 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004522 {
4523 for (i = 0; i < 4; i++)
4524 {
4525 /*inPtr pointing to the beginning of first space after number of ie fields*/
4526 inPtr = strpbrk( inPtr, " " );
4527 /*no ie data after the number of ie fields argument*/
4528 if (NULL == inPtr) return -EINVAL;
4529
4530 /*removing empty space*/
4531 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4532
4533 /*no ie data after the number of ie fields argument and spaces*/
4534 if ( '\0' == *inPtr ) return -EINVAL;
4535
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004536 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004537 if (1 != v) return -EINVAL;
4538
4539 v = kstrtos32(buf, 10, &tempInt);
4540 if (v < 0) return -EINVAL;
4541
4542 switch (i)
4543 {
4544 case 0: /* Measurement token */
4545 if (tempInt <= 0)
4546 {
4547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4548 "Invalid Measurement Token(%d)", tempInt);
4549 return -EINVAL;
4550 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004551 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004552 break;
4553
4554 case 1: /* Channel number */
4555 if ((tempInt <= 0) ||
4556 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4557 {
4558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4559 "Invalid Channel Number(%d)", tempInt);
4560 return -EINVAL;
4561 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004562 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004563 break;
4564
4565 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004566 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004567 {
4568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4569 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4570 return -EINVAL;
4571 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004572 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004573 break;
4574
4575 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004576 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4577 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004578 {
4579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4580 "Invalid Measurement Duration(%d)", tempInt);
4581 return -EINVAL;
4582 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004583 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004584 break;
4585 }
4586 }
4587 }
4588
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004589 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004590 {
4591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304592 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004593 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004594 pEseBcnReq->bcnReq[j].measurementToken,
4595 pEseBcnReq->bcnReq[j].channel,
4596 pEseBcnReq->bcnReq[j].scanMode,
4597 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004598 }
4599
4600 return VOS_STATUS_SUCCESS;
4601}
4602
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004603static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4604{
4605 struct statsContext *pStatsContext = NULL;
4606 hdd_adapter_t *pAdapter = NULL;
4607
4608 if (NULL == pContext)
4609 {
4610 hddLog(VOS_TRACE_LEVEL_ERROR,
4611 "%s: Bad param, pContext [%p]",
4612 __func__, pContext);
4613 return;
4614 }
4615
Jeff Johnson72a40512013-12-19 10:14:15 -08004616 /* there is a race condition that exists between this callback
4617 function and the caller since the caller could time out either
4618 before or while this code is executing. we use a spinlock to
4619 serialize these actions */
4620 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004621
4622 pStatsContext = pContext;
4623 pAdapter = pStatsContext->pAdapter;
4624 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4625 {
4626 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004627 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004628 hddLog(VOS_TRACE_LEVEL_WARN,
4629 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4630 __func__, pAdapter, pStatsContext->magic);
4631 return;
4632 }
4633
Jeff Johnson72a40512013-12-19 10:14:15 -08004634 /* context is valid so caller is still waiting */
4635
4636 /* paranoia: invalidate the magic */
4637 pStatsContext->magic = 0;
4638
4639 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004640 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4641 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4642 tsmMetrics.UplinkPktQueueDlyHist,
4643 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4644 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4645 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4646 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4647 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4648 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4649 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4650
Jeff Johnson72a40512013-12-19 10:14:15 -08004651 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004652 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004653
4654 /* serialization is complete */
4655 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004656}
4657
4658
4659
4660static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4661 tAniTrafStrmMetrics* pTsmMetrics)
4662{
4663 hdd_station_ctx_t *pHddStaCtx = NULL;
4664 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004665 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004666 long lrc;
4667 struct statsContext context;
4668 hdd_context_t *pHddCtx = NULL;
4669
4670 if (NULL == pAdapter)
4671 {
4672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4673 return VOS_STATUS_E_FAULT;
4674 }
4675
4676 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4677 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4678
4679 /* we are connected prepare our callback context */
4680 init_completion(&context.completion);
4681 context.pAdapter = pAdapter;
4682 context.magic = STATS_CONTEXT_MAGIC;
4683
4684 /* query tsm stats */
4685 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4686 pHddStaCtx->conn_info.staId[ 0 ],
4687 pHddStaCtx->conn_info.bssId,
4688 &context, pHddCtx->pvosContext, tid);
4689
4690 if (eHAL_STATUS_SUCCESS != hstatus)
4691 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4693 __func__);
4694 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004695 }
4696 else
4697 {
4698 /* request was sent -- wait for the response */
4699 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4700 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004701 if (lrc <= 0)
4702 {
4703 hddLog(VOS_TRACE_LEVEL_ERROR,
4704 "%s: SME %s while retrieving statistics",
4705 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004706 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004707 }
4708 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004709
Jeff Johnson72a40512013-12-19 10:14:15 -08004710 /* either we never sent a request, we sent a request and received a
4711 response or we sent a request and timed out. if we never sent a
4712 request or if we sent a request and got a response, we want to
4713 clear the magic out of paranoia. if we timed out there is a
4714 race condition such that the callback function could be
4715 executing at the same time we are. of primary concern is if the
4716 callback function had already verified the "magic" but had not
4717 yet set the completion variable when a timeout occurred. we
4718 serialize these activities by invalidating the magic while
4719 holding a shared spinlock which will cause us to block if the
4720 callback is currently executing */
4721 spin_lock(&hdd_context_lock);
4722 context.magic = 0;
4723 spin_unlock(&hdd_context_lock);
4724
4725 if (VOS_STATUS_SUCCESS == vstatus)
4726 {
4727 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4728 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4729 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4730 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4731 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4732 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4733 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4734 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4735 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4736 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4737 }
4738 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004739}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004740#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004741
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004742#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004743void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4744{
4745 eCsrBand band = -1;
4746 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4747 switch (band)
4748 {
4749 case eCSR_BAND_ALL:
4750 *pBand = WLAN_HDD_UI_BAND_AUTO;
4751 break;
4752
4753 case eCSR_BAND_24:
4754 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4755 break;
4756
4757 case eCSR_BAND_5G:
4758 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4759 break;
4760
4761 default:
4762 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4763 *pBand = -1;
4764 break;
4765 }
4766}
4767
4768/**---------------------------------------------------------------------------
4769
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004770 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4771
4772 This function parses the send action frame data passed in the format
4773 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4774
Srinivas Girigowda56076852013-08-20 14:00:50 -07004775 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004776 \param - pTargetApBssid Pointer to target Ap bssid
4777 \param - pChannel Pointer to the Target AP channel
4778 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4779 \param - pBuf Pointer to data
4780 \param - pBufLen Pointer to data length
4781
4782 \return - 0 for success non-zero for failure
4783
4784 --------------------------------------------------------------------------*/
4785VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4786 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4787{
4788 tANI_U8 *inPtr = pValue;
4789 tANI_U8 *dataEnd;
4790 int tempInt;
4791 int j = 0;
4792 int i = 0;
4793 int v = 0;
4794 tANI_U8 tempBuf[32];
4795 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004796 /* 12 hexa decimal digits, 5 ':' and '\0' */
4797 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004798
4799 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4800 /*no argument after the command*/
4801 if (NULL == inPtr)
4802 {
4803 return -EINVAL;
4804 }
4805
4806 /*no space after the command*/
4807 else if (SPACE_ASCII_VALUE != *inPtr)
4808 {
4809 return -EINVAL;
4810 }
4811
4812 /*removing empty spaces*/
4813 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4814
4815 /*no argument followed by spaces*/
4816 if ('\0' == *inPtr)
4817 {
4818 return -EINVAL;
4819 }
4820
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004821 v = sscanf(inPtr, "%17s", macAddress);
4822 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004823 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004824 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4825 "Invalid MAC address or All hex inputs are not read (%d)", v);
4826 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004827 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004828
4829 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4830 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4831 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4832 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4833 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4834 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004835
4836 /* point to the next argument */
4837 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4838 /*no argument after the command*/
4839 if (NULL == inPtr) return -EINVAL;
4840
4841 /*removing empty spaces*/
4842 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4843
4844 /*no argument followed by spaces*/
4845 if ('\0' == *inPtr)
4846 {
4847 return -EINVAL;
4848 }
4849
4850 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004851 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004852 if (1 != v) return -EINVAL;
4853
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004854 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304855 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304856 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004857
4858 *pChannel = tempInt;
4859
4860 /* point to the next argument */
4861 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4862 /*no argument after the command*/
4863 if (NULL == inPtr) return -EINVAL;
4864 /*removing empty spaces*/
4865 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4866
4867 /*no argument followed by spaces*/
4868 if ('\0' == *inPtr)
4869 {
4870 return -EINVAL;
4871 }
4872
4873 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004874 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004875 if (1 != v) return -EINVAL;
4876
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004877 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004878 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004879
4880 *pDwellTime = tempInt;
4881
4882 /* point to the next argument */
4883 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4884 /*no argument after the command*/
4885 if (NULL == inPtr) return -EINVAL;
4886 /*removing empty spaces*/
4887 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4888
4889 /*no argument followed by spaces*/
4890 if ('\0' == *inPtr)
4891 {
4892 return -EINVAL;
4893 }
4894
4895 /* find the length of data */
4896 dataEnd = inPtr;
4897 while(('\0' != *dataEnd) )
4898 {
4899 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004900 }
Kiet Lambe150c22013-11-21 16:30:32 +05304901 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004902 if ( *pBufLen <= 0) return -EINVAL;
4903
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004904 /* Allocate the number of bytes based on the number of input characters
4905 whether it is even or odd.
4906 if the number of input characters are even, then we need N/2 byte.
4907 if the number of input characters are odd, then we need do (N+1)/2 to
4908 compensate rounding off.
4909 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4910 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4911 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004912 if (NULL == *pBuf)
4913 {
4914 hddLog(VOS_TRACE_LEVEL_FATAL,
4915 "%s: vos_mem_alloc failed ", __func__);
4916 return -EINVAL;
4917 }
4918
4919 /* the buffer received from the upper layer is character buffer,
4920 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4921 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4922 and f0 in 3rd location */
4923 for (i = 0, j = 0; j < *pBufLen; j += 2)
4924 {
Kiet Lambe150c22013-11-21 16:30:32 +05304925 if( j+1 == *pBufLen)
4926 {
4927 tempByte = hdd_parse_hex(inPtr[j]);
4928 }
4929 else
4930 {
4931 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4932 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004933 (*pBuf)[i++] = tempByte;
4934 }
4935 *pBufLen = i;
4936 return VOS_STATUS_SUCCESS;
4937}
4938
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004939/**---------------------------------------------------------------------------
4940
Srinivas Girigowdade697412013-02-14 16:31:48 -08004941 \brief hdd_parse_channellist() - HDD Parse channel list
4942
4943 This function parses the channel list passed in the format
4944 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004945 if the Number of channels (N) does not match with the actual number of channels passed
4946 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4947 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4948 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4949 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004950
4951 \param - pValue Pointer to input channel list
4952 \param - ChannelList Pointer to local output array to record channel list
4953 \param - pNumChannels Pointer to number of roam scan channels
4954
4955 \return - 0 for success non-zero for failure
4956
4957 --------------------------------------------------------------------------*/
4958VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4959{
4960 tANI_U8 *inPtr = pValue;
4961 int tempInt;
4962 int j = 0;
4963 int v = 0;
4964 char buf[32];
4965
4966 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4967 /*no argument after the command*/
4968 if (NULL == inPtr)
4969 {
4970 return -EINVAL;
4971 }
4972
4973 /*no space after the command*/
4974 else if (SPACE_ASCII_VALUE != *inPtr)
4975 {
4976 return -EINVAL;
4977 }
4978
4979 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004980 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004981
4982 /*no argument followed by spaces*/
4983 if ('\0' == *inPtr)
4984 {
4985 return -EINVAL;
4986 }
4987
4988 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004989 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004990 if (1 != v) return -EINVAL;
4991
Srinivas Girigowdade697412013-02-14 16:31:48 -08004992 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004993 if ((v < 0) ||
4994 (tempInt <= 0) ||
4995 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4996 {
4997 return -EINVAL;
4998 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004999
5000 *pNumChannels = tempInt;
5001
5002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5003 "Number of channels are: %d", *pNumChannels);
5004
5005 for (j = 0; j < (*pNumChannels); j++)
5006 {
5007 /*inPtr pointing to the beginning of first space after number of channels*/
5008 inPtr = strpbrk( inPtr, " " );
5009 /*no channel list after the number of channels argument*/
5010 if (NULL == inPtr)
5011 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005012 if (0 != j)
5013 {
5014 *pNumChannels = j;
5015 return VOS_STATUS_SUCCESS;
5016 }
5017 else
5018 {
5019 return -EINVAL;
5020 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005021 }
5022
5023 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005024 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005025
5026 /*no channel list after the number of channels argument and spaces*/
5027 if ( '\0' == *inPtr )
5028 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005029 if (0 != j)
5030 {
5031 *pNumChannels = j;
5032 return VOS_STATUS_SUCCESS;
5033 }
5034 else
5035 {
5036 return -EINVAL;
5037 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005038 }
5039
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005040 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005041 if (1 != v) return -EINVAL;
5042
Srinivas Girigowdade697412013-02-14 16:31:48 -08005043 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005044 if ((v < 0) ||
5045 (tempInt <= 0) ||
5046 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5047 {
5048 return -EINVAL;
5049 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005050 pChannelList[j] = tempInt;
5051
5052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5053 "Channel %d added to preferred channel list",
5054 pChannelList[j] );
5055 }
5056
Srinivas Girigowdade697412013-02-14 16:31:48 -08005057 return VOS_STATUS_SUCCESS;
5058}
5059
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005060
5061/**---------------------------------------------------------------------------
5062
5063 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5064
5065 This function parses the reasoc command data passed in the format
5066 REASSOC<space><bssid><space><channel>
5067
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005068 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005069 \param - pTargetApBssid Pointer to target Ap bssid
5070 \param - pChannel Pointer to the Target AP channel
5071
5072 \return - 0 for success non-zero for failure
5073
5074 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005075VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5076 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005077{
5078 tANI_U8 *inPtr = pValue;
5079 int tempInt;
5080 int v = 0;
5081 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005082 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005083 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005084
5085 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5086 /*no argument after the command*/
5087 if (NULL == inPtr)
5088 {
5089 return -EINVAL;
5090 }
5091
5092 /*no space after the command*/
5093 else if (SPACE_ASCII_VALUE != *inPtr)
5094 {
5095 return -EINVAL;
5096 }
5097
5098 /*removing empty spaces*/
5099 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5100
5101 /*no argument followed by spaces*/
5102 if ('\0' == *inPtr)
5103 {
5104 return -EINVAL;
5105 }
5106
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005107 v = sscanf(inPtr, "%17s", macAddress);
5108 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005109 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5111 "Invalid MAC address or All hex inputs are not read (%d)", v);
5112 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005113 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005114
5115 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5116 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5117 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5118 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5119 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5120 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005121
5122 /* point to the next argument */
5123 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5124 /*no argument after the command*/
5125 if (NULL == inPtr) return -EINVAL;
5126
5127 /*removing empty spaces*/
5128 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5129
5130 /*no argument followed by spaces*/
5131 if ('\0' == *inPtr)
5132 {
5133 return -EINVAL;
5134 }
5135
5136 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005137 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005138 if (1 != v) return -EINVAL;
5139
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005140 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005141 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305142 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005143 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5144 {
5145 return -EINVAL;
5146 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005147
5148 *pChannel = tempInt;
5149 return VOS_STATUS_SUCCESS;
5150}
5151
5152#endif
5153
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005154#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005155/**---------------------------------------------------------------------------
5156
5157 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5158
5159 This function parses the SETCCKM IE command
5160 SETCCKMIE<space><ie data>
5161
5162 \param - pValue Pointer to input data
5163 \param - pCckmIe Pointer to output cckm Ie
5164 \param - pCckmIeLen Pointer to output cckm ie length
5165
5166 \return - 0 for success non-zero for failure
5167
5168 --------------------------------------------------------------------------*/
5169VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5170 tANI_U8 *pCckmIeLen)
5171{
5172 tANI_U8 *inPtr = pValue;
5173 tANI_U8 *dataEnd;
5174 int j = 0;
5175 int i = 0;
5176 tANI_U8 tempByte = 0;
5177
5178 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5179 /*no argument after the command*/
5180 if (NULL == inPtr)
5181 {
5182 return -EINVAL;
5183 }
5184
5185 /*no space after the command*/
5186 else if (SPACE_ASCII_VALUE != *inPtr)
5187 {
5188 return -EINVAL;
5189 }
5190
5191 /*removing empty spaces*/
5192 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5193
5194 /*no argument followed by spaces*/
5195 if ('\0' == *inPtr)
5196 {
5197 return -EINVAL;
5198 }
5199
5200 /* find the length of data */
5201 dataEnd = inPtr;
5202 while(('\0' != *dataEnd) )
5203 {
5204 dataEnd++;
5205 ++(*pCckmIeLen);
5206 }
5207 if ( *pCckmIeLen <= 0) return -EINVAL;
5208
5209 /* Allocate the number of bytes based on the number of input characters
5210 whether it is even or odd.
5211 if the number of input characters are even, then we need N/2 byte.
5212 if the number of input characters are odd, then we need do (N+1)/2 to
5213 compensate rounding off.
5214 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5215 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5216 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5217 if (NULL == *pCckmIe)
5218 {
5219 hddLog(VOS_TRACE_LEVEL_FATAL,
5220 "%s: vos_mem_alloc failed ", __func__);
5221 return -EINVAL;
5222 }
5223 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5224 /* the buffer received from the upper layer is character buffer,
5225 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5226 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5227 and f0 in 3rd location */
5228 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5229 {
5230 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5231 (*pCckmIe)[i++] = tempByte;
5232 }
5233 *pCckmIeLen = i;
5234
5235 return VOS_STATUS_SUCCESS;
5236}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005237#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005238
Jeff Johnson295189b2012-06-20 16:38:30 -07005239/**---------------------------------------------------------------------------
5240
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005241 \brief hdd_is_valid_mac_address() - Validate MAC address
5242
5243 This function validates whether the given MAC address is valid or not
5244 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5245 where X is the hexa decimal digit character and separated by ':'
5246 This algorithm works even if MAC address is not separated by ':'
5247
5248 This code checks given input string mac contains exactly 12 hexadecimal digits.
5249 and a separator colon : appears in the input string only after
5250 an even number of hex digits.
5251
5252 \param - pMacAddr pointer to the input MAC address
5253 \return - 1 for valid and 0 for invalid
5254
5255 --------------------------------------------------------------------------*/
5256
5257v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5258{
5259 int xdigit = 0;
5260 int separator = 0;
5261 while (*pMacAddr)
5262 {
5263 if (isxdigit(*pMacAddr))
5264 {
5265 xdigit++;
5266 }
5267 else if (':' == *pMacAddr)
5268 {
5269 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5270 break;
5271
5272 ++separator;
5273 }
5274 else
5275 {
5276 separator = -1;
5277 /* Invalid MAC found */
5278 return 0;
5279 }
5280 ++pMacAddr;
5281 }
5282 return (xdigit == 12 && (separator == 5 || separator == 0));
5283}
5284
5285/**---------------------------------------------------------------------------
5286
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305287 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005288
5289 \param - dev Pointer to net_device structure
5290
5291 \return - 0 for success non-zero for failure
5292
5293 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305294int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005295{
5296 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5297 hdd_context_t *pHddCtx;
5298 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5299 VOS_STATUS status;
5300 v_BOOL_t in_standby = TRUE;
5301
5302 if (NULL == pAdapter)
5303 {
5304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305305 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005306 return -ENODEV;
5307 }
5308
5309 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305310 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5311 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005312 if (NULL == pHddCtx)
5313 {
5314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005315 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005316 return -ENODEV;
5317 }
5318
5319 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5320 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5321 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005322 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5323 {
5324 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305325 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005326 in_standby = FALSE;
5327 break;
5328 }
5329 else
5330 {
5331 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5332 pAdapterNode = pNext;
5333 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005334 }
5335
5336 if (TRUE == in_standby)
5337 {
5338 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5339 {
5340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5341 "wlan out of power save", __func__);
5342 return -EINVAL;
5343 }
5344 }
5345
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005346 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005347 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5348 {
5349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005350 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005351 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305352 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005353 netif_tx_start_all_queues(dev);
5354 }
5355
5356 return 0;
5357}
5358
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305359/**---------------------------------------------------------------------------
5360
5361 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5362
5363 This is called in response to ifconfig up
5364
5365 \param - dev Pointer to net_device structure
5366
5367 \return - 0 for success non-zero for failure
5368
5369 --------------------------------------------------------------------------*/
5370int hdd_open(struct net_device *dev)
5371{
5372 int ret;
5373
5374 vos_ssr_protect(__func__);
5375 ret = __hdd_open(dev);
5376 vos_ssr_unprotect(__func__);
5377
5378 return ret;
5379}
5380
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305381int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005382{
5383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5384
5385 if(pAdapter == NULL) {
5386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005387 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005388 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005389 }
5390
5391 netif_start_queue(dev);
5392
5393 return 0;
5394}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305395
5396int hdd_mon_open (struct net_device *dev)
5397{
5398 int ret;
5399
5400 vos_ssr_protect(__func__);
5401 ret = __hdd_mon_open(dev);
5402 vos_ssr_unprotect(__func__);
5403
5404 return ret;
5405}
5406
Jeff Johnson295189b2012-06-20 16:38:30 -07005407/**---------------------------------------------------------------------------
5408
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305409 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005410
5411 \param - dev Pointer to net_device structure
5412
5413 \return - 0 for success non-zero for failure
5414
5415 --------------------------------------------------------------------------*/
5416
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305417int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005418{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305419 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005420 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5421 hdd_context_t *pHddCtx;
5422 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5423 VOS_STATUS status;
5424 v_BOOL_t enter_standby = TRUE;
5425
5426 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005427 if (NULL == pAdapter)
5428 {
5429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305430 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 return -ENODEV;
5432 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305433 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305434 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305435
5436 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5437 ret = wlan_hdd_validate_context(pHddCtx);
5438 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5441 "%s: HDD context is not valid!", __func__);
5442 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005443 }
5444
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305445 /* Nothing to be done if the interface is not opened */
5446 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5447 {
5448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5449 "%s: NETDEV Interface is not OPENED", __func__);
5450 return -ENODEV;
5451 }
5452
5453 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005454 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305456
5457 /* Disable TX on the interface, after this hard_start_xmit() will not
5458 * be called on that interface
5459 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305460 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305462
5463 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005464 netif_carrier_off(pAdapter->dev);
5465
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305466 /* The interface is marked as down for outside world (aka kernel)
5467 * But the driver is pretty much alive inside. The driver needs to
5468 * tear down the existing connection on the netdev (session)
5469 * cleanup the data pipes and wait until the control plane is stabilized
5470 * for this interface. The call also needs to wait until the above
5471 * mentioned actions are completed before returning to the caller.
5472 * Notice that the hdd_stop_adapter is requested not to close the session
5473 * That is intentional to be able to scan if it is a STA/P2P interface
5474 */
5475 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305476#ifdef FEATURE_WLAN_TDLS
5477 mutex_lock(&pHddCtx->tdls_lock);
5478#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305479 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305480 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305481#ifdef FEATURE_WLAN_TDLS
5482 mutex_unlock(&pHddCtx->tdls_lock);
5483#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005484 /* SoftAP ifaces should never go in power save mode
5485 making sure same here. */
5486 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5487 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005489 )
5490 {
5491 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5493 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 EXIT();
5495 return 0;
5496 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305497 /* Find if any iface is up. If any iface is up then can't put device to
5498 * sleep/power save mode
5499 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5501 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5502 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005503 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5504 {
5505 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305506 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005507 enter_standby = FALSE;
5508 break;
5509 }
5510 else
5511 {
5512 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5513 pAdapterNode = pNext;
5514 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005515 }
5516
5517 if (TRUE == enter_standby)
5518 {
5519 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5520 "entering standby", __func__);
5521 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5522 {
5523 /*log and return success*/
5524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5525 "wlan in power save", __func__);
5526 }
5527 }
5528
5529 EXIT();
5530 return 0;
5531}
5532
5533/**---------------------------------------------------------------------------
5534
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305535 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005536
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305537 This is called in response to ifconfig down
5538
5539 \param - dev Pointer to net_device structure
5540
5541 \return - 0 for success non-zero for failure
5542-----------------------------------------------------------------------------*/
5543int hdd_stop (struct net_device *dev)
5544{
5545 int ret;
5546
5547 vos_ssr_protect(__func__);
5548 ret = __hdd_stop(dev);
5549 vos_ssr_unprotect(__func__);
5550
5551 return ret;
5552}
5553
5554/**---------------------------------------------------------------------------
5555
5556 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005557
5558 \param - dev Pointer to net_device structure
5559
5560 \return - void
5561
5562 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305563static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005564{
5565 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305566 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 ENTER();
5568
5569 do
5570 {
5571 if (NULL == pAdapter)
5572 {
5573 hddLog(VOS_TRACE_LEVEL_FATAL,
5574 "%s: NULL pAdapter", __func__);
5575 break;
5576 }
5577
5578 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5579 {
5580 hddLog(VOS_TRACE_LEVEL_FATAL,
5581 "%s: Invalid magic", __func__);
5582 break;
5583 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305584 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5585 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 {
5587 hddLog(VOS_TRACE_LEVEL_FATAL,
5588 "%s: NULL pHddCtx", __func__);
5589 break;
5590 }
5591
5592 if (dev != pAdapter->dev)
5593 {
5594 hddLog(VOS_TRACE_LEVEL_FATAL,
5595 "%s: Invalid device reference", __func__);
5596 /* we haven't validated all cases so let this go for now */
5597 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305598#ifdef FEATURE_WLAN_TDLS
5599 mutex_lock(&pHddCtx->tdls_lock);
5600#endif
c_hpothu002231a2015-02-05 14:58:51 +05305601 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305602#ifdef FEATURE_WLAN_TDLS
5603 mutex_unlock(&pHddCtx->tdls_lock);
5604#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005605
5606 /* after uninit our adapter structure will no longer be valid */
5607 pAdapter->dev = NULL;
5608 pAdapter->magic = 0;
5609 } while (0);
5610
5611 EXIT();
5612}
5613
5614/**---------------------------------------------------------------------------
5615
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305616 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5617
5618 This is called during the netdev unregister to uninitialize all data
5619associated with the device
5620
5621 \param - dev Pointer to net_device structure
5622
5623 \return - void
5624
5625 --------------------------------------------------------------------------*/
5626static void hdd_uninit (struct net_device *dev)
5627{
5628 vos_ssr_protect(__func__);
5629 __hdd_uninit(dev);
5630 vos_ssr_unprotect(__func__);
5631}
5632
5633/**---------------------------------------------------------------------------
5634
Jeff Johnson295189b2012-06-20 16:38:30 -07005635 \brief hdd_release_firmware() -
5636
5637 This function calls the release firmware API to free the firmware buffer.
5638
5639 \param - pFileName Pointer to the File Name.
5640 pCtx - Pointer to the adapter .
5641
5642
5643 \return - 0 for success, non zero for failure
5644
5645 --------------------------------------------------------------------------*/
5646
5647VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5648{
5649 VOS_STATUS status = VOS_STATUS_SUCCESS;
5650 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5651 ENTER();
5652
5653
5654 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5655
5656 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5657
5658 if(pHddCtx->fw) {
5659 release_firmware(pHddCtx->fw);
5660 pHddCtx->fw = NULL;
5661 }
5662 else
5663 status = VOS_STATUS_E_FAILURE;
5664 }
5665 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5666 if(pHddCtx->nv) {
5667 release_firmware(pHddCtx->nv);
5668 pHddCtx->nv = NULL;
5669 }
5670 else
5671 status = VOS_STATUS_E_FAILURE;
5672
5673 }
5674
5675 EXIT();
5676 return status;
5677}
5678
5679/**---------------------------------------------------------------------------
5680
5681 \brief hdd_request_firmware() -
5682
5683 This function reads the firmware file using the request firmware
5684 API and returns the the firmware data and the firmware file size.
5685
5686 \param - pfileName - Pointer to the file name.
5687 - pCtx - Pointer to the adapter .
5688 - ppfw_data - Pointer to the pointer of the firmware data.
5689 - pSize - Pointer to the file size.
5690
5691 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5692
5693 --------------------------------------------------------------------------*/
5694
5695
5696VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5697{
5698 int status;
5699 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5700 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5701 ENTER();
5702
5703 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5704
5705 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5706
5707 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5708 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5709 __func__, pfileName);
5710 retval = VOS_STATUS_E_FAILURE;
5711 }
5712
5713 else {
5714 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5715 *pSize = pHddCtx->fw->size;
5716 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5717 __func__, *pSize);
5718 }
5719 }
5720 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5721
5722 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5723
5724 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5725 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5726 __func__, pfileName);
5727 retval = VOS_STATUS_E_FAILURE;
5728 }
5729
5730 else {
5731 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5732 *pSize = pHddCtx->nv->size;
5733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5734 __func__, *pSize);
5735 }
5736 }
5737
5738 EXIT();
5739 return retval;
5740}
5741/**---------------------------------------------------------------------------
5742 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5743
5744 This is the function invoked by SME to inform the result of a full power
5745 request issued by HDD
5746
5747 \param - callbackcontext - Pointer to cookie
5748 status - result of request
5749
5750 \return - None
5751
5752--------------------------------------------------------------------------*/
5753void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5754{
5755 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5756
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005757 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005758 if(&pHddCtx->full_pwr_comp_var)
5759 {
5760 complete(&pHddCtx->full_pwr_comp_var);
5761 }
5762}
5763
5764/**---------------------------------------------------------------------------
5765
5766 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5767
5768 This is the function invoked by SME to inform the result of BMPS
5769 request issued by HDD
5770
5771 \param - callbackcontext - Pointer to cookie
5772 status - result of request
5773
5774 \return - None
5775
5776--------------------------------------------------------------------------*/
5777void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5778{
5779
5780 struct completion *completion_var = (struct completion*) callbackContext;
5781
Arif Hussain6d2a3322013-11-17 19:50:10 -08005782 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005783 if(completion_var != NULL)
5784 {
5785 complete(completion_var);
5786 }
5787}
5788
5789/**---------------------------------------------------------------------------
5790
5791 \brief hdd_get_cfg_file_size() -
5792
5793 This function reads the configuration file using the request firmware
5794 API and returns the configuration file size.
5795
5796 \param - pCtx - Pointer to the adapter .
5797 - pFileName - Pointer to the file name.
5798 - pBufSize - Pointer to the buffer size.
5799
5800 \return - 0 for success, non zero for failure
5801
5802 --------------------------------------------------------------------------*/
5803
5804VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5805{
5806 int status;
5807 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5808
5809 ENTER();
5810
5811 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5812
5813 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5814 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5815 status = VOS_STATUS_E_FAILURE;
5816 }
5817 else {
5818 *pBufSize = pHddCtx->fw->size;
5819 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5820 release_firmware(pHddCtx->fw);
5821 pHddCtx->fw = NULL;
5822 }
5823
5824 EXIT();
5825 return VOS_STATUS_SUCCESS;
5826}
5827
5828/**---------------------------------------------------------------------------
5829
5830 \brief hdd_read_cfg_file() -
5831
5832 This function reads the configuration file using the request firmware
5833 API and returns the cfg data and the buffer size of the configuration file.
5834
5835 \param - pCtx - Pointer to the adapter .
5836 - pFileName - Pointer to the file name.
5837 - pBuffer - Pointer to the data buffer.
5838 - pBufSize - Pointer to the buffer size.
5839
5840 \return - 0 for success, non zero for failure
5841
5842 --------------------------------------------------------------------------*/
5843
5844VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5845 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5846{
5847 int status;
5848 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5849
5850 ENTER();
5851
5852 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5853
5854 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5855 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5856 return VOS_STATUS_E_FAILURE;
5857 }
5858 else {
5859 if(*pBufSize != pHddCtx->fw->size) {
5860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5861 "file size", __func__);
5862 release_firmware(pHddCtx->fw);
5863 pHddCtx->fw = NULL;
5864 return VOS_STATUS_E_FAILURE;
5865 }
5866 else {
5867 if(pBuffer) {
5868 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5869 }
5870 release_firmware(pHddCtx->fw);
5871 pHddCtx->fw = NULL;
5872 }
5873 }
5874
5875 EXIT();
5876
5877 return VOS_STATUS_SUCCESS;
5878}
5879
5880/**---------------------------------------------------------------------------
5881
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305882 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005883
5884 This function sets the user specified mac address using
5885 the command ifconfig wlanX hw ether <mac adress>.
5886
5887 \param - dev - Pointer to the net device.
5888 - addr - Pointer to the sockaddr.
5889 \return - 0 for success, non zero for failure
5890
5891 --------------------------------------------------------------------------*/
5892
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305893static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005894{
5895 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5896 struct sockaddr *psta_mac_addr = addr;
5897 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
5898
5899 ENTER();
5900
5901 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5903
5904 EXIT();
5905 return halStatus;
5906}
5907
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305908/**---------------------------------------------------------------------------
5909
5910 \brief hdd_set_mac_address() -
5911
5912 Wrapper function to protect __hdd_set_mac_address() function from ssr
5913
5914 \param - dev - Pointer to the net device.
5915 - addr - Pointer to the sockaddr.
5916 \return - 0 for success, non zero for failure
5917
5918 --------------------------------------------------------------------------*/
5919static int hdd_set_mac_address(struct net_device *dev, void *addr)
5920{
5921 int ret;
5922
5923 vos_ssr_protect(__func__);
5924 ret = __hdd_set_mac_address(dev, addr);
5925 vos_ssr_unprotect(__func__);
5926
5927 return ret;
5928}
5929
Jeff Johnson295189b2012-06-20 16:38:30 -07005930tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5931{
5932 int i;
5933 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5934 {
Abhishek Singheb183782014-02-06 13:37:21 +05305935 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 break;
5937 }
5938
5939 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5940 return NULL;
5941
5942 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5943 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5944}
5945
5946void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5947{
5948 int i;
5949 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5950 {
5951 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5952 {
5953 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5954 break;
5955 }
5956 }
5957 return;
5958}
5959
5960#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5961 static struct net_device_ops wlan_drv_ops = {
5962 .ndo_open = hdd_open,
5963 .ndo_stop = hdd_stop,
5964 .ndo_uninit = hdd_uninit,
5965 .ndo_start_xmit = hdd_hard_start_xmit,
5966 .ndo_tx_timeout = hdd_tx_timeout,
5967 .ndo_get_stats = hdd_stats,
5968 .ndo_do_ioctl = hdd_ioctl,
5969 .ndo_set_mac_address = hdd_set_mac_address,
5970 .ndo_select_queue = hdd_select_queue,
5971#ifdef WLAN_FEATURE_PACKET_FILTERING
5972#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5973 .ndo_set_rx_mode = hdd_set_multicast_list,
5974#else
5975 .ndo_set_multicast_list = hdd_set_multicast_list,
5976#endif //LINUX_VERSION_CODE
5977#endif
5978 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005979 static struct net_device_ops wlan_mon_drv_ops = {
5980 .ndo_open = hdd_mon_open,
5981 .ndo_stop = hdd_stop,
5982 .ndo_uninit = hdd_uninit,
5983 .ndo_start_xmit = hdd_mon_hard_start_xmit,
5984 .ndo_tx_timeout = hdd_tx_timeout,
5985 .ndo_get_stats = hdd_stats,
5986 .ndo_do_ioctl = hdd_ioctl,
5987 .ndo_set_mac_address = hdd_set_mac_address,
5988 };
Mahesh A Saptasagard477b092015-02-06 15:12:16 +05305989 static struct net_device_ops nullify_netdev_ops = {
5990 .ndo_open = NULL,
5991 .ndo_stop = NULL,
5992 .ndo_uninit = NULL,
5993 .ndo_start_xmit = NULL,
5994 .ndo_tx_timeout = NULL,
5995 .ndo_get_stats = NULL,
5996 .ndo_set_mac_address = NULL,
5997 .ndo_do_ioctl = NULL,
5998 .ndo_change_mtu = NULL,
5999 .ndo_select_queue = NULL,
6000 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006001#endif
6002
6003void hdd_set_station_ops( struct net_device *pWlanDev )
6004{
6005#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 pWlanDev->netdev_ops = &wlan_drv_ops;
6007#else
6008 pWlanDev->open = hdd_open;
6009 pWlanDev->stop = hdd_stop;
6010 pWlanDev->uninit = hdd_uninit;
6011 pWlanDev->hard_start_xmit = NULL;
6012 pWlanDev->tx_timeout = hdd_tx_timeout;
6013 pWlanDev->get_stats = hdd_stats;
6014 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 pWlanDev->set_mac_address = hdd_set_mac_address;
6016#endif
6017}
6018
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006019static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006020{
6021 struct net_device *pWlanDev = NULL;
6022 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006023 /*
6024 * cfg80211 initialization and registration....
6025 */
6026 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6027
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 if(pWlanDev != NULL)
6029 {
6030
6031 //Save the pointer to the net_device in the HDD adapter
6032 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6033
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6035
6036 pAdapter->dev = pWlanDev;
6037 pAdapter->pHddCtx = pHddCtx;
6038 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306039 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006040
6041 init_completion(&pAdapter->session_open_comp_var);
6042 init_completion(&pAdapter->session_close_comp_var);
6043 init_completion(&pAdapter->disconnect_comp_var);
6044 init_completion(&pAdapter->linkup_event_var);
6045 init_completion(&pAdapter->cancel_rem_on_chan_var);
6046 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306047 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006048#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6049 init_completion(&pAdapter->offchannel_tx_event);
6050#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006052#ifdef FEATURE_WLAN_TDLS
6053 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006054 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006055 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306056 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006057#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 init_completion(&pHddCtx->mc_sus_event_var);
6059 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306060 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006061 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006062 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006063
Rajeev79dbe4c2013-10-05 11:03:42 +05306064#ifdef FEATURE_WLAN_BATCH_SCAN
6065 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6066 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6067 pAdapter->pBatchScanRsp = NULL;
6068 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006069 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006070 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306071 mutex_init(&pAdapter->hdd_batch_scan_lock);
6072#endif
6073
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 pAdapter->isLinkUpSvcNeeded = FALSE;
6075 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6076 //Init the net_device structure
6077 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6078
6079 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6080 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6081 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6082 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6083
6084 hdd_set_station_ops( pAdapter->dev );
6085
6086 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006087 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6088 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6089 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006090 /* set pWlanDev's parent to underlying device */
6091 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006092
6093 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 }
6095
6096 return pAdapter;
6097}
6098
6099VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6100{
6101 struct net_device *pWlanDev = pAdapter->dev;
6102 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6103 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6104 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6105
6106 if( rtnl_lock_held )
6107 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006108 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006109 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6110 {
6111 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6112 return VOS_STATUS_E_FAILURE;
6113 }
6114 }
6115 if (register_netdevice(pWlanDev))
6116 {
6117 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6118 return VOS_STATUS_E_FAILURE;
6119 }
6120 }
6121 else
6122 {
6123 if(register_netdev(pWlanDev))
6124 {
6125 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6126 return VOS_STATUS_E_FAILURE;
6127 }
6128 }
6129 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6130
6131 return VOS_STATUS_SUCCESS;
6132}
6133
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006134static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006135{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006136 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006137
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006138 if (NULL == pAdapter)
6139 {
6140 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6141 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006142 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006143
6144 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6145 {
6146 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6147 return eHAL_STATUS_NOT_INITIALIZED;
6148 }
6149
6150 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6151
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006152#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006153 /* need to make sure all of our scheduled work has completed.
6154 * This callback is called from MC thread context, so it is safe to
6155 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006156 *
6157 * Even though this is called from MC thread context, if there is a faulty
6158 * work item in the system, that can hang this call forever. So flushing
6159 * this global work queue is not safe; and now we make sure that
6160 * individual work queues are stopped correctly. But the cancel work queue
6161 * is a GPL only API, so the proprietary version of the driver would still
6162 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006163 */
6164 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006165#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006166
6167 /* We can be blocked while waiting for scheduled work to be
6168 * flushed, and the adapter structure can potentially be freed, in
6169 * which case the magic will have been reset. So make sure the
6170 * magic is still good, and hence the adapter structure is still
6171 * valid, before signaling completion */
6172 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6173 {
6174 complete(&pAdapter->session_close_comp_var);
6175 }
6176
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 return eHAL_STATUS_SUCCESS;
6178}
6179
6180VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6181{
6182 struct net_device *pWlanDev = pAdapter->dev;
6183 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6184 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6185 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6186 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306187 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006188
6189 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006190 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006191 //Open a SME session for future operation
6192 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006193 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006194 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6195 {
6196 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006197 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006198 halStatus, halStatus );
6199 status = VOS_STATUS_E_FAILURE;
6200 goto error_sme_open;
6201 }
6202
6203 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306204 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006205 &pAdapter->session_open_comp_var,
6206 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306207 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006208 {
6209 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306210 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006211 status = VOS_STATUS_E_FAILURE;
6212 goto error_sme_open;
6213 }
6214
6215 // Register wireless extensions
6216 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6217 {
6218 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006219 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006220 halStatus, halStatus );
6221 status = VOS_STATUS_E_FAILURE;
6222 goto error_register_wext;
6223 }
6224 //Safe to register the hard_start_xmit function again
6225#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6226 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6227#else
6228 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6229#endif
6230
6231 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306232 hddLog(VOS_TRACE_LEVEL_INFO,
6233 "%s: Set HDD connState to eConnectionState_NotConnected",
6234 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006235 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6236
6237 //Set the default operation channel
6238 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6239
6240 /* Make the default Auth Type as OPEN*/
6241 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6242
6243 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6244 {
6245 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006246 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 status, status );
6248 goto error_init_txrx;
6249 }
6250
6251 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6252
6253 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6254 {
6255 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006256 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 status, status );
6258 goto error_wmm_init;
6259 }
6260
6261 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6262
6263 return VOS_STATUS_SUCCESS;
6264
6265error_wmm_init:
6266 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6267 hdd_deinit_tx_rx(pAdapter);
6268error_init_txrx:
6269 hdd_UnregisterWext(pWlanDev);
6270error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006271 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006272 {
6273 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006274 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006276 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006277 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306278 unsigned long rc;
6279
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306281 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006282 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006283 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306284 if (rc <= 0)
6285 hddLog(VOS_TRACE_LEVEL_ERROR,
6286 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006287 }
6288}
6289error_sme_open:
6290 return status;
6291}
6292
Jeff Johnson295189b2012-06-20 16:38:30 -07006293void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6294{
6295 hdd_cfg80211_state_t *cfgState;
6296
6297 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6298
6299 if( NULL != cfgState->buf )
6300 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306301 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6303 rc = wait_for_completion_interruptible_timeout(
6304 &pAdapter->tx_action_cnf_event,
6305 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306306 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306309 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6310 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006311 }
6312 }
6313 return;
6314}
Jeff Johnson295189b2012-06-20 16:38:30 -07006315
c_hpothu002231a2015-02-05 14:58:51 +05306316void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006317{
6318 ENTER();
6319 switch ( pAdapter->device_mode )
6320 {
6321 case WLAN_HDD_INFRA_STATION:
6322 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006323 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 {
6325 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6326 {
6327 hdd_deinit_tx_rx( pAdapter );
6328 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6329 }
6330
6331 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6332 {
6333 hdd_wmm_adapter_close( pAdapter );
6334 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6335 }
6336
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 break;
6339 }
6340
6341 case WLAN_HDD_SOFTAP:
6342 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306344
6345 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6346 {
6347 hdd_wmm_adapter_close( pAdapter );
6348 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6349 }
6350
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006352
c_hpothu002231a2015-02-05 14:58:51 +05306353 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 break;
6357 }
6358
6359 case WLAN_HDD_MONITOR:
6360 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6363 {
6364 hdd_deinit_tx_rx( pAdapter );
6365 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6366 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 if(NULL != pAdapterforTx)
6368 {
6369 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 break;
6372 }
6373
6374
6375 default:
6376 break;
6377 }
6378
6379 EXIT();
6380}
6381
6382void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6383{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006384 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306385
6386 ENTER();
6387 if (NULL == pAdapter)
6388 {
6389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6390 "%s: HDD adapter is Null", __func__);
6391 return;
6392 }
6393
6394 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006395
Rajeev79dbe4c2013-10-05 11:03:42 +05306396#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306397 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6398 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006399 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306400 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6401 )
6402 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006403 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306404 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006405 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6406 {
6407 hdd_deinit_batch_scan(pAdapter);
6408 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306409 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006410 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306411#endif
6412
Jeff Johnson295189b2012-06-20 16:38:30 -07006413 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6414 if( rtnl_held )
6415 {
6416 unregister_netdevice(pWlanDev);
6417 }
6418 else
6419 {
6420 unregister_netdev(pWlanDev);
6421 }
6422 // note that the pAdapter is no longer valid at this point
6423 // since the memory has been reclaimed
6424 }
6425
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306426 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006427}
6428
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006429void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6430{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306431 VOS_STATUS status;
6432 hdd_adapter_t *pAdapter = NULL;
6433 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006434
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306435 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006436
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306437 /*loop through all adapters.*/
6438 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006439 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306440 pAdapter = pAdapterNode->pAdapter;
6441 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6442 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006443
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306444 { // we skip this registration for modes other than STA and P2P client modes.
6445 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6446 pAdapterNode = pNext;
6447 continue;
6448 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006449
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306450 //Apply Dynamic DTIM For P2P
6451 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6452 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6453 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6454 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6455 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6456 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6457 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6458 (eConnectionState_Associated ==
6459 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6460 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6461 {
6462 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006463
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306464 powerRequest.uIgnoreDTIM = 1;
6465 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6466
6467 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6468 {
6469 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6470 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6471 }
6472 else
6473 {
6474 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6475 }
6476
6477 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6478 * specified during Enter/Exit BMPS when LCD off*/
6479 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6480 NULL, eANI_BOOLEAN_FALSE);
6481 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6482 NULL, eANI_BOOLEAN_FALSE);
6483
6484 /* switch to the DTIM specified in cfg.ini */
6485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6486 "Switch to DTIM %d", powerRequest.uListenInterval);
6487 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6488 break;
6489
6490 }
6491
6492 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6493 pAdapterNode = pNext;
6494 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006495}
6496
6497void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6498{
6499 /*Switch back to DTIM 1*/
6500 tSirSetPowerParamsReq powerRequest = { 0 };
6501
6502 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6503 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006504 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006505
6506 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6507 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6508 NULL, eANI_BOOLEAN_FALSE);
6509 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6510 NULL, eANI_BOOLEAN_FALSE);
6511
6512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6513 "Switch to DTIM%d",powerRequest.uListenInterval);
6514 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6515
6516}
6517
Jeff Johnson295189b2012-06-20 16:38:30 -07006518VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6519{
6520 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306521 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6522 {
6523 hddLog( LOGE, FL("Wlan Unload in progress"));
6524 return VOS_STATUS_E_PERM;
6525 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006526 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6527 {
6528 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6529 }
6530
6531 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6532 {
6533 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6534 }
6535
6536 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6537 {
6538 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6539 }
6540
6541 return status;
6542}
6543
6544VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6545{
6546 hdd_adapter_t *pAdapter = NULL;
6547 eHalStatus halStatus;
6548 VOS_STATUS status = VOS_STATUS_E_INVAL;
6549 v_BOOL_t disableBmps = FALSE;
6550 v_BOOL_t disableImps = FALSE;
6551
6552 switch(session_type)
6553 {
6554 case WLAN_HDD_INFRA_STATION:
6555 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 case WLAN_HDD_P2P_CLIENT:
6557 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 //Exit BMPS -> Is Sta/P2P Client is already connected
6559 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6560 if((NULL != pAdapter)&&
6561 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6562 {
6563 disableBmps = TRUE;
6564 }
6565
6566 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6567 if((NULL != pAdapter)&&
6568 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6569 {
6570 disableBmps = TRUE;
6571 }
6572
6573 //Exit both Bmps and Imps incase of Go/SAP Mode
6574 if((WLAN_HDD_SOFTAP == session_type) ||
6575 (WLAN_HDD_P2P_GO == session_type))
6576 {
6577 disableBmps = TRUE;
6578 disableImps = TRUE;
6579 }
6580
6581 if(TRUE == disableImps)
6582 {
6583 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6584 {
6585 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6586 }
6587 }
6588
6589 if(TRUE == disableBmps)
6590 {
6591 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6592 {
6593 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6594
6595 if(eHAL_STATUS_SUCCESS != halStatus)
6596 {
6597 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006598 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006599 VOS_ASSERT(0);
6600 return status;
6601 }
6602 }
6603
6604 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6605 {
6606 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6607
6608 if(eHAL_STATUS_SUCCESS != halStatus)
6609 {
6610 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006611 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006612 VOS_ASSERT(0);
6613 return status;
6614 }
6615 }
6616 }
6617
6618 if((TRUE == disableBmps) ||
6619 (TRUE == disableImps))
6620 {
6621 /* Now, get the chip into Full Power now */
6622 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6623 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6624 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6625
6626 if(halStatus != eHAL_STATUS_SUCCESS)
6627 {
6628 if(halStatus == eHAL_STATUS_PMC_PENDING)
6629 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306630 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306632 ret = wait_for_completion_interruptible_timeout(
6633 &pHddCtx->full_pwr_comp_var,
6634 msecs_to_jiffies(1000));
6635 if (ret <= 0)
6636 {
6637 hddLog(VOS_TRACE_LEVEL_ERROR,
6638 "%s: wait on full_pwr_comp_var failed %ld",
6639 __func__, ret);
6640 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006641 }
6642 else
6643 {
6644 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006645 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006646 VOS_ASSERT(0);
6647 return status;
6648 }
6649 }
6650
6651 status = VOS_STATUS_SUCCESS;
6652 }
6653
6654 break;
6655 }
6656 return status;
6657}
6658
6659hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006660 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006661 tANI_U8 rtnl_held )
6662{
6663 hdd_adapter_t *pAdapter = NULL;
6664 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6665 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6666 VOS_STATUS exitbmpsStatus;
6667
Arif Hussain6d2a3322013-11-17 19:50:10 -08006668 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006669
Nirav Shah436658f2014-02-28 17:05:45 +05306670 if(macAddr == NULL)
6671 {
6672 /* Not received valid macAddr */
6673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6674 "%s:Unable to add virtual intf: Not able to get"
6675 "valid mac address",__func__);
6676 return NULL;
6677 }
6678
Jeff Johnson295189b2012-06-20 16:38:30 -07006679 //Disable BMPS incase of Concurrency
6680 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6681
6682 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6683 {
6684 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306685 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006686 VOS_ASSERT(0);
6687 return NULL;
6688 }
6689
6690 switch(session_type)
6691 {
6692 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006693 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006694 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 {
6696 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6697
6698 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306699 {
6700 hddLog(VOS_TRACE_LEVEL_FATAL,
6701 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306703 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006704
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306705#ifdef FEATURE_WLAN_TDLS
6706 /* A Mutex Lock is introduced while changing/initializing the mode to
6707 * protect the concurrent access for the Adapters by TDLS module.
6708 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306709 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306710#endif
6711
Jeff Johnsone7245742012-09-05 17:12:55 -07006712 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6713 NL80211_IFTYPE_P2P_CLIENT:
6714 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006715
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306717#ifdef FEATURE_WLAN_TDLS
6718 mutex_unlock(&pHddCtx->tdls_lock);
6719#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306720
6721 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 if( VOS_STATUS_SUCCESS != status )
6723 goto err_free_netdev;
6724
6725 status = hdd_register_interface( pAdapter, rtnl_held );
6726 if( VOS_STATUS_SUCCESS != status )
6727 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306728#ifdef FEATURE_WLAN_TDLS
6729 mutex_lock(&pHddCtx->tdls_lock);
6730#endif
c_hpothu002231a2015-02-05 14:58:51 +05306731 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306732#ifdef FEATURE_WLAN_TDLS
6733 mutex_unlock(&pHddCtx->tdls_lock);
6734#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006735 goto err_free_netdev;
6736 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306737
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306738 // Workqueue which gets scheduled in IPv4 notification callback.
6739 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6740
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306741#ifdef WLAN_NS_OFFLOAD
6742 // Workqueue which gets scheduled in IPv6 notification callback.
6743 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6744#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006745 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306746 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006747 netif_tx_disable(pAdapter->dev);
6748 //netif_tx_disable(pWlanDev);
6749 netif_carrier_off(pAdapter->dev);
6750
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306751 if (WLAN_HDD_P2P_CLIENT == session_type ||
6752 WLAN_HDD_P2P_DEVICE == session_type)
6753 {
6754 /* Initialize the work queue to defer the
6755 * back to back RoC request */
6756 INIT_DELAYED_WORK(&pAdapter->roc_work,
6757 hdd_p2p_roc_work_queue);
6758 }
6759
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 break;
6761 }
6762
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 case WLAN_HDD_SOFTAP:
6765 {
6766 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6767 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306768 {
6769 hddLog(VOS_TRACE_LEVEL_FATAL,
6770 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006771 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306772 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006773
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6775 NL80211_IFTYPE_AP:
6776 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 pAdapter->device_mode = session_type;
6778
6779 status = hdd_init_ap_mode(pAdapter);
6780 if( VOS_STATUS_SUCCESS != status )
6781 goto err_free_netdev;
6782
6783 status = hdd_register_hostapd( pAdapter, rtnl_held );
6784 if( VOS_STATUS_SUCCESS != status )
6785 {
c_hpothu002231a2015-02-05 14:58:51 +05306786 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 goto err_free_netdev;
6788 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306789 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 netif_tx_disable(pAdapter->dev);
6791 netif_carrier_off(pAdapter->dev);
6792
6793 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306794
6795 if (WLAN_HDD_P2P_GO == session_type)
6796 {
6797 /* Initialize the work queue to
6798 * defer the back to back RoC request */
6799 INIT_DELAYED_WORK(&pAdapter->roc_work,
6800 hdd_p2p_roc_work_queue);
6801 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006802 break;
6803 }
6804 case WLAN_HDD_MONITOR:
6805 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6807 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306808 {
6809 hddLog(VOS_TRACE_LEVEL_FATAL,
6810 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006811 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306812 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006813
6814 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6815 pAdapter->device_mode = session_type;
6816 status = hdd_register_interface( pAdapter, rtnl_held );
6817#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6818 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6819#else
6820 pAdapter->dev->open = hdd_mon_open;
6821 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6822#endif
6823 hdd_init_tx_rx( pAdapter );
6824 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6825 //Set adapter to be used for data tx. It will use either GO or softap.
6826 pAdapter->sessionCtx.monitor.pAdapterForTx =
6827 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006828 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6829 {
6830 pAdapter->sessionCtx.monitor.pAdapterForTx =
6831 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6832 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006833 /* This workqueue will be used to transmit management packet over
6834 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006835 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6836 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6837 return NULL;
6838 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006839
Jeff Johnson295189b2012-06-20 16:38:30 -07006840 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6841 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 }
6843 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 case WLAN_HDD_FTM:
6845 {
6846 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6847
6848 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306849 {
6850 hddLog(VOS_TRACE_LEVEL_FATAL,
6851 FL("failed to allocate adapter for session %d"), session_type);
6852 return NULL;
6853 }
6854
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6856 * message while loading driver in FTM mode. */
6857 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6858 pAdapter->device_mode = session_type;
6859 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306860
6861 hdd_init_tx_rx( pAdapter );
6862
6863 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306864 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306865 netif_tx_disable(pAdapter->dev);
6866 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006867 }
6868 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006869 default:
6870 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306871 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6872 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 VOS_ASSERT(0);
6874 return NULL;
6875 }
6876 }
6877
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 if( VOS_STATUS_SUCCESS == status )
6879 {
6880 //Add it to the hdd's session list.
6881 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6882 if( NULL == pHddAdapterNode )
6883 {
6884 status = VOS_STATUS_E_NOMEM;
6885 }
6886 else
6887 {
6888 pHddAdapterNode->pAdapter = pAdapter;
6889 status = hdd_add_adapter_back ( pHddCtx,
6890 pHddAdapterNode );
6891 }
6892 }
6893
6894 if( VOS_STATUS_SUCCESS != status )
6895 {
6896 if( NULL != pAdapter )
6897 {
6898 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6899 pAdapter = NULL;
6900 }
6901 if( NULL != pHddAdapterNode )
6902 {
6903 vos_mem_free( pHddAdapterNode );
6904 }
6905
6906 goto resume_bmps;
6907 }
6908
6909 if(VOS_STATUS_SUCCESS == status)
6910 {
6911 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6912
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006913 //Initialize the WoWL service
6914 if(!hdd_init_wowl(pAdapter))
6915 {
6916 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6917 goto err_free_netdev;
6918 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006919 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 return pAdapter;
6921
6922err_free_netdev:
6923 free_netdev(pAdapter->dev);
6924 wlan_hdd_release_intf_addr( pHddCtx,
6925 pAdapter->macAddressCurrent.bytes );
6926
6927resume_bmps:
6928 //If bmps disabled enable it
6929 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6930 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306931 if (pHddCtx->hdd_wlan_suspended)
6932 {
6933 hdd_set_pwrparams(pHddCtx);
6934 }
6935 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006936 }
6937 return NULL;
6938}
6939
6940VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6941 tANI_U8 rtnl_held )
6942{
6943 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6944 VOS_STATUS status;
6945
6946 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6947 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306948 {
6949 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6950 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006951 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306952 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006953
6954 while ( pCurrent->pAdapter != pAdapter )
6955 {
6956 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6957 if( VOS_STATUS_SUCCESS != status )
6958 break;
6959
6960 pCurrent = pNext;
6961 }
6962 pAdapterNode = pCurrent;
6963 if( VOS_STATUS_SUCCESS == status )
6964 {
6965 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6966 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306967
6968#ifdef FEATURE_WLAN_TDLS
6969
6970 /* A Mutex Lock is introduced while changing/initializing the mode to
6971 * protect the concurrent access for the Adapters by TDLS module.
6972 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306973 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306974#endif
6975
Jeff Johnson295189b2012-06-20 16:38:30 -07006976 hdd_remove_adapter( pHddCtx, pAdapterNode );
6977 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006978 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006979
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306980#ifdef FEATURE_WLAN_TDLS
6981 mutex_unlock(&pHddCtx->tdls_lock);
6982#endif
6983
Jeff Johnson295189b2012-06-20 16:38:30 -07006984
6985 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306986 if ((!vos_concurrent_open_sessions_running()) &&
6987 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6988 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006989 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306990 if (pHddCtx->hdd_wlan_suspended)
6991 {
6992 hdd_set_pwrparams(pHddCtx);
6993 }
6994 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006995 }
6996
6997 return VOS_STATUS_SUCCESS;
6998 }
6999
7000 return VOS_STATUS_E_FAILURE;
7001}
7002
7003VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7004{
7005 hdd_adapter_list_node_t *pHddAdapterNode;
7006 VOS_STATUS status;
7007
7008 ENTER();
7009
7010 do
7011 {
7012 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7013 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7014 {
7015 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7016 vos_mem_free( pHddAdapterNode );
7017 }
7018 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7019
7020 EXIT();
7021
7022 return VOS_STATUS_SUCCESS;
7023}
7024
7025void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7026{
7027 v_U8_t addIE[1] = {0};
7028
7029 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7030 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7031 eANI_BOOLEAN_FALSE) )
7032 {
7033 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007034 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 }
7036
7037 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7038 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7039 eANI_BOOLEAN_FALSE) )
7040 {
7041 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007042 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 }
7044
7045 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7046 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7047 eANI_BOOLEAN_FALSE) )
7048 {
7049 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007050 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 }
7052}
7053
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307054VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7055 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007056{
7057 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7058 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307059 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007060 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307061 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307062 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007063
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307064 if (pHddCtx->isLogpInProgress) {
7065 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7066 "%s:LOGP in Progress. Ignore!!!",__func__);
7067 return VOS_STATUS_E_FAILURE;
7068 }
7069
Jeff Johnson295189b2012-06-20 16:38:30 -07007070 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307071
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307072 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 switch(pAdapter->device_mode)
7074 {
7075 case WLAN_HDD_INFRA_STATION:
7076 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007077 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307078 {
7079 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7080 if( hdd_connIsConnected(pstation) ||
7081 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007082 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307083#ifdef FEATURE_WLAN_TDLS
7084 mutex_lock(&pHddCtx->tdls_lock);
7085 wlan_hdd_tdls_exit(pAdapter);
7086 mutex_unlock(&pHddCtx->tdls_lock);
7087#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007088 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7089 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7090 pAdapter->sessionId,
7091 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7092 else
7093 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7094 pAdapter->sessionId,
7095 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7096 //success implies disconnect command got queued up successfully
7097 if(halStatus == eHAL_STATUS_SUCCESS)
7098 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307099 ret = wait_for_completion_interruptible_timeout(
7100 &pAdapter->disconnect_comp_var,
7101 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7102 if (ret <= 0)
7103 {
7104 hddLog(VOS_TRACE_LEVEL_ERROR,
7105 "%s: wait on disconnect_comp_var failed %ld",
7106 __func__, ret);
7107 }
7108 }
7109 else
7110 {
7111 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7112 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007113 }
7114 memset(&wrqu, '\0', sizeof(wrqu));
7115 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7116 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7117 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7118 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307119 else if(pstation->conn_info.connState ==
7120 eConnectionState_Disconnecting)
7121 {
7122 ret = wait_for_completion_interruptible_timeout(
7123 &pAdapter->disconnect_comp_var,
7124 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7125 if (ret <= 0)
7126 {
7127 hddLog(VOS_TRACE_LEVEL_ERROR,
7128 FL("wait on disconnect_comp_var failed %ld"), ret);
7129 }
7130 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307131 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007132 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307133 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307134 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307136 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7137 {
7138 while (pAdapter->is_roc_inprogress)
7139 {
7140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7141 "%s: ROC in progress for session %d!!!",
7142 __func__, pAdapter->sessionId);
7143 // waiting for ROC to expire
7144 msleep(500);
7145 /* In GO present case , if retry exceeds 3,
7146 it means something went wrong. */
7147 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7148 {
7149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7150 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307151 if (eHAL_STATUS_SUCCESS !=
7152 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7153 pAdapter->sessionId ))
7154 {
7155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7156 FL("Failed to Cancel Remain on Channel"));
7157 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307158 wait_for_completion_interruptible_timeout(
7159 &pAdapter->cancel_rem_on_chan_var,
7160 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7161 break;
7162 }
7163 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307164#ifdef WLAN_OPEN_SOURCE
7165 cancel_delayed_work_sync(&pAdapter->roc_work);
7166#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307167 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307168#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307169#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307170 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7171#endif
7172#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307173
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307174#ifdef WLAN_OPEN_SOURCE
7175 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7176#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307177
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307178 /* It is possible that the caller of this function does not
7179 * wish to close the session
7180 */
7181 if (VOS_TRUE == bCloseSession &&
7182 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007183 {
7184 INIT_COMPLETION(pAdapter->session_close_comp_var);
7185 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307186 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7187 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007188 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307189 unsigned long ret;
7190
Jeff Johnson295189b2012-06-20 16:38:30 -07007191 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307192 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307193 &pAdapter->session_close_comp_var,
7194 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307195 if ( 0 >= ret)
7196 {
7197 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307198 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307199 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 }
7201 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307202 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007203 break;
7204
7205 case WLAN_HDD_SOFTAP:
7206 case WLAN_HDD_P2P_GO:
7207 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307208 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7209 while (pAdapter->is_roc_inprogress) {
7210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7211 "%s: ROC in progress for session %d!!!",
7212 __func__, pAdapter->sessionId);
7213 msleep(500);
7214 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7216 "%s: ROC completion is not received.!!!", __func__);
7217 WLANSAP_CancelRemainOnChannel(
7218 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7219 wait_for_completion_interruptible_timeout(
7220 &pAdapter->cancel_rem_on_chan_var,
7221 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7222 break;
7223 }
7224 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307225
7226#ifdef WLAN_OPEN_SOURCE
7227 cancel_delayed_work_sync(&pAdapter->roc_work);
7228#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307229 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007230 mutex_lock(&pHddCtx->sap_lock);
7231 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7232 {
7233 VOS_STATUS status;
7234 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7235
7236 //Stop Bss.
7237 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7238 if (VOS_IS_STATUS_SUCCESS(status))
7239 {
7240 hdd_hostapd_state_t *pHostapdState =
7241 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7242
7243 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7244
7245 if (!VOS_IS_STATUS_SUCCESS(status))
7246 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307247 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7248 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007249 }
7250 }
7251 else
7252 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007253 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007254 }
7255 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307256 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007257
7258 if (eHAL_STATUS_FAILURE ==
7259 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7260 0, NULL, eANI_BOOLEAN_FALSE))
7261 {
7262 hddLog(LOGE,
7263 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007264 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007265 }
7266
7267 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7268 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7269 eANI_BOOLEAN_FALSE) )
7270 {
7271 hddLog(LOGE,
7272 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7273 }
7274
7275 // Reset WNI_CFG_PROBE_RSP Flags
7276 wlan_hdd_reset_prob_rspies(pAdapter);
7277 kfree(pAdapter->sessionCtx.ap.beacon);
7278 pAdapter->sessionCtx.ap.beacon = NULL;
7279 }
7280 mutex_unlock(&pHddCtx->sap_lock);
7281 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007282
Jeff Johnson295189b2012-06-20 16:38:30 -07007283 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007284#ifdef WLAN_OPEN_SOURCE
7285 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7286#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007287 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007288
Jeff Johnson295189b2012-06-20 16:38:30 -07007289 default:
7290 break;
7291 }
7292
7293 EXIT();
7294 return VOS_STATUS_SUCCESS;
7295}
7296
7297VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7298{
7299 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7300 VOS_STATUS status;
7301 hdd_adapter_t *pAdapter;
7302
7303 ENTER();
7304
7305 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7306
7307 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7308 {
7309 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007310
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307311 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007312
7313 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7314 pAdapterNode = pNext;
7315 }
7316
7317 EXIT();
7318
7319 return VOS_STATUS_SUCCESS;
7320}
7321
Rajeev Kumarf999e582014-01-09 17:33:29 -08007322
7323#ifdef FEATURE_WLAN_BATCH_SCAN
7324/**---------------------------------------------------------------------------
7325
7326 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7327 structures
7328
7329 \param - pAdapter Pointer to HDD adapter
7330
7331 \return - None
7332
7333 --------------------------------------------------------------------------*/
7334void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7335{
7336 tHddBatchScanRsp *pNode;
7337 tHddBatchScanRsp *pPrev;
7338
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307339 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007340 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307341 hddLog(VOS_TRACE_LEVEL_ERROR,
7342 "%s: Adapter context is Null", __func__);
7343 return;
7344 }
7345
7346 pNode = pAdapter->pBatchScanRsp;
7347 while (pNode)
7348 {
7349 pPrev = pNode;
7350 pNode = pNode->pNext;
7351 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007352 }
7353
7354 pAdapter->pBatchScanRsp = NULL;
7355 pAdapter->numScanList = 0;
7356 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7357 pAdapter->prev_batch_id = 0;
7358
7359 return;
7360}
7361#endif
7362
7363
Jeff Johnson295189b2012-06-20 16:38:30 -07007364VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7365{
7366 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7367 VOS_STATUS status;
7368 hdd_adapter_t *pAdapter;
7369
7370 ENTER();
7371
7372 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7373
7374 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7375 {
7376 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307377 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007378 netif_tx_disable(pAdapter->dev);
7379 netif_carrier_off(pAdapter->dev);
7380
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007381 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7382
Jeff Johnson295189b2012-06-20 16:38:30 -07007383 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307384
7385 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7386
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307387 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7388 {
7389 hdd_wmm_adapter_close( pAdapter );
7390 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7391 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007392
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307393 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7394 {
7395 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7396 }
7397
Rajeev Kumarf999e582014-01-09 17:33:29 -08007398#ifdef FEATURE_WLAN_BATCH_SCAN
7399 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7400 {
7401 hdd_deinit_batch_scan(pAdapter);
7402 }
7403#endif
7404
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307405#ifdef FEATURE_WLAN_TDLS
7406 mutex_lock(&pHddCtx->tdls_lock);
7407 wlan_hdd_tdls_exit(pAdapter);
7408 mutex_unlock(&pHddCtx->tdls_lock);
7409#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7411 pAdapterNode = pNext;
7412 }
7413
7414 EXIT();
7415
7416 return VOS_STATUS_SUCCESS;
7417}
7418
7419VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7420{
7421 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7422 VOS_STATUS status;
7423 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307424 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007425
7426 ENTER();
7427
7428 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7429
7430 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7431 {
7432 pAdapter = pAdapterNode->pAdapter;
7433
Kumar Anand82c009f2014-05-29 00:29:42 -07007434 hdd_wmm_init( pAdapter );
7435
Jeff Johnson295189b2012-06-20 16:38:30 -07007436 switch(pAdapter->device_mode)
7437 {
7438 case WLAN_HDD_INFRA_STATION:
7439 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007440 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307441
7442 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7443
Jeff Johnson295189b2012-06-20 16:38:30 -07007444 hdd_init_station_mode(pAdapter);
7445 /* Open the gates for HDD to receive Wext commands */
7446 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007447 pHddCtx->scan_info.mScanPending = FALSE;
7448 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007449
7450 //Trigger the initial scan
7451 hdd_wlan_initial_scan(pAdapter);
7452
7453 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307454 if (eConnectionState_Associated == connState ||
7455 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007456 {
7457 union iwreq_data wrqu;
7458 memset(&wrqu, '\0', sizeof(wrqu));
7459 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7460 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7461 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007462 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007463
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 /* indicate disconnected event to nl80211 */
7465 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7466 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007467 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307468 else if (eConnectionState_Connecting == connState)
7469 {
7470 /*
7471 * Indicate connect failure to supplicant if we were in the
7472 * process of connecting
7473 */
7474 cfg80211_connect_result(pAdapter->dev, NULL,
7475 NULL, 0, NULL, 0,
7476 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7477 GFP_KERNEL);
7478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 break;
7480
7481 case WLAN_HDD_SOFTAP:
7482 /* softAP can handle SSR */
7483 break;
7484
7485 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007486 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007488 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007489 break;
7490
7491 case WLAN_HDD_MONITOR:
7492 /* monitor interface start */
7493 break;
7494 default:
7495 break;
7496 }
7497
7498 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7499 pAdapterNode = pNext;
7500 }
7501
7502 EXIT();
7503
7504 return VOS_STATUS_SUCCESS;
7505}
7506
7507VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7508{
7509 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7510 hdd_adapter_t *pAdapter;
7511 VOS_STATUS status;
7512 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307513 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007514
7515 ENTER();
7516
7517 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7518
7519 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7520 {
7521 pAdapter = pAdapterNode->pAdapter;
7522
7523 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7524 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7525 {
7526 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7527 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7528
Abhishek Singhf4669da2014-05-26 15:07:49 +05307529 hddLog(VOS_TRACE_LEVEL_INFO,
7530 "%s: Set HDD connState to eConnectionState_NotConnected",
7531 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007532 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7533 init_completion(&pAdapter->disconnect_comp_var);
7534 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7535 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7536
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307537 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007538 &pAdapter->disconnect_comp_var,
7539 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307540 if (0 >= ret)
7541 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7542 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007543
7544 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7545 pHddCtx->isAmpAllowed = VOS_FALSE;
7546 sme_RoamConnect(pHddCtx->hHal,
7547 pAdapter->sessionId, &(pWextState->roamProfile),
7548 &roamId);
7549 }
7550
7551 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7552 pAdapterNode = pNext;
7553 }
7554
7555 EXIT();
7556
7557 return VOS_STATUS_SUCCESS;
7558}
7559
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007560void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7561{
7562 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7563 VOS_STATUS status;
7564 hdd_adapter_t *pAdapter;
7565 hdd_station_ctx_t *pHddStaCtx;
7566 hdd_ap_ctx_t *pHddApCtx;
7567 hdd_hostapd_state_t * pHostapdState;
7568 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7569 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7570 const char *p2pMode = "DEV";
7571 const char *ccMode = "Standalone";
7572 int n;
7573
7574 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7575 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7576 {
7577 pAdapter = pAdapterNode->pAdapter;
7578 switch (pAdapter->device_mode) {
7579 case WLAN_HDD_INFRA_STATION:
7580 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7581 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7582 staChannel = pHddStaCtx->conn_info.operationChannel;
7583 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7584 }
7585 break;
7586 case WLAN_HDD_P2P_CLIENT:
7587 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7588 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7589 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7590 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7591 p2pMode = "CLI";
7592 }
7593 break;
7594 case WLAN_HDD_P2P_GO:
7595 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7596 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7597 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7598 p2pChannel = pHddApCtx->operatingChannel;
7599 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7600 }
7601 p2pMode = "GO";
7602 break;
7603 case WLAN_HDD_SOFTAP:
7604 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7605 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7606 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7607 apChannel = pHddApCtx->operatingChannel;
7608 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7609 }
7610 break;
7611 default:
7612 break;
7613 }
7614 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7615 pAdapterNode = pNext;
7616 }
7617 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7618 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7619 }
7620 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7621 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7622 if (p2pChannel > 0) {
7623 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7624 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7625 }
7626 if (apChannel > 0) {
7627 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7628 apChannel, MAC_ADDR_ARRAY(apBssid));
7629 }
7630
7631 if (p2pChannel > 0 && apChannel > 0) {
7632 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7633 }
7634}
7635
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007636bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007637{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007638 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007639}
7640
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007641/* Once SSR is disabled then it cannot be set. */
7642void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007643{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007644 if (HDD_SSR_DISABLED == isSsrRequired)
7645 return;
7646
Jeff Johnson295189b2012-06-20 16:38:30 -07007647 isSsrRequired = value;
7648}
7649
7650VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7651 hdd_adapter_list_node_t** ppAdapterNode)
7652{
7653 VOS_STATUS status;
7654 spin_lock(&pHddCtx->hddAdapters.lock);
7655 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7656 (hdd_list_node_t**) ppAdapterNode );
7657 spin_unlock(&pHddCtx->hddAdapters.lock);
7658 return status;
7659}
7660
7661VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7662 hdd_adapter_list_node_t* pAdapterNode,
7663 hdd_adapter_list_node_t** pNextAdapterNode)
7664{
7665 VOS_STATUS status;
7666 spin_lock(&pHddCtx->hddAdapters.lock);
7667 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7668 (hdd_list_node_t*) pAdapterNode,
7669 (hdd_list_node_t**)pNextAdapterNode );
7670
7671 spin_unlock(&pHddCtx->hddAdapters.lock);
7672 return status;
7673}
7674
7675VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7676 hdd_adapter_list_node_t* pAdapterNode)
7677{
7678 VOS_STATUS status;
7679 spin_lock(&pHddCtx->hddAdapters.lock);
7680 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7681 &pAdapterNode->node );
7682 spin_unlock(&pHddCtx->hddAdapters.lock);
7683 return status;
7684}
7685
7686VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7687 hdd_adapter_list_node_t** ppAdapterNode)
7688{
7689 VOS_STATUS status;
7690 spin_lock(&pHddCtx->hddAdapters.lock);
7691 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7692 (hdd_list_node_t**) ppAdapterNode );
7693 spin_unlock(&pHddCtx->hddAdapters.lock);
7694 return status;
7695}
7696
7697VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7698 hdd_adapter_list_node_t* pAdapterNode)
7699{
7700 VOS_STATUS status;
7701 spin_lock(&pHddCtx->hddAdapters.lock);
7702 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7703 (hdd_list_node_t*) pAdapterNode );
7704 spin_unlock(&pHddCtx->hddAdapters.lock);
7705 return status;
7706}
7707
7708VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7709 hdd_adapter_list_node_t* pAdapterNode)
7710{
7711 VOS_STATUS status;
7712 spin_lock(&pHddCtx->hddAdapters.lock);
7713 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7714 (hdd_list_node_t*) pAdapterNode );
7715 spin_unlock(&pHddCtx->hddAdapters.lock);
7716 return status;
7717}
7718
7719hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7720 tSirMacAddr macAddr )
7721{
7722 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7723 hdd_adapter_t *pAdapter;
7724 VOS_STATUS status;
7725
7726 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7727
7728 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7729 {
7730 pAdapter = pAdapterNode->pAdapter;
7731
7732 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7733 macAddr, sizeof(tSirMacAddr) ) )
7734 {
7735 return pAdapter;
7736 }
7737 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7738 pAdapterNode = pNext;
7739 }
7740
7741 return NULL;
7742
7743}
7744
7745hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7746{
7747 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7748 hdd_adapter_t *pAdapter;
7749 VOS_STATUS status;
7750
7751 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7752
7753 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7754 {
7755 pAdapter = pAdapterNode->pAdapter;
7756
7757 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7758 IFNAMSIZ ) )
7759 {
7760 return pAdapter;
7761 }
7762 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7763 pAdapterNode = pNext;
7764 }
7765
7766 return NULL;
7767
7768}
7769
7770hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7771{
7772 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7773 hdd_adapter_t *pAdapter;
7774 VOS_STATUS status;
7775
7776 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7777
7778 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7779 {
7780 pAdapter = pAdapterNode->pAdapter;
7781
7782 if( pAdapter && (mode == pAdapter->device_mode) )
7783 {
7784 return pAdapter;
7785 }
7786 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7787 pAdapterNode = pNext;
7788 }
7789
7790 return NULL;
7791
7792}
7793
7794//Remove this function later
7795hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7796{
7797 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7798 hdd_adapter_t *pAdapter;
7799 VOS_STATUS status;
7800
7801 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7802
7803 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7804 {
7805 pAdapter = pAdapterNode->pAdapter;
7806
7807 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7808 {
7809 return pAdapter;
7810 }
7811
7812 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7813 pAdapterNode = pNext;
7814 }
7815
7816 return NULL;
7817
7818}
7819
Jeff Johnson295189b2012-06-20 16:38:30 -07007820/**---------------------------------------------------------------------------
7821
7822 \brief hdd_set_monitor_tx_adapter() -
7823
7824 This API initializes the adapter to be used while transmitting on monitor
7825 adapter.
7826
7827 \param - pHddCtx - Pointer to the HDD context.
7828 pAdapter - Adapter that will used for TX. This can be NULL.
7829 \return - None.
7830 --------------------------------------------------------------------------*/
7831void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7832{
7833 hdd_adapter_t *pMonAdapter;
7834
7835 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7836
7837 if( NULL != pMonAdapter )
7838 {
7839 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7840 }
7841}
Jeff Johnson295189b2012-06-20 16:38:30 -07007842/**---------------------------------------------------------------------------
7843
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307844 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007845
7846 This API returns the operating channel of the requested device mode
7847
7848 \param - pHddCtx - Pointer to the HDD context.
7849 - mode - Device mode for which operating channel is required
7850 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7851 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7852 \return - channel number. "0" id the requested device is not found OR it is not connected.
7853 --------------------------------------------------------------------------*/
7854v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7855{
7856 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7857 VOS_STATUS status;
7858 hdd_adapter_t *pAdapter;
7859 v_U8_t operatingChannel = 0;
7860
7861 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7862
7863 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7864 {
7865 pAdapter = pAdapterNode->pAdapter;
7866
7867 if( mode == pAdapter->device_mode )
7868 {
7869 switch(pAdapter->device_mode)
7870 {
7871 case WLAN_HDD_INFRA_STATION:
7872 case WLAN_HDD_P2P_CLIENT:
7873 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7874 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7875 break;
7876 case WLAN_HDD_SOFTAP:
7877 case WLAN_HDD_P2P_GO:
7878 /*softap connection info */
7879 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7880 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7881 break;
7882 default:
7883 break;
7884 }
7885
7886 break; //Found the device of interest. break the loop
7887 }
7888
7889 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7890 pAdapterNode = pNext;
7891 }
7892 return operatingChannel;
7893}
7894
7895#ifdef WLAN_FEATURE_PACKET_FILTERING
7896/**---------------------------------------------------------------------------
7897
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307898 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007899
7900 This used to set the multicast address list.
7901
7902 \param - dev - Pointer to the WLAN device.
7903 - skb - Pointer to OS packet (sk_buff).
7904 \return - success/fail
7905
7906 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307907static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007908{
7909 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 int mc_count;
7911 int i = 0;
7912 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307913
7914 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007915 {
7916 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307917 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 return;
7919 }
7920
7921 if (dev->flags & IFF_ALLMULTI)
7922 {
7923 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007924 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307925 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 }
7927 else
7928 {
7929 mc_count = netdev_mc_count(dev);
7930 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007931 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007932 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7933 {
7934 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007935 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307936 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007937 return;
7938 }
7939
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307940 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007941
7942 netdev_for_each_mc_addr(ha, dev) {
7943 if (i == mc_count)
7944 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307945 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7946 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007947 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007948 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307949 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007950 i++;
7951 }
7952 }
7953 return;
7954}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307955
7956static void hdd_set_multicast_list(struct net_device *dev)
7957{
7958 vos_ssr_protect(__func__);
7959 __hdd_set_multicast_list(dev);
7960 vos_ssr_unprotect(__func__);
7961}
Jeff Johnson295189b2012-06-20 16:38:30 -07007962#endif
7963
7964/**---------------------------------------------------------------------------
7965
7966 \brief hdd_select_queue() -
7967
7968 This function is registered with the Linux OS for network
7969 core to decide which queue to use first.
7970
7971 \param - dev - Pointer to the WLAN device.
7972 - skb - Pointer to OS packet (sk_buff).
7973 \return - ac, Queue Index/access category corresponding to UP in IP header
7974
7975 --------------------------------------------------------------------------*/
7976v_U16_t hdd_select_queue(struct net_device *dev,
7977 struct sk_buff *skb)
7978{
7979 return hdd_wmm_select_queue(dev, skb);
7980}
7981
7982
7983/**---------------------------------------------------------------------------
7984
7985 \brief hdd_wlan_initial_scan() -
7986
7987 This function triggers the initial scan
7988
7989 \param - pAdapter - Pointer to the HDD adapter.
7990
7991 --------------------------------------------------------------------------*/
7992void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
7993{
7994 tCsrScanRequest scanReq;
7995 tCsrChannelInfo channelInfo;
7996 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07007997 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007998 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7999
8000 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8001 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8002 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8003
8004 if(sme_Is11dSupported(pHddCtx->hHal))
8005 {
8006 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8007 if ( HAL_STATUS_SUCCESS( halStatus ) )
8008 {
8009 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8010 if( !scanReq.ChannelInfo.ChannelList )
8011 {
8012 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8013 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008014 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008015 return;
8016 }
8017 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8018 channelInfo.numOfChannels);
8019 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8020 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008021 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008022 }
8023
8024 scanReq.scanType = eSIR_PASSIVE_SCAN;
8025 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8026 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8027 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8028 }
8029 else
8030 {
8031 scanReq.scanType = eSIR_ACTIVE_SCAN;
8032 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8033 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8034 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8035 }
8036
8037 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8038 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8039 {
8040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8041 __func__, halStatus );
8042 }
8043
8044 if(sme_Is11dSupported(pHddCtx->hHal))
8045 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8046}
8047
Jeff Johnson295189b2012-06-20 16:38:30 -07008048/**---------------------------------------------------------------------------
8049
8050 \brief hdd_full_power_callback() - HDD full power callback function
8051
8052 This is the function invoked by SME to inform the result of a full power
8053 request issued by HDD
8054
8055 \param - callbackcontext - Pointer to cookie
8056 \param - status - result of request
8057
8058 \return - None
8059
8060 --------------------------------------------------------------------------*/
8061static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8062{
Jeff Johnson72a40512013-12-19 10:14:15 -08008063 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008064
8065 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308066 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008067
8068 if (NULL == callbackContext)
8069 {
8070 hddLog(VOS_TRACE_LEVEL_ERROR,
8071 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008072 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 return;
8074 }
8075
Jeff Johnson72a40512013-12-19 10:14:15 -08008076 /* there is a race condition that exists between this callback
8077 function and the caller since the caller could time out either
8078 before or while this code is executing. we use a spinlock to
8079 serialize these actions */
8080 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008081
8082 if (POWER_CONTEXT_MAGIC != pContext->magic)
8083 {
8084 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008085 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 hddLog(VOS_TRACE_LEVEL_WARN,
8087 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008088 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008089 return;
8090 }
8091
Jeff Johnson72a40512013-12-19 10:14:15 -08008092 /* context is valid so caller is still waiting */
8093
8094 /* paranoia: invalidate the magic */
8095 pContext->magic = 0;
8096
8097 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008098 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008099
8100 /* serialization is complete */
8101 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008102}
8103
8104/**---------------------------------------------------------------------------
8105
8106 \brief hdd_wlan_exit() - HDD WLAN exit function
8107
8108 This is the driver exit point (invoked during rmmod)
8109
8110 \param - pHddCtx - Pointer to the HDD Context
8111
8112 \return - None
8113
8114 --------------------------------------------------------------------------*/
8115void hdd_wlan_exit(hdd_context_t *pHddCtx)
8116{
8117 eHalStatus halStatus;
8118 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8119 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308120 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008121 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008122 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308124 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008125
8126 ENTER();
8127
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308128#ifdef WLAN_NS_OFFLOAD
8129 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8130 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8131#endif
8132 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8133 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8134
Jeff Johnson88ba7742013-02-27 14:36:02 -08008135 if (VOS_FTM_MODE != hdd_get_conparam())
8136 {
8137 // Unloading, restart logic is no more required.
8138 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008139
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308140#ifdef FEATURE_WLAN_TDLS
8141 /* At the time of driver unloading; if tdls connection is present;
8142 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8143 * wlan_hdd_tdls_find_peer always checks for valid context;
8144 * as load/unload in progress there can be a race condition.
8145 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8146 * when tdls state is enabled.
8147 * As soon as driver set load/unload flag; tdls flag also needs
8148 * to be disabled so that hdd_rx_packet_cbk won't call
8149 * wlan_hdd_tdls_find_peer.
8150 */
8151 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8152#endif
8153
c_hpothu5ab05e92014-06-13 17:34:05 +05308154 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8155 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008156 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308157 pAdapter = pAdapterNode->pAdapter;
8158 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008159 {
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308160 /* DeInit the adapter. This ensures that all data packets
8161 * are freed.
8162 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308163#ifdef FEATURE_WLAN_TDLS
8164 mutex_lock(&pHddCtx->tdls_lock);
8165#endif
c_hpothu002231a2015-02-05 14:58:51 +05308166 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308167#ifdef FEATURE_WLAN_TDLS
8168 mutex_unlock(&pHddCtx->tdls_lock);
8169#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308170
c_hpothu5ab05e92014-06-13 17:34:05 +05308171 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8172 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8173 {
8174 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8175 hdd_UnregisterWext(pAdapter->dev);
8176 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308177
Jeff Johnson295189b2012-06-20 16:38:30 -07008178 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308179 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8180 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008181 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308182 // Cancel any outstanding scan requests. We are about to close all
8183 // of our adapters, but an adapter structure is what SME passes back
8184 // to our callback function. Hence if there are any outstanding scan
8185 // requests then there is a race condition between when the adapter
8186 // is closed and when the callback is invoked.We try to resolve that
8187 // race condition here by canceling any outstanding scans before we
8188 // close the adapters.
8189 // Note that the scans may be cancelled in an asynchronous manner,
8190 // so ideally there needs to be some kind of synchronization. Rather
8191 // than introduce a new synchronization here, we will utilize the
8192 // fact that we are about to Request Full Power, and since that is
8193 // synchronized, the expectation is that by the time Request Full
8194 // Power has completed all scans will be cancelled.
8195 if (pHddCtx->scan_info.mScanPending)
8196 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308197 if(NULL != pAdapter)
8198 {
8199 hddLog(VOS_TRACE_LEVEL_INFO,
8200 FL("abort scan mode: %d sessionId: %d"),
8201 pAdapter->device_mode,
8202 pAdapter->sessionId);
8203 }
8204 hdd_abort_mac_scan(pHddCtx,
8205 pHddCtx->scan_info.sessionId,
8206 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308207 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308209 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008210 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308211 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Jeff Johnson88ba7742013-02-27 14:36:02 -08008212 wlan_hdd_ftm_close(pHddCtx);
8213 goto free_hdd_ctx;
8214 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308215
Jeff Johnson295189b2012-06-20 16:38:30 -07008216 /* DeRegister with platform driver as client for Suspend/Resume */
8217 vosStatus = hddDeregisterPmOps(pHddCtx);
8218 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8219 {
8220 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8221 VOS_ASSERT(0);
8222 }
8223
8224 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8225 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8226 {
8227 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8228 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008229
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008230 //Stop the traffic monitor timer
8231 if ( VOS_TIMER_STATE_RUNNING ==
8232 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8233 {
8234 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8235 }
8236
8237 // Destroy the traffic monitor timer
8238 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8239 &pHddCtx->tx_rx_trafficTmr)))
8240 {
8241 hddLog(VOS_TRACE_LEVEL_ERROR,
8242 "%s: Cannot deallocate Traffic monitor timer", __func__);
8243 }
8244
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 //Disable IMPS/BMPS as we do not want the device to enter any power
8246 //save mode during shutdown
8247 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8248 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8249 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8250
8251 //Ensure that device is in full power as we will touch H/W during vos_Stop
8252 init_completion(&powerContext.completion);
8253 powerContext.magic = POWER_CONTEXT_MAGIC;
8254
8255 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8256 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8257
8258 if (eHAL_STATUS_SUCCESS != halStatus)
8259 {
8260 if (eHAL_STATUS_PMC_PENDING == halStatus)
8261 {
8262 /* request was sent -- wait for the response */
8263 lrc = wait_for_completion_interruptible_timeout(
8264 &powerContext.completion,
8265 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008266 if (lrc <= 0)
8267 {
8268 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008269 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 }
8271 }
8272 else
8273 {
8274 hddLog(VOS_TRACE_LEVEL_ERROR,
8275 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008276 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008277 /* continue -- need to clean up as much as possible */
8278 }
8279 }
8280
Jeff Johnson72a40512013-12-19 10:14:15 -08008281 /* either we never sent a request, we sent a request and received a
8282 response or we sent a request and timed out. if we never sent a
8283 request or if we sent a request and got a response, we want to
8284 clear the magic out of paranoia. if we timed out there is a
8285 race condition such that the callback function could be
8286 executing at the same time we are. of primary concern is if the
8287 callback function had already verified the "magic" but had not
8288 yet set the completion variable when a timeout occurred. we
8289 serialize these activities by invalidating the magic while
8290 holding a shared spinlock which will cause us to block if the
8291 callback is currently executing */
8292 spin_lock(&hdd_context_lock);
8293 powerContext.magic = 0;
8294 spin_unlock(&hdd_context_lock);
8295
Yue Ma0d4891e2013-08-06 17:01:45 -07008296 hdd_debugfs_exit(pHddCtx);
8297
Jeff Johnson295189b2012-06-20 16:38:30 -07008298 // Unregister the Net Device Notifier
8299 unregister_netdevice_notifier(&hdd_netdev_notifier);
8300
Jeff Johnson295189b2012-06-20 16:38:30 -07008301 hdd_stop_all_adapters( pHddCtx );
8302
Jeff Johnson295189b2012-06-20 16:38:30 -07008303#ifdef WLAN_BTAMP_FEATURE
8304 vosStatus = WLANBAP_Stop(pVosContext);
8305 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8306 {
8307 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8308 "%s: Failed to stop BAP",__func__);
8309 }
8310#endif //WLAN_BTAMP_FEATURE
8311
8312 //Stop all the modules
8313 vosStatus = vos_stop( pVosContext );
8314 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8315 {
8316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8317 "%s: Failed to stop VOSS",__func__);
8318 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8319 }
8320
Jeff Johnson295189b2012-06-20 16:38:30 -07008321 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008322 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008323
8324 //Close the scheduler before calling vos_close to make sure no thread is
8325 // scheduled after the each module close is called i.e after all the data
8326 // structures are freed.
8327 vosStatus = vos_sched_close( pVosContext );
8328 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8329 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8330 "%s: Failed to close VOSS Scheduler",__func__);
8331 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8332 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008333#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008334#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8335 /* Destroy the wake lock */
8336 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8337#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008338 /* Destroy the wake lock */
8339 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008340#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008341
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308342#ifdef CONFIG_ENABLE_LINUX_REG
8343 vosStatus = vos_nv_close();
8344 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8345 {
8346 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8347 "%s: Failed to close NV", __func__);
8348 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8349 }
8350#endif
8351
Jeff Johnson295189b2012-06-20 16:38:30 -07008352 //Close VOSS
8353 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8354 vos_close(pVosContext);
8355
Jeff Johnson295189b2012-06-20 16:38:30 -07008356 //Close Watchdog
8357 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8358 vos_watchdog_close(pVosContext);
8359
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308360 //Clean up HDD Nlink Service
8361 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308362
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308363#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308364 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308365 {
8366 wlan_logging_sock_deactivate_svc();
8367 }
8368#endif
8369
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308370#ifdef WLAN_KD_READY_NOTIFIER
8371 nl_srv_exit(pHddCtx->ptt_pid);
8372#else
8373 nl_srv_exit();
8374#endif /* WLAN_KD_READY_NOTIFIER */
8375
8376
Jeff Johnson295189b2012-06-20 16:38:30 -07008377 hdd_close_all_adapters( pHddCtx );
8378
Jeff Johnson295189b2012-06-20 16:38:30 -07008379 /* free the power on lock from platform driver */
8380 if (free_riva_power_on_lock("wlan"))
8381 {
8382 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8383 __func__);
8384 }
8385
Jeff Johnson88ba7742013-02-27 14:36:02 -08008386free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308387
8388 //Free up dynamically allocated members inside HDD Adapter
8389 if (pHddCtx->cfg_ini)
8390 {
8391 kfree(pHddCtx->cfg_ini);
8392 pHddCtx->cfg_ini= NULL;
8393 }
8394
Leo Changf04ddad2013-09-18 13:46:38 -07008395 /* FTM mode, WIPHY did not registered
8396 If un-register here, system crash will happen */
8397 if (VOS_FTM_MODE != hdd_get_conparam())
8398 {
8399 wiphy_unregister(wiphy) ;
8400 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008402 if (hdd_is_ssr_required())
8403 {
8404 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008405 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 msleep(5000);
8407 }
8408 hdd_set_ssr_required (VOS_FALSE);
8409}
8410
8411
8412/**---------------------------------------------------------------------------
8413
8414 \brief hdd_update_config_from_nv() - Function to update the contents of
8415 the running configuration with parameters taken from NV storage
8416
8417 \param - pHddCtx - Pointer to the HDD global context
8418
8419 \return - VOS_STATUS_SUCCESS if successful
8420
8421 --------------------------------------------------------------------------*/
8422static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8423{
Jeff Johnson295189b2012-06-20 16:38:30 -07008424 v_BOOL_t itemIsValid = VOS_FALSE;
8425 VOS_STATUS status;
8426 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8427 v_U8_t macLoop;
8428
8429 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8430 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8431 if(status != VOS_STATUS_SUCCESS)
8432 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008433 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 return VOS_STATUS_E_FAILURE;
8435 }
8436
8437 if (itemIsValid == VOS_TRUE)
8438 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008439 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008440 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8441 VOS_MAX_CONCURRENCY_PERSONA);
8442 if(status != VOS_STATUS_SUCCESS)
8443 {
8444 /* Get MAC from NV fail, not update CFG info
8445 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008446 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008447 return VOS_STATUS_E_FAILURE;
8448 }
8449
8450 /* If first MAC is not valid, treat all others are not valid
8451 * Then all MACs will be got from ini file */
8452 if(vos_is_macaddr_zero(&macFromNV[0]))
8453 {
8454 /* MAC address in NV file is not configured yet */
8455 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8456 return VOS_STATUS_E_INVAL;
8457 }
8458
8459 /* Get MAC address from NV, update CFG info */
8460 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8461 {
8462 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8463 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308464 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 /* This MAC is not valid, skip it
8466 * This MAC will be got from ini file */
8467 }
8468 else
8469 {
8470 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8471 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8472 VOS_MAC_ADDR_SIZE);
8473 }
8474 }
8475 }
8476 else
8477 {
8478 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8479 return VOS_STATUS_E_FAILURE;
8480 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008481
Jeff Johnson295189b2012-06-20 16:38:30 -07008482
8483 return VOS_STATUS_SUCCESS;
8484}
8485
8486/**---------------------------------------------------------------------------
8487
8488 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8489
8490 \param - pAdapter - Pointer to the HDD
8491
8492 \return - None
8493
8494 --------------------------------------------------------------------------*/
8495VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8496{
8497 eHalStatus halStatus;
8498 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308499 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008500
Jeff Johnson295189b2012-06-20 16:38:30 -07008501
8502 // Send ready indication to the HDD. This will kick off the MAC
8503 // into a 'running' state and should kick off an initial scan.
8504 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8505 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8506 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308507 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008508 "code %08d [x%08x]",__func__, halStatus, halStatus );
8509 return VOS_STATUS_E_FAILURE;
8510 }
8511
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308512 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008513 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8514 // And RIVA will crash
8515 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8516 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308517 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8518 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8519
8520
Jeff Johnson295189b2012-06-20 16:38:30 -07008521 return VOS_STATUS_SUCCESS;
8522}
8523
Jeff Johnson295189b2012-06-20 16:38:30 -07008524/* wake lock APIs for HDD */
8525void hdd_prevent_suspend(void)
8526{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008527#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008528 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008529#else
8530 wcnss_prevent_suspend();
8531#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008532}
8533
8534void hdd_allow_suspend(void)
8535{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008536#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008537 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008538#else
8539 wcnss_allow_suspend();
8540#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008541}
8542
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308543void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008544{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008545#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008546 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008547#else
8548 /* Do nothing as there is no API in wcnss for timeout*/
8549#endif
8550}
8551
Jeff Johnson295189b2012-06-20 16:38:30 -07008552/**---------------------------------------------------------------------------
8553
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008554 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8555 information between Host and Riva
8556
8557 This function gets reported version of FW
8558 It also finds the version of Riva headers used to compile the host
8559 It compares the above two and prints a warning if they are different
8560 It gets the SW and HW version string
8561 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8562 indicating the features they support through a bitmap
8563
8564 \param - pHddCtx - Pointer to HDD context
8565
8566 \return - void
8567
8568 --------------------------------------------------------------------------*/
8569
8570void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8571{
8572
8573 tSirVersionType versionCompiled;
8574 tSirVersionType versionReported;
8575 tSirVersionString versionString;
8576 tANI_U8 fwFeatCapsMsgSupported = 0;
8577 VOS_STATUS vstatus;
8578
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008579 memset(&versionCompiled, 0, sizeof(versionCompiled));
8580 memset(&versionReported, 0, sizeof(versionReported));
8581
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008582 /* retrieve and display WCNSS version information */
8583 do {
8584
8585 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8586 &versionCompiled);
8587 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8588 {
8589 hddLog(VOS_TRACE_LEVEL_FATAL,
8590 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008591 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008592 break;
8593 }
8594
8595 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8596 &versionReported);
8597 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8598 {
8599 hddLog(VOS_TRACE_LEVEL_FATAL,
8600 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008601 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008602 break;
8603 }
8604
8605 if ((versionCompiled.major != versionReported.major) ||
8606 (versionCompiled.minor != versionReported.minor) ||
8607 (versionCompiled.version != versionReported.version) ||
8608 (versionCompiled.revision != versionReported.revision))
8609 {
8610 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8611 "Host expected %u.%u.%u.%u\n",
8612 WLAN_MODULE_NAME,
8613 (int)versionReported.major,
8614 (int)versionReported.minor,
8615 (int)versionReported.version,
8616 (int)versionReported.revision,
8617 (int)versionCompiled.major,
8618 (int)versionCompiled.minor,
8619 (int)versionCompiled.version,
8620 (int)versionCompiled.revision);
8621 }
8622 else
8623 {
8624 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8625 WLAN_MODULE_NAME,
8626 (int)versionReported.major,
8627 (int)versionReported.minor,
8628 (int)versionReported.version,
8629 (int)versionReported.revision);
8630 }
8631
8632 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8633 versionString,
8634 sizeof(versionString));
8635 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8636 {
8637 hddLog(VOS_TRACE_LEVEL_FATAL,
8638 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008639 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008640 break;
8641 }
8642
8643 pr_info("%s: WCNSS software version %s\n",
8644 WLAN_MODULE_NAME, versionString);
8645
8646 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8647 versionString,
8648 sizeof(versionString));
8649 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8650 {
8651 hddLog(VOS_TRACE_LEVEL_FATAL,
8652 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008653 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008654 break;
8655 }
8656
8657 pr_info("%s: WCNSS hardware version %s\n",
8658 WLAN_MODULE_NAME, versionString);
8659
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008660 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8661 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008662 send the message only if it the riva is 1.1
8663 minor numbers for different riva branches:
8664 0 -> (1.0)Mainline Build
8665 1 -> (1.1)Mainline Build
8666 2->(1.04) Stability Build
8667 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008668 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008669 ((versionReported.minor>=1) && (versionReported.version>=1)))
8670 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8671 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008672
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008673 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008674 {
8675#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8676 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8677 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8678#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008679 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8680 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8681 {
8682 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8683 }
8684
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008685 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008686 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008687
8688 } while (0);
8689
8690}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308691void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8692{
8693 struct sk_buff *skb;
8694 struct nlmsghdr *nlh;
8695 tAniMsgHdr *ani_hdr;
8696
8697 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8698
8699 if(skb == NULL) {
8700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8701 "%s: alloc_skb failed", __func__);
8702 return;
8703 }
8704
8705 nlh = (struct nlmsghdr *)skb->data;
8706 nlh->nlmsg_pid = 0; /* from kernel */
8707 nlh->nlmsg_flags = 0;
8708 nlh->nlmsg_seq = 0;
8709 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8710
8711 ani_hdr = NLMSG_DATA(nlh);
8712 ani_hdr->type = type;
8713
8714 switch(type) {
8715 case WLAN_SVC_SAP_RESTART_IND:
8716 ani_hdr->length = 0;
8717 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8718 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8719 break;
8720 default:
8721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8722 "Attempt to send unknown nlink message %d", type);
8723 kfree_skb(skb);
8724 return;
8725 }
8726
8727 nl_srv_bcast(skb);
8728
8729 return;
8730}
8731
8732
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008733
8734/**---------------------------------------------------------------------------
8735
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308736 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8737
8738 \param - pHddCtx - Pointer to the hdd context
8739
8740 \return - true if hardware supports 5GHz
8741
8742 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308743boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308744{
8745 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8746 * then hardware support 5Ghz.
8747 */
8748 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8749 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308750 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308751 return true;
8752 }
8753 else
8754 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308755 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308756 __func__);
8757 return false;
8758 }
8759}
8760
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308761/**---------------------------------------------------------------------------
8762
8763 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8764 generate function
8765
8766 This is generate the random mac address for WLAN interface
8767
8768 \param - pHddCtx - Pointer to HDD context
8769 idx - Start interface index to get auto
8770 generated mac addr.
8771 mac_addr - Mac address
8772
8773 \return - 0 for success, < 0 for failure
8774
8775 --------------------------------------------------------------------------*/
8776
8777static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8778 int idx, v_MACADDR_t mac_addr)
8779{
8780 int i;
8781 unsigned int serialno;
8782 serialno = wcnss_get_serial_number();
8783
8784 if (0 != serialno)
8785 {
8786 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8787 bytes of the serial number that can be used to generate
8788 the other 3 bytes of the MAC address. Mask off all but
8789 the lower 3 bytes (this will also make sure we don't
8790 overflow in the next step) */
8791 serialno &= 0x00FFFFFF;
8792
8793 /* we need a unique address for each session */
8794 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8795
8796 /* autogen other Mac addresses */
8797 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8798 {
8799 /* start with the entire default address */
8800 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8801 /* then replace the lower 3 bytes */
8802 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8803 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8804 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8805
8806 serialno++;
8807 hddLog(VOS_TRACE_LEVEL_ERROR,
8808 "%s: Derived Mac Addr: "
8809 MAC_ADDRESS_STR, __func__,
8810 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8811 }
8812
8813 }
8814 else
8815 {
8816 hddLog(LOGE, FL("Failed to Get Serial NO"));
8817 return -1;
8818 }
8819 return 0;
8820}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308821
8822/**---------------------------------------------------------------------------
8823
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308824 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8825 completed to flush out the scan results
8826
8827 11d scan is done during driver load and is a passive scan on all
8828 channels supported by the device, 11d scans may find some APs on
8829 frequencies which are forbidden to be used in the regulatory domain
8830 the device is operating in. If these APs are notified to the supplicant
8831 it may try to connect to these APs, thus flush out all the scan results
8832 which are present in SME after 11d scan is done.
8833
8834 \return - eHalStatus
8835
8836 --------------------------------------------------------------------------*/
8837static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8838 tANI_U32 scanId, eCsrScanStatus status)
8839{
8840 ENTER();
8841
8842 sme_ScanFlushResult(halHandle, 0);
8843
8844 EXIT();
8845
8846 return eHAL_STATUS_SUCCESS;
8847}
8848
8849/**---------------------------------------------------------------------------
8850
Jeff Johnson295189b2012-06-20 16:38:30 -07008851 \brief hdd_wlan_startup() - HDD init function
8852
8853 This is the driver startup code executed once a WLAN device has been detected
8854
8855 \param - dev - Pointer to the underlying device
8856
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008857 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008858
8859 --------------------------------------------------------------------------*/
8860
8861int hdd_wlan_startup(struct device *dev )
8862{
8863 VOS_STATUS status;
8864 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008865 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008866 hdd_context_t *pHddCtx = NULL;
8867 v_CONTEXT_t pVosContext= NULL;
8868#ifdef WLAN_BTAMP_FEATURE
8869 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8870 WLANBAP_ConfigType btAmpConfig;
8871 hdd_config_t *pConfig;
8872#endif
8873 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008874 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308875 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008876
8877 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 /*
8879 * cfg80211: wiphy allocation
8880 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308881 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008882
8883 if(wiphy == NULL)
8884 {
8885 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008886 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008887 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008888 pHddCtx = wiphy_priv(wiphy);
8889
Jeff Johnson295189b2012-06-20 16:38:30 -07008890 //Initialize the adapter context to zeros.
8891 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8892
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308895 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008896
8897 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8898
8899 /*Get vos context here bcoz vos_open requires it*/
8900 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8901
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008902 if(pVosContext == NULL)
8903 {
8904 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8905 goto err_free_hdd_context;
8906 }
8907
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 //Save the Global VOSS context in adapter context for future.
8909 pHddCtx->pvosContext = pVosContext;
8910
8911 //Save the adapter context in global context for future.
8912 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8913
Jeff Johnson295189b2012-06-20 16:38:30 -07008914 pHddCtx->parent_dev = dev;
8915
8916 init_completion(&pHddCtx->full_pwr_comp_var);
8917 init_completion(&pHddCtx->standby_comp_var);
8918 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008919 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008920 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308921 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308922 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008923
8924#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008925 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008926#else
8927 init_completion(&pHddCtx->driver_crda_req);
8928#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008929
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308930 spin_lock_init(&pHddCtx->schedScan_lock);
8931
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8933
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308934#ifdef FEATURE_WLAN_TDLS
8935 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8936 * invoked by other instances also) to protect the concurrent
8937 * access for the Adapters by TDLS module.
8938 */
8939 mutex_init(&pHddCtx->tdls_lock);
8940#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05308941 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Agarwal Ashish1f422872014-07-22 00:11:55 +05308942 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308943
Agarwal Ashish1f422872014-07-22 00:11:55 +05308944 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 // Load all config first as TL config is needed during vos_open
8946 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8947 if(pHddCtx->cfg_ini == NULL)
8948 {
8949 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8950 goto err_free_hdd_context;
8951 }
8952
8953 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8954
8955 // Read and parse the qcom_cfg.ini file
8956 status = hdd_parse_config_ini( pHddCtx );
8957 if ( VOS_STATUS_SUCCESS != status )
8958 {
8959 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
8960 __func__, WLAN_INI_FILE);
8961 goto err_config;
8962 }
Arif Hussaind5218912013-12-05 01:10:55 -08008963#ifdef MEMORY_DEBUG
8964 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
8965 vos_mem_init();
8966
8967 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
8968 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
8969#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008970
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05308971 /* INI has been read, initialise the configuredMcastBcastFilter with
8972 * INI value as this will serve as the default value
8973 */
8974 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
8975 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
8976 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308977
8978 if (false == hdd_is_5g_supported(pHddCtx))
8979 {
8980 //5Ghz is not supported.
8981 if (1 != pHddCtx->cfg_ini->nBandCapability)
8982 {
8983 hddLog(VOS_TRACE_LEVEL_INFO,
8984 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
8985 pHddCtx->cfg_ini->nBandCapability = 1;
8986 }
8987 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05308988
8989 /* If SNR Monitoring is enabled, FW has to parse all beacons
8990 * for calcaluting and storing the average SNR, so set Nth beacon
8991 * filter to 1 to enable FW to parse all the beaocons
8992 */
8993 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
8994 {
8995 /* The log level is deliberately set to WARN as overriding
8996 * nthBeaconFilter to 1 will increase power cosumption and this
8997 * might just prove helpful to detect the power issue.
8998 */
8999 hddLog(VOS_TRACE_LEVEL_WARN,
9000 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9001 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9002 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009003 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309004 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009006 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009007 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009008 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9009 {
9010 hddLog(VOS_TRACE_LEVEL_FATAL,
9011 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9012 goto err_config;
9013 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009015
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009016 // Update VOS trace levels based upon the cfg.ini
9017 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9018 pHddCtx->cfg_ini->vosTraceEnableBAP);
9019 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9020 pHddCtx->cfg_ini->vosTraceEnableTL);
9021 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9022 pHddCtx->cfg_ini->vosTraceEnableWDI);
9023 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9024 pHddCtx->cfg_ini->vosTraceEnableHDD);
9025 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9026 pHddCtx->cfg_ini->vosTraceEnableSME);
9027 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9028 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309029 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9030 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009031 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9032 pHddCtx->cfg_ini->vosTraceEnableWDA);
9033 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9034 pHddCtx->cfg_ini->vosTraceEnableSYS);
9035 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9036 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009037 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9038 pHddCtx->cfg_ini->vosTraceEnableSAP);
9039 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9040 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009041
Jeff Johnson295189b2012-06-20 16:38:30 -07009042 // Update WDI trace levels based upon the cfg.ini
9043 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9044 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9045 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9046 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9047 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9048 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9049 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9050 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009051
Jeff Johnson88ba7742013-02-27 14:36:02 -08009052 if (VOS_FTM_MODE == hdd_get_conparam())
9053 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009054 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9055 {
9056 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9057 goto err_free_hdd_context;
9058 }
9059 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05309060
9061 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009062 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009063 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009064
Jeff Johnson88ba7742013-02-27 14:36:02 -08009065 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009066 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9067 {
9068 status = vos_watchdog_open(pVosContext,
9069 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9070
9071 if(!VOS_IS_STATUS_SUCCESS( status ))
9072 {
9073 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309074 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009075 }
9076 }
9077
9078 pHddCtx->isLogpInProgress = FALSE;
9079 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9080
Amar Singhala49cbc52013-10-08 18:37:44 -07009081#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009082 /* initialize the NV module. This is required so that
9083 we can initialize the channel information in wiphy
9084 from the NV.bin data. The channel information in
9085 wiphy needs to be initialized before wiphy registration */
9086
9087 status = vos_nv_open();
9088 if (!VOS_IS_STATUS_SUCCESS(status))
9089 {
9090 /* NV module cannot be initialized */
9091 hddLog( VOS_TRACE_LEVEL_FATAL,
9092 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309093 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009094 }
9095
9096 status = vos_init_wiphy_from_nv_bin();
9097 if (!VOS_IS_STATUS_SUCCESS(status))
9098 {
9099 /* NV module cannot be initialized */
9100 hddLog( VOS_TRACE_LEVEL_FATAL,
9101 "%s: vos_init_wiphy failed", __func__);
9102 goto err_vos_nv_close;
9103 }
9104
Amar Singhala49cbc52013-10-08 18:37:44 -07009105#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309106#ifdef DEBUG_ROAM_DELAY
9107 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
9108#endif //#ifdef DEBUG_ROAM_DELAY
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309109 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009110 if ( !VOS_IS_STATUS_SUCCESS( status ))
9111 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009112 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309113 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009114 }
9115
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9117
9118 if ( NULL == pHddCtx->hHal )
9119 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009120 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 goto err_vosclose;
9122 }
9123
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009124 status = vos_preStart( pHddCtx->pvosContext );
9125 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9126 {
9127 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309128 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009129 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009130
Arif Hussaineaf68602013-12-30 23:10:44 -08009131 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9132 {
9133 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9134 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9135 __func__, enable_dfs_chan_scan);
9136 }
9137 if (0 == enable_11d || 1 == enable_11d)
9138 {
9139 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9140 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9141 __func__, enable_11d);
9142 }
9143
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009144 /* Note that the vos_preStart() sequence triggers the cfg download.
9145 The cfg download must occur before we update the SME config
9146 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 status = hdd_set_sme_config( pHddCtx );
9148
9149 if ( VOS_STATUS_SUCCESS != status )
9150 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009151 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309152 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009153 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009154
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 /* In the integrated architecture we update the configuration from
9156 the INI file and from NV before vOSS has been started so that
9157 the final contents are available to send down to the cCPU */
9158
9159 // Apply the cfg.ini to cfg.dat
9160 if (FALSE == hdd_update_config_dat(pHddCtx))
9161 {
9162 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309163 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009164 }
9165
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309166 // Get mac addr from platform driver
9167 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9168
9169 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009170 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309171 /* Store the mac addr for first interface */
9172 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9173
9174 hddLog(VOS_TRACE_LEVEL_ERROR,
9175 "%s: WLAN Mac Addr: "
9176 MAC_ADDRESS_STR, __func__,
9177 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9178
9179 /* Here, passing Arg2 as 1 because we do not want to change the
9180 last 3 bytes (means non OUI bytes) of first interface mac
9181 addr.
9182 */
9183 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9184 {
9185 hddLog(VOS_TRACE_LEVEL_ERROR,
9186 "%s: Failed to generate wlan interface mac addr "
9187 "using MAC from ini file ", __func__);
9188 }
9189 }
9190 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9191 {
9192 // Apply the NV to cfg.dat
9193 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009194#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9195 /* There was not a valid set of MAC Addresses in NV. See if the
9196 default addresses were modified by the cfg.ini settings. If so,
9197 we'll use them, but if not, we'll autogenerate a set of MAC
9198 addresses based upon the device serial number */
9199
9200 static const v_MACADDR_t default_address =
9201 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009202
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309203 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9204 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 {
9206 /* cfg.ini has the default address, invoke autogen logic */
9207
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309208 /* Here, passing Arg2 as 0 because we want to change the
9209 last 3 bytes (means non OUI bytes) of all the interfaces
9210 mac addr.
9211 */
9212 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9213 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009214 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309215 hddLog(VOS_TRACE_LEVEL_ERROR,
9216 "%s: Failed to generate wlan interface mac addr "
9217 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9218 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009219 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 }
9221 else
9222#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9223 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009224 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 "%s: Invalid MAC address in NV, using MAC from ini file "
9226 MAC_ADDRESS_STR, __func__,
9227 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9228 }
9229 }
9230 {
9231 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309232
9233 /* Set the MAC Address Currently this is used by HAL to
9234 * add self sta. Remove this once self sta is added as
9235 * part of session open.
9236 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009237 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9238 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9239 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309240
Jeff Johnson295189b2012-06-20 16:38:30 -07009241 if (!HAL_STATUS_SUCCESS( halStatus ))
9242 {
9243 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9244 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309245 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009246 }
9247 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009248
9249 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9250 Note: Firmware image will be read and downloaded inside vos_start API */
9251 status = vos_start( pHddCtx->pvosContext );
9252 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9253 {
9254 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309255 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 }
9257
Leo Chang6cec3e22014-01-21 15:33:49 -08009258#ifdef FEATURE_WLAN_CH_AVOID
9259 /* Plug in avoid channel notification callback
9260 * This should happen before ADD_SELF_STA
9261 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309262
9263 /* check the Channel Avoidance is enabled */
9264 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9265 {
9266 sme_AddChAvoidCallback(pHddCtx->hHal,
9267 hdd_hostapd_ch_avoid_cb);
9268 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009269#endif /* FEATURE_WLAN_CH_AVOID */
9270
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009271 /* Exchange capability info between Host and FW and also get versioning info from FW */
9272 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009273
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309274#ifdef CONFIG_ENABLE_LINUX_REG
9275 status = wlan_hdd_init_channels(pHddCtx);
9276 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9277 {
9278 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9279 __func__);
9280 goto err_vosstop;
9281 }
9282#endif
9283
Jeff Johnson295189b2012-06-20 16:38:30 -07009284 status = hdd_post_voss_start_config( pHddCtx );
9285 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9286 {
9287 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9288 __func__);
9289 goto err_vosstop;
9290 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009291
9292#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309293 wlan_hdd_cfg80211_update_reg_info( wiphy );
9294
9295 /* registration of wiphy dev with cfg80211 */
9296 if (0 > wlan_hdd_cfg80211_register(wiphy))
9297 {
9298 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9299 goto err_vosstop;
9300 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009301#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009302
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309303#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309304 /* registration of wiphy dev with cfg80211 */
9305 if (0 > wlan_hdd_cfg80211_register(wiphy))
9306 {
9307 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9308 goto err_vosstop;
9309 }
9310
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309311 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309312 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9313 {
9314 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9315 __func__);
9316 goto err_unregister_wiphy;
9317 }
9318#endif
9319
c_hpothu4a298be2014-12-22 21:12:51 +05309320 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9321
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9323 {
9324 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9325 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9326 }
9327 else
9328 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009329 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9330 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9331 if (pAdapter != NULL)
9332 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309333 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309335 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9336 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9337 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009338
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309339 /* Generate the P2P Device Address. This consists of the device's
9340 * primary MAC address with the locally administered bit set.
9341 */
9342 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009343 }
9344 else
9345 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309346 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9347 if (p2p_dev_addr != NULL)
9348 {
9349 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9350 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9351 }
9352 else
9353 {
9354 hddLog(VOS_TRACE_LEVEL_FATAL,
9355 "%s: Failed to allocate mac_address for p2p_device",
9356 __func__);
9357 goto err_close_adapter;
9358 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009359 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009360
9361 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9362 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9363 if ( NULL == pP2pAdapter )
9364 {
9365 hddLog(VOS_TRACE_LEVEL_FATAL,
9366 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009367 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009368 goto err_close_adapter;
9369 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009371 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009372
9373 if( pAdapter == NULL )
9374 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009375 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9376 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009378
Arif Hussain66559122013-11-21 10:11:40 -08009379 if (country_code)
9380 {
9381 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009382 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009383 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9384#ifndef CONFIG_ENABLE_LINUX_REG
9385 hdd_checkandupdate_phymode(pAdapter, country_code);
9386#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009387 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9388 (void *)(tSmeChangeCountryCallback)
9389 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009390 country_code,
9391 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309392 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009393 if (eHAL_STATUS_SUCCESS == ret)
9394 {
Arif Hussaincb607082013-12-20 11:57:42 -08009395 ret = wait_for_completion_interruptible_timeout(
9396 &pAdapter->change_country_code,
9397 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9398
9399 if (0 >= ret)
9400 {
9401 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9402 "%s: SME while setting country code timed out", __func__);
9403 }
Arif Hussain66559122013-11-21 10:11:40 -08009404 }
9405 else
9406 {
Arif Hussaincb607082013-12-20 11:57:42 -08009407 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9408 "%s: SME Change Country code from module param fail ret=%d",
9409 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009410 }
9411 }
9412
Jeff Johnson295189b2012-06-20 16:38:30 -07009413#ifdef WLAN_BTAMP_FEATURE
9414 vStatus = WLANBAP_Open(pVosContext);
9415 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9416 {
9417 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9418 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009419 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 }
9421
9422 vStatus = BSL_Init(pVosContext);
9423 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9424 {
9425 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9426 "%s: Failed to Init BSL",__func__);
9427 goto err_bap_close;
9428 }
9429 vStatus = WLANBAP_Start(pVosContext);
9430 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9431 {
9432 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9433 "%s: Failed to start TL",__func__);
9434 goto err_bap_close;
9435 }
9436
9437 pConfig = pHddCtx->cfg_ini;
9438 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9439 status = WLANBAP_SetConfig(&btAmpConfig);
9440
9441#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009442
Mihir Shete9c238772014-10-15 14:35:16 +05309443 /*
9444 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9445 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9446 * which is greater than 0xf. So the below check is safe to make
9447 * sure that there is no entry for UapsdMask in the ini
9448 */
9449 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9450 {
9451 if(IS_DYNAMIC_WMM_PS_ENABLED)
9452 {
9453 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9454 __func__);
9455 pHddCtx->cfg_ini->UapsdMask =
9456 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9457 }
9458 else
9459 {
9460 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9461 __func__);
9462 pHddCtx->cfg_ini->UapsdMask =
9463 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9464 }
9465 }
9466
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009467#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9468 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9469 {
9470 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9471 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9472 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9473 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9474 }
9475#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009476
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309477 wlan_hdd_tdls_init(pHddCtx);
9478
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309479 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9480
Jeff Johnson295189b2012-06-20 16:38:30 -07009481 /* Register with platform driver as client for Suspend/Resume */
9482 status = hddRegisterPmOps(pHddCtx);
9483 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9484 {
9485 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9486#ifdef WLAN_BTAMP_FEATURE
9487 goto err_bap_stop;
9488#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009489 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009490#endif //WLAN_BTAMP_FEATURE
9491 }
9492
Yue Ma0d4891e2013-08-06 17:01:45 -07009493 /* Open debugfs interface */
9494 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9495 {
9496 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9497 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009498 }
9499
Jeff Johnson295189b2012-06-20 16:38:30 -07009500 /* Register TM level change handler function to the platform */
9501 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9502 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9503 {
9504 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9505 goto err_unregister_pmops;
9506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009507
9508 /* register for riva power on lock to platform driver */
9509 if (req_riva_power_on_lock("wlan"))
9510 {
9511 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9512 __func__);
9513 goto err_unregister_pmops;
9514 }
9515
Jeff Johnson295189b2012-06-20 16:38:30 -07009516 // register net device notifier for device change notification
9517 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9518
9519 if(ret < 0)
9520 {
9521 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9522 goto err_free_power_on_lock;
9523 }
9524
9525 //Initialize the nlink service
9526 if(nl_srv_init() != 0)
9527 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309528 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 goto err_reg_netdev;
9530 }
9531
Leo Chang4ce1cc52013-10-21 18:27:15 -07009532#ifdef WLAN_KD_READY_NOTIFIER
9533 pHddCtx->kd_nl_init = 1;
9534#endif /* WLAN_KD_READY_NOTIFIER */
9535
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 //Initialize the BTC service
9537 if(btc_activate_service(pHddCtx) != 0)
9538 {
9539 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9540 goto err_nl_srv;
9541 }
9542
9543#ifdef PTT_SOCK_SVC_ENABLE
9544 //Initialize the PTT service
9545 if(ptt_sock_activate_svc(pHddCtx) != 0)
9546 {
9547 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9548 goto err_nl_srv;
9549 }
9550#endif
9551
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309552#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9553 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9554 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309555 if(wlan_logging_sock_activate_svc(
9556 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9557 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9558 {
9559 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9560 " failed", __func__);
9561 goto err_nl_srv;
9562 }
9563 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9564 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309565 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9566 pHddCtx->cfg_ini->gEnableDebugLog =
9567 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309568 }
9569#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009573 /* Action frame registered in one adapter which will
9574 * applicable to all interfaces
9575 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309576 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009578
9579 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309580 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009581
Jeff Johnson295189b2012-06-20 16:38:30 -07009582
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009583#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009584#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9585 /* Initialize the wake lcok */
9586 wake_lock_init(&pHddCtx->rx_wake_lock,
9587 WAKE_LOCK_SUSPEND,
9588 "qcom_rx_wakelock");
9589#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009590 /* Initialize the wake lcok */
9591 wake_lock_init(&pHddCtx->sap_wake_lock,
9592 WAKE_LOCK_SUSPEND,
9593 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009594#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009595
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009596 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9597 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009598
Katya Nigam5c306ea2014-06-19 15:39:54 +05309599 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9601 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309602
9603#ifdef FEATURE_WLAN_SCAN_PNO
9604 /*SME must send channel update configuration to RIVA*/
9605 sme_UpdateChannelConfig(pHddCtx->hHal);
9606#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309607 /* Send the update default channel list to the FW*/
9608 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309609#ifndef CONFIG_ENABLE_LINUX_REG
9610 /*updating wiphy so that regulatory user hints can be processed*/
9611 if (wiphy)
9612 {
9613 regulatory_hint(wiphy, "00");
9614 }
9615#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009616 // Initialize the restart logic
9617 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309618
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009619 //Register the traffic monitor timer now
9620 if ( pHddCtx->cfg_ini->dynSplitscan)
9621 {
9622 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9623 VOS_TIMER_TYPE_SW,
9624 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9625 (void *)pHddCtx);
9626 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309627#ifdef WLAN_FEATURE_EXTSCAN
9628 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9629 wlan_hdd_cfg80211_extscan_callback,
9630 pHddCtx);
9631#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309632
9633#ifdef WLAN_NS_OFFLOAD
9634 // Register IPv6 notifier to notify if any change in IP
9635 // So that we can reconfigure the offload parameters
9636 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
9637 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
9638 if (ret)
9639 {
9640 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
9641 }
9642 else
9643 {
9644 hddLog(LOGE, FL("Registered IPv6 notifier"));
9645 }
9646#endif
9647
9648 // Register IPv4 notifier to notify if any change in IP
9649 // So that we can reconfigure the offload parameters
9650 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
9651 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
9652 if (ret)
9653 {
9654 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
9655 }
9656 else
9657 {
9658 hddLog(LOGE, FL("Registered IPv4 notifier"));
9659 }
9660
Jeff Johnson295189b2012-06-20 16:38:30 -07009661 goto success;
9662
9663err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009664#ifdef WLAN_KD_READY_NOTIFIER
9665 nl_srv_exit(pHddCtx->ptt_pid);
9666#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009668#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009669err_reg_netdev:
9670 unregister_netdevice_notifier(&hdd_netdev_notifier);
9671
9672err_free_power_on_lock:
9673 free_riva_power_on_lock("wlan");
9674
9675err_unregister_pmops:
9676 hddDevTmUnregisterNotifyCallback(pHddCtx);
9677 hddDeregisterPmOps(pHddCtx);
9678
Yue Ma0d4891e2013-08-06 17:01:45 -07009679 hdd_debugfs_exit(pHddCtx);
9680
Jeff Johnson295189b2012-06-20 16:38:30 -07009681#ifdef WLAN_BTAMP_FEATURE
9682err_bap_stop:
9683 WLANBAP_Stop(pVosContext);
9684#endif
9685
9686#ifdef WLAN_BTAMP_FEATURE
9687err_bap_close:
9688 WLANBAP_Close(pVosContext);
9689#endif
9690
Jeff Johnson295189b2012-06-20 16:38:30 -07009691err_close_adapter:
9692 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309693#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309694err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309695#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309696 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009697err_vosstop:
9698 vos_stop(pVosContext);
9699
Amar Singhala49cbc52013-10-08 18:37:44 -07009700err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 status = vos_sched_close( pVosContext );
9702 if (!VOS_IS_STATUS_SUCCESS(status)) {
9703 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9704 "%s: Failed to close VOSS Scheduler", __func__);
9705 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9706 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009707 vos_close(pVosContext );
9708
Amar Singhal0a402232013-10-11 20:57:16 -07009709err_vos_nv_close:
9710
c_hpothue6a36282014-03-19 12:27:38 +05309711#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009712 vos_nv_close();
9713
c_hpothu70f8d812014-03-22 22:59:23 +05309714#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009715
9716err_wdclose:
9717 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9718 vos_watchdog_close(pVosContext);
9719
Jeff Johnson295189b2012-06-20 16:38:30 -07009720err_config:
9721 kfree(pHddCtx->cfg_ini);
9722 pHddCtx->cfg_ini= NULL;
9723
9724err_free_hdd_context:
9725 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009726 wiphy_free(wiphy) ;
9727 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 VOS_BUG(1);
9729
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009730 if (hdd_is_ssr_required())
9731 {
9732 /* WDI timeout had happened during load, so SSR is needed here */
9733 subsystem_restart("wcnss");
9734 msleep(5000);
9735 }
9736 hdd_set_ssr_required (VOS_FALSE);
9737
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009738 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009739
9740success:
9741 EXIT();
9742 return 0;
9743}
9744
9745/**---------------------------------------------------------------------------
9746
Jeff Johnson32d95a32012-09-10 13:15:23 -07009747 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009748
Jeff Johnson32d95a32012-09-10 13:15:23 -07009749 This is the driver entry point - called in different timeline depending
9750 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009751
9752 \param - None
9753
9754 \return - 0 for success, non zero for failure
9755
9756 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009757static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009758{
9759 VOS_STATUS status;
9760 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 struct device *dev = NULL;
9762 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009763#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9764 int max_retries = 0;
9765#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009766
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309767#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9768 wlan_logging_sock_init_svc();
9769#endif
9770
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 ENTER();
9772
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009773#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009775#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009776
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309777 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9779 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9780
Jeff Johnson295189b2012-06-20 16:38:30 -07009781#ifdef ANI_BUS_TYPE_PCI
9782
9783 dev = wcnss_wlan_get_device();
9784
9785#endif // ANI_BUS_TYPE_PCI
9786
9787#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009788
9789#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9790 /* wait until WCNSS driver downloads NV */
9791 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9792 msleep(1000);
9793 }
9794 if (max_retries >= 5) {
9795 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309796#ifdef WLAN_OPEN_SOURCE
9797 wake_lock_destroy(&wlan_wake_lock);
9798#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309799
9800#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9801 wlan_logging_sock_deinit_svc();
9802#endif
9803
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009804 return -ENODEV;
9805 }
9806#endif
9807
Jeff Johnson295189b2012-06-20 16:38:30 -07009808 dev = wcnss_wlan_get_device();
9809#endif // ANI_BUS_TYPE_PLATFORM
9810
9811
9812 do {
9813 if (NULL == dev) {
9814 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9815 ret_status = -1;
9816 break;
9817 }
9818
Jeff Johnson295189b2012-06-20 16:38:30 -07009819#ifdef TIMER_MANAGER
9820 vos_timer_manager_init();
9821#endif
9822
9823 /* Preopen VOSS so that it is ready to start at least SAL */
9824 status = vos_preOpen(&pVosContext);
9825
9826 if (!VOS_IS_STATUS_SUCCESS(status))
9827 {
9828 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9829 ret_status = -1;
9830 break;
9831 }
9832
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009833#ifndef MODULE
9834 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9835 */
9836 hdd_set_conparam((v_UINT_t)con_mode);
9837#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009838
9839 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009840 if (hdd_wlan_startup(dev))
9841 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009843 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009844 vos_preClose( &pVosContext );
9845 ret_status = -1;
9846 break;
9847 }
9848
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 } while (0);
9850
9851 if (0 != ret_status)
9852 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009853#ifdef TIMER_MANAGER
9854 vos_timer_exit();
9855#endif
9856#ifdef MEMORY_DEBUG
9857 vos_mem_exit();
9858#endif
9859
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009860#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009862#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309863
9864#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9865 wlan_logging_sock_deinit_svc();
9866#endif
9867
Jeff Johnson295189b2012-06-20 16:38:30 -07009868 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9869 }
9870 else
9871 {
9872 //Send WLAN UP indication to Nlink Service
9873 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9874
9875 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 }
9877
9878 EXIT();
9879
9880 return ret_status;
9881}
9882
Jeff Johnson32d95a32012-09-10 13:15:23 -07009883/**---------------------------------------------------------------------------
9884
9885 \brief hdd_module_init() - Init Function
9886
9887 This is the driver entry point (invoked when module is loaded using insmod)
9888
9889 \param - None
9890
9891 \return - 0 for success, non zero for failure
9892
9893 --------------------------------------------------------------------------*/
9894#ifdef MODULE
9895static int __init hdd_module_init ( void)
9896{
9897 return hdd_driver_init();
9898}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009899#else /* #ifdef MODULE */
9900static int __init hdd_module_init ( void)
9901{
9902 /* Driver initialization is delayed to fwpath_changed_handler */
9903 return 0;
9904}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009905#endif /* #ifdef MODULE */
9906
Jeff Johnson295189b2012-06-20 16:38:30 -07009907
9908/**---------------------------------------------------------------------------
9909
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009910 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009911
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009912 This is the driver exit point (invoked when module is unloaded using rmmod
9913 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009914
9915 \param - None
9916
9917 \return - None
9918
9919 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009920static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009921{
9922 hdd_context_t *pHddCtx = NULL;
9923 v_CONTEXT_t pVosContext = NULL;
Siddharth Bhala204f572015-01-17 02:03:36 +05309924 pVosWatchdogContext pVosWDCtx = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309925 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309926 unsigned long rc = 0;
Siddharth Bhala204f572015-01-17 02:03:36 +05309927 unsigned long flags;
Jeff Johnson295189b2012-06-20 16:38:30 -07009928
9929 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9930
9931 //Get the global vos context
9932 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9933
9934 if(!pVosContext)
9935 {
9936 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9937 goto done;
9938 }
9939
9940 //Get the HDD context.
9941 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9942
9943 if(!pHddCtx)
9944 {
9945 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9946 }
9947 else
9948 {
Siddharth Bhala204f572015-01-17 02:03:36 +05309949 pVosWDCtx = get_vos_watchdog_ctxt();
9950 if(pVosWDCtx == NULL)
9951 {
9952 hddLog(VOS_TRACE_LEVEL_ERROR, FL("WD context is invalid"));
9953 goto done;
9954 }
Mahesh A Saptasagard477b092015-02-06 15:12:16 +05309955 rtnl_lock();
9956 hdd_nullify_netdev_ops(pHddCtx);
9957 rtnl_unlock();
Siddharth Bhala204f572015-01-17 02:03:36 +05309958 spin_lock_irqsave(&pVosWDCtx->wdLock, flags);
9959 if (!pHddCtx->isLogpInProgress || (TRUE ==
9960 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
9961 {
9962 //SSR isn't in progress OR last wlan reinit wasn't successful
9963 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
9964 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9965 spin_unlock_irqrestore(&pVosWDCtx->wdLock, flags);
9966 }
9967 else
9968 {
9969 INIT_COMPLETION(pHddCtx->ssr_comp_var);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309970
Siddharth Bhala204f572015-01-17 02:03:36 +05309971 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
9972 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
9973 spin_unlock_irqrestore(&pVosWDCtx->wdLock, flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07009974
Siddharth Bhala204f572015-01-17 02:03:36 +05309975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9976 "%s:SSR is in Progress; block rmmod !!!", __func__);
9977 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
9978 msecs_to_jiffies(30000));
9979 if(!rc)
9980 {
9981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9982 "%s:SSR timedout, fatal error", __func__);
9983 VOS_BUG(0);
9984 }
9985 }
9986
9987 /* We wait for active entry threads to exit from driver
9988 * by waiting until rtnl_lock is available.
9989 */
9990 rtnl_lock();
9991 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -07009992
c_hpothu8adb97b2014-12-08 19:38:20 +05309993 /* Driver Need to send country code 00 in below condition
9994 * 1) If gCountryCodePriority is set to 1; and last country
9995 * code set is through 11d. This needs to be done in case
9996 * when NV country code is 00.
9997 * This Needs to be done as when kernel store last country
9998 * code and if stored country code is not through 11d,
9999 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10000 * in next load/unload as soon as we get any country through
10001 * 11d. In sme_HandleChangeCountryCodeByUser
10002 * pMsg->countryCode will be last countryCode and
10003 * pMac->scan.countryCode11d will be country through 11d so
10004 * due to mismatch driver will disable 11d.
10005 *
10006 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010007
c_hpothu8adb97b2014-12-08 19:38:20 +053010008 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010009 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010010 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010011 {
10012 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010013 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010014 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10015 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010016
c_hpothu8adb97b2014-12-08 19:38:20 +053010017 //Do all the cleanup before deregistering the driver
10018 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010019 }
10020
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 vos_preClose( &pVosContext );
10022
10023#ifdef TIMER_MANAGER
10024 vos_timer_exit();
10025#endif
10026#ifdef MEMORY_DEBUG
10027 vos_mem_exit();
10028#endif
10029
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010030#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10031 wlan_logging_sock_deinit_svc();
10032#endif
10033
Jeff Johnson295189b2012-06-20 16:38:30 -070010034done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010035#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010036 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010037#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010038
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10040}
10041
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010042/**---------------------------------------------------------------------------
10043
10044 \brief hdd_module_exit() - Exit function
10045
10046 This is the driver exit point (invoked when module is unloaded using rmmod)
10047
10048 \param - None
10049
10050 \return - None
10051
10052 --------------------------------------------------------------------------*/
10053static void __exit hdd_module_exit(void)
10054{
10055 hdd_driver_exit();
10056}
10057
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010058#ifdef MODULE
10059static int fwpath_changed_handler(const char *kmessage,
10060 struct kernel_param *kp)
10061{
Jeff Johnson76052702013-04-16 13:55:05 -070010062 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010063}
10064
10065static int con_mode_handler(const char *kmessage,
10066 struct kernel_param *kp)
10067{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010068 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010069}
10070#else /* #ifdef MODULE */
10071/**---------------------------------------------------------------------------
10072
Jeff Johnson76052702013-04-16 13:55:05 -070010073 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010074
Jeff Johnson76052702013-04-16 13:55:05 -070010075 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010076 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010077 - invoked when module parameter fwpath is modified from userspace to signal
10078 initializing the WLAN driver or when con_mode is modified from userspace
10079 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010080
10081 \return - 0 for success, non zero for failure
10082
10083 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010084static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010085{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010086 int ret_status;
10087
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010088 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010089 ret_status = hdd_driver_init();
10090 wlan_hdd_inited = ret_status ? 0 : 1;
10091 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010092 }
10093
10094 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010095
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010096 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010097
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010098 ret_status = hdd_driver_init();
10099 wlan_hdd_inited = ret_status ? 0 : 1;
10100 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010101}
10102
Jeff Johnson295189b2012-06-20 16:38:30 -070010103/**---------------------------------------------------------------------------
10104
Jeff Johnson76052702013-04-16 13:55:05 -070010105 \brief fwpath_changed_handler() - Handler Function
10106
10107 Handle changes to the fwpath parameter
10108
10109 \return - 0 for success, non zero for failure
10110
10111 --------------------------------------------------------------------------*/
10112static int fwpath_changed_handler(const char *kmessage,
10113 struct kernel_param *kp)
10114{
10115 int ret;
10116
10117 ret = param_set_copystring(kmessage, kp);
10118 if (0 == ret)
10119 ret = kickstart_driver();
10120 return ret;
10121}
10122
10123/**---------------------------------------------------------------------------
10124
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010125 \brief con_mode_handler() -
10126
10127 Handler function for module param con_mode when it is changed by userspace
10128 Dynamically linked - do nothing
10129 Statically linked - exit and init driver, as in rmmod and insmod
10130
Jeff Johnson76052702013-04-16 13:55:05 -070010131 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010132
Jeff Johnson76052702013-04-16 13:55:05 -070010133 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010134
10135 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010136static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010137{
Jeff Johnson76052702013-04-16 13:55:05 -070010138 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010139
Jeff Johnson76052702013-04-16 13:55:05 -070010140 ret = param_set_int(kmessage, kp);
10141 if (0 == ret)
10142 ret = kickstart_driver();
10143 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010144}
10145#endif /* #ifdef MODULE */
10146
10147/**---------------------------------------------------------------------------
10148
Jeff Johnson295189b2012-06-20 16:38:30 -070010149 \brief hdd_get_conparam() -
10150
10151 This is the driver exit point (invoked when module is unloaded using rmmod)
10152
10153 \param - None
10154
10155 \return - tVOS_CON_MODE
10156
10157 --------------------------------------------------------------------------*/
10158tVOS_CON_MODE hdd_get_conparam ( void )
10159{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010160#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010161 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010162#else
10163 return (tVOS_CON_MODE)curr_con_mode;
10164#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010165}
10166void hdd_set_conparam ( v_UINT_t newParam )
10167{
10168 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010169#ifndef MODULE
10170 curr_con_mode = con_mode;
10171#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010172}
10173/**---------------------------------------------------------------------------
10174
10175 \brief hdd_softap_sta_deauth() - function
10176
10177 This to take counter measure to handle deauth req from HDD
10178
10179 \param - pAdapter - Pointer to the HDD
10180
10181 \param - enable - boolean value
10182
10183 \return - None
10184
10185 --------------------------------------------------------------------------*/
10186
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010187VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10188 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010189{
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010191 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010192
10193 ENTER();
10194
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010195 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10196 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010197
10198 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010199 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010200 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010201
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010202 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010203
10204 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010205 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010206}
10207
10208/**---------------------------------------------------------------------------
10209
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010210 \brief hdd_del_all_sta() - function
10211
10212 This function removes all the stations associated on stopping AP/P2P GO.
10213
10214 \param - pAdapter - Pointer to the HDD
10215
10216 \return - None
10217
10218 --------------------------------------------------------------------------*/
10219
10220int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10221{
10222 v_U16_t i;
10223 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010224 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10225 ptSapContext pSapCtx = NULL;
10226 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10227 if(pSapCtx == NULL){
10228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10229 FL("psapCtx is NULL"));
10230 return 1;
10231 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010232 ENTER();
10233
10234 hddLog(VOS_TRACE_LEVEL_INFO,
10235 "%s: Delete all STAs associated.",__func__);
10236 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10237 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10238 )
10239 {
10240 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10241 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010242 if ((pSapCtx->aStaInfo[i].isUsed) &&
10243 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010244 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010245 struct tagCsrDelStaParams delStaParams;
10246
10247 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010248 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010249 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10250 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010251 &delStaParams);
10252 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010253 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010254 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010255 }
10256 }
10257 }
10258
10259 EXIT();
10260 return 0;
10261}
10262
10263/**---------------------------------------------------------------------------
10264
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 \brief hdd_softap_sta_disassoc() - function
10266
10267 This to take counter measure to handle deauth req from HDD
10268
10269 \param - pAdapter - Pointer to the HDD
10270
10271 \param - enable - boolean value
10272
10273 \return - None
10274
10275 --------------------------------------------------------------------------*/
10276
10277void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10278{
10279 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10280
10281 ENTER();
10282
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010283 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010284
10285 //Ignore request to disassoc bcmc station
10286 if( pDestMacAddress[0] & 0x1 )
10287 return;
10288
10289 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10290}
10291
10292void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10293{
10294 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10295
10296 ENTER();
10297
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010298 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010299
10300 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10301}
10302
Jeff Johnson295189b2012-06-20 16:38:30 -070010303/**---------------------------------------------------------------------------
10304 *
10305 * \brief hdd_get__concurrency_mode() -
10306 *
10307 *
10308 * \param - None
10309 *
10310 * \return - CONCURRENCY MODE
10311 *
10312 * --------------------------------------------------------------------------*/
10313tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10314{
10315 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10316 hdd_context_t *pHddCtx;
10317
10318 if (NULL != pVosContext)
10319 {
10320 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10321 if (NULL != pHddCtx)
10322 {
10323 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10324 }
10325 }
10326
10327 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010328 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010329 return VOS_STA;
10330}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010331v_BOOL_t
10332wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10333{
10334 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010335
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010336 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10337 if (pAdapter == NULL)
10338 {
10339 hddLog(VOS_TRACE_LEVEL_INFO,
10340 FL("GO doesn't exist"));
10341 return TRUE;
10342 }
10343 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10344 {
10345 hddLog(VOS_TRACE_LEVEL_INFO,
10346 FL("GO started"));
10347 return TRUE;
10348 }
10349 else
10350 /* wait till GO changes its interface to p2p device */
10351 hddLog(VOS_TRACE_LEVEL_INFO,
10352 FL("Del_bss called, avoid apps suspend"));
10353 return FALSE;
10354
10355}
Jeff Johnson295189b2012-06-20 16:38:30 -070010356/* Decide whether to allow/not the apps power collapse.
10357 * Allow apps power collapse if we are in connected state.
10358 * if not, allow only if we are in IMPS */
10359v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10360{
10361 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010362 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010363 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010364 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10365 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10366 hdd_adapter_t *pAdapter = NULL;
10367 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010368 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010369
Jeff Johnson295189b2012-06-20 16:38:30 -070010370 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10371 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010372
Yathish9f22e662012-12-10 14:21:35 -080010373 concurrent_state = hdd_get_concurrency_mode();
10374
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010375 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10376 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10377 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010378#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010379
Yathish9f22e662012-12-10 14:21:35 -080010380 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010381 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010382 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10383 return TRUE;
10384#endif
10385
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 /*loop through all adapters. TBD fix for Concurrency */
10387 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10388 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10389 {
10390 pAdapter = pAdapterNode->pAdapter;
10391 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10392 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10393 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010394 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010395 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010396 && pmcState != STOPPED && pmcState != STANDBY &&
10397 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010398 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10399 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010401 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010402 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10403 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 return FALSE;
10405 }
10406 }
10407 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10408 pAdapterNode = pNext;
10409 }
10410 return TRUE;
10411}
10412
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010413/* Decides whether to send suspend notification to Riva
10414 * if any adapter is in BMPS; then it is required */
10415v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10416{
10417 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10418 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10419
10420 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10421 {
10422 return TRUE;
10423 }
10424 return FALSE;
10425}
10426
Jeff Johnson295189b2012-06-20 16:38:30 -070010427void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10428{
10429 switch(mode)
10430 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010431 case VOS_STA_MODE:
10432 case VOS_P2P_CLIENT_MODE:
10433 case VOS_P2P_GO_MODE:
10434 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010435 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010436 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010437 break;
10438 default:
10439 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010441 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10442 "Number of open sessions for mode %d = %d"),
10443 pHddCtx->concurrency_mode, mode,
10444 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010445}
10446
10447
10448void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10449{
10450 switch(mode)
10451 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010452 case VOS_STA_MODE:
10453 case VOS_P2P_CLIENT_MODE:
10454 case VOS_P2P_GO_MODE:
10455 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010456 pHddCtx->no_of_open_sessions[mode]--;
10457 if (!(pHddCtx->no_of_open_sessions[mode]))
10458 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 break;
10460 default:
10461 break;
10462 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010463 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10464 "Number of open sessions for mode %d = %d"),
10465 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10466
10467}
10468/**---------------------------------------------------------------------------
10469 *
10470 * \brief wlan_hdd_incr_active_session()
10471 *
10472 * This function increments the number of active sessions
10473 * maintained per device mode
10474 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10475 * Incase of SAP/P2P GO upon bss start it is incremented
10476 *
10477 * \param pHddCtx - HDD Context
10478 * \param mode - device mode
10479 *
10480 * \return - None
10481 *
10482 * --------------------------------------------------------------------------*/
10483void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10484{
10485 switch (mode) {
10486 case VOS_STA_MODE:
10487 case VOS_P2P_CLIENT_MODE:
10488 case VOS_P2P_GO_MODE:
10489 case VOS_STA_SAP_MODE:
10490 pHddCtx->no_of_active_sessions[mode]++;
10491 break;
10492 default:
10493 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10494 break;
10495 }
10496 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10497 mode,
10498 pHddCtx->no_of_active_sessions[mode]);
10499}
10500
10501/**---------------------------------------------------------------------------
10502 *
10503 * \brief wlan_hdd_decr_active_session()
10504 *
10505 * This function decrements the number of active sessions
10506 * maintained per device mode
10507 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10508 * Incase of SAP/P2P GO upon bss stop it is decremented
10509 *
10510 * \param pHddCtx - HDD Context
10511 * \param mode - device mode
10512 *
10513 * \return - None
10514 *
10515 * --------------------------------------------------------------------------*/
10516void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10517{
10518 switch (mode) {
10519 case VOS_STA_MODE:
10520 case VOS_P2P_CLIENT_MODE:
10521 case VOS_P2P_GO_MODE:
10522 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010523 if (pHddCtx->no_of_active_sessions[mode] > 0)
10524 pHddCtx->no_of_active_sessions[mode]--;
10525 else
10526 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10527 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010528 break;
10529 default:
10530 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10531 break;
10532 }
10533 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10534 mode,
10535 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010536}
10537
Jeff Johnsone7245742012-09-05 17:12:55 -070010538/**---------------------------------------------------------------------------
10539 *
10540 * \brief wlan_hdd_restart_init
10541 *
10542 * This function initalizes restart timer/flag. An internal function.
10543 *
10544 * \param - pHddCtx
10545 *
10546 * \return - None
10547 *
10548 * --------------------------------------------------------------------------*/
10549
10550static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10551{
10552 /* Initialize */
10553 pHddCtx->hdd_restart_retries = 0;
10554 atomic_set(&pHddCtx->isRestartInProgress, 0);
10555 vos_timer_init(&pHddCtx->hdd_restart_timer,
10556 VOS_TIMER_TYPE_SW,
10557 wlan_hdd_restart_timer_cb,
10558 pHddCtx);
10559}
10560/**---------------------------------------------------------------------------
10561 *
10562 * \brief wlan_hdd_restart_deinit
10563 *
10564 * This function cleans up the resources used. An internal function.
10565 *
10566 * \param - pHddCtx
10567 *
10568 * \return - None
10569 *
10570 * --------------------------------------------------------------------------*/
10571
10572static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10573{
10574
10575 VOS_STATUS vos_status;
10576 /* Block any further calls */
10577 atomic_set(&pHddCtx->isRestartInProgress, 1);
10578 /* Cleanup */
10579 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10580 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010581 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010582 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10583 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010584 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010585
10586}
10587
10588/**---------------------------------------------------------------------------
10589 *
10590 * \brief wlan_hdd_framework_restart
10591 *
10592 * This function uses a cfg80211 API to start a framework initiated WLAN
10593 * driver module unload/load.
10594 *
10595 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10596 *
10597 *
10598 * \param - pHddCtx
10599 *
10600 * \return - VOS_STATUS_SUCCESS: Success
10601 * VOS_STATUS_E_EMPTY: Adapter is Empty
10602 * VOS_STATUS_E_NOMEM: No memory
10603
10604 * --------------------------------------------------------------------------*/
10605
10606static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10607{
10608 VOS_STATUS status = VOS_STATUS_SUCCESS;
10609 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010610 int len = (sizeof (struct ieee80211_mgmt));
10611 struct ieee80211_mgmt *mgmt = NULL;
10612
10613 /* Prepare the DEAUTH managment frame with reason code */
10614 mgmt = kzalloc(len, GFP_KERNEL);
10615 if(mgmt == NULL)
10616 {
10617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10618 "%s: memory allocation failed (%d bytes)", __func__, len);
10619 return VOS_STATUS_E_NOMEM;
10620 }
10621 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010622
10623 /* Iterate over all adapters/devices */
10624 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10625 do
10626 {
10627 if( (status == VOS_STATUS_SUCCESS) &&
10628 pAdapterNode &&
10629 pAdapterNode->pAdapter)
10630 {
10631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10632 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10633 pAdapterNode->pAdapter->dev->name,
10634 pAdapterNode->pAdapter->device_mode,
10635 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010636 /*
10637 * CFG80211 event to restart the driver
10638 *
10639 * 'cfg80211_send_unprot_deauth' sends a
10640 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10641 * of SME(Linux Kernel) state machine.
10642 *
10643 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10644 * the driver.
10645 *
10646 */
10647
10648 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010649 }
10650 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10651 pAdapterNode = pNext;
10652 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10653
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010654
10655 /* Free the allocated management frame */
10656 kfree(mgmt);
10657
Jeff Johnsone7245742012-09-05 17:12:55 -070010658 /* Retry until we unload or reach max count */
10659 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10660 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10661
10662 return status;
10663
10664}
10665/**---------------------------------------------------------------------------
10666 *
10667 * \brief wlan_hdd_restart_timer_cb
10668 *
10669 * Restart timer callback. An internal function.
10670 *
10671 * \param - User data:
10672 *
10673 * \return - None
10674 *
10675 * --------------------------------------------------------------------------*/
10676
10677void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10678{
10679 hdd_context_t *pHddCtx = usrDataForCallback;
10680 wlan_hdd_framework_restart(pHddCtx);
10681 return;
10682
10683}
10684
10685
10686/**---------------------------------------------------------------------------
10687 *
10688 * \brief wlan_hdd_restart_driver
10689 *
10690 * This function sends an event to supplicant to restart the WLAN driver.
10691 *
10692 * This function is called from vos_wlanRestart.
10693 *
10694 * \param - pHddCtx
10695 *
10696 * \return - VOS_STATUS_SUCCESS: Success
10697 * VOS_STATUS_E_EMPTY: Adapter is Empty
10698 * VOS_STATUS_E_ALREADY: Request already in progress
10699
10700 * --------------------------------------------------------------------------*/
10701VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10702{
10703 VOS_STATUS status = VOS_STATUS_SUCCESS;
10704
10705 /* A tight check to make sure reentrancy */
10706 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10707 {
Mihir Shetefd528652014-06-23 19:07:50 +053010708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010709 "%s: WLAN restart is already in progress", __func__);
10710
10711 return VOS_STATUS_E_ALREADY;
10712 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010713 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010714#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010715 wcnss_reset_intr();
10716#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010717
Jeff Johnsone7245742012-09-05 17:12:55 -070010718 return status;
10719}
10720
Mihir Shetee1093ba2014-01-21 20:13:32 +053010721/**---------------------------------------------------------------------------
10722 *
10723 * \brief wlan_hdd_init_channels
10724 *
10725 * This function is used to initialize the channel list in CSR
10726 *
10727 * This function is called from hdd_wlan_startup
10728 *
10729 * \param - pHddCtx: HDD context
10730 *
10731 * \return - VOS_STATUS_SUCCESS: Success
10732 * VOS_STATUS_E_FAULT: Failure reported by SME
10733
10734 * --------------------------------------------------------------------------*/
10735static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10736{
10737 eHalStatus status;
10738
10739 status = sme_InitChannels(pHddCtx->hHal);
10740 if (HAL_STATUS_SUCCESS(status))
10741 {
10742 return VOS_STATUS_SUCCESS;
10743 }
10744 else
10745 {
10746 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10747 __func__, status);
10748 return VOS_STATUS_E_FAULT;
10749 }
10750}
10751
Mihir Shete04206452014-11-20 17:50:58 +053010752#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010753VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010754{
10755 eHalStatus status;
10756
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010757 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010758 if (HAL_STATUS_SUCCESS(status))
10759 {
10760 return VOS_STATUS_SUCCESS;
10761 }
10762 else
10763 {
10764 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10765 __func__, status);
10766 return VOS_STATUS_E_FAULT;
10767 }
10768}
Mihir Shete04206452014-11-20 17:50:58 +053010769#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010770/*
10771 * API to find if there is any STA or P2P-Client is connected
10772 */
10773VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10774{
10775 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10776}
Jeff Johnsone7245742012-09-05 17:12:55 -070010777
Agarwal Ashish57e84372014-12-05 18:26:53 +053010778/*
10779 * API to find if there is any session connected
10780 */
10781VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
10782{
10783 return sme_is_any_session_connected(pHddCtx->hHal);
10784}
10785
10786
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010787int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10788{
10789 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10790 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010791 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053010792 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010793
10794 pScanInfo = &pHddCtx->scan_info;
10795 if (pScanInfo->mScanPending)
10796 {
c_hpothua3d45d52015-01-05 14:11:17 +053010797 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
10798 eCSR_SCAN_ABORT_DEFAULT);
10799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10800 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010801
c_hpothua3d45d52015-01-05 14:11:17 +053010802 /* If there is active scan command lets wait for the completion else
10803 * there is no need to wait as scan command might be in the SME pending
10804 * command list.
10805 */
10806 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
10807 {
10808 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10809 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010810 &pScanInfo->abortscan_event_var,
10811 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053010812 if (0 >= status)
10813 {
10814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010815 "%s: Timeout or Interrupt occurred while waiting for abort"
10816 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053010817 return -ETIMEDOUT;
10818 }
10819 }
10820 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
10821 {
10822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10823 FL("hdd_abort_mac_scan failed"));
10824 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010825 }
10826 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010827 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010828}
10829
c_hpothu225aa7c2014-10-22 17:45:13 +053010830VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10831{
10832 hdd_adapter_t *pAdapter;
10833 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10834 VOS_STATUS vosStatus;
10835
10836 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10837 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10838 {
10839 pAdapter = pAdapterNode->pAdapter;
10840 if (NULL != pAdapter)
10841 {
10842 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10843 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10844 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10845 {
10846 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10847 pAdapter->device_mode);
10848 if (VOS_STATUS_SUCCESS !=
10849 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10850 {
10851 hddLog(LOGE, FL("failed to abort ROC"));
10852 return VOS_STATUS_E_FAILURE;
10853 }
10854 }
10855 }
10856 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10857 pAdapterNode = pNext;
10858 }
10859 return VOS_STATUS_SUCCESS;
10860}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053010861
10862void hdd_nullify_netdev_ops(hdd_context_t *pHddCtx)
10863{
10864 VOS_STATUS status;
10865 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10866 hdd_adapter_t *pAdapter;
10867
10868 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10869 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10870 {
10871 pAdapter = pAdapterNode->pAdapter;
10872 if (NULL != pAdapter)
10873 {
10874 /* Disable TX on the interface, after this hard_start_xmit() will
10875 * not be called on that interface
10876 */
10877 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10878 netif_tx_disable(pAdapter->dev);
10879 /* Mark the interface status as "down" for outside world */
10880 netif_carrier_off(pAdapter->dev);
10881 pAdapter->dev->netdev_ops = &nullify_netdev_ops;
10882 }
10883 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10884 pAdapterNode = pNext;
10885 }
10886}
10887
Jeff Johnson295189b2012-06-20 16:38:30 -070010888//Register the module init/exit functions
10889module_init(hdd_module_init);
10890module_exit(hdd_module_exit);
10891
10892MODULE_LICENSE("Dual BSD/GPL");
10893MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10894MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10895
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010896module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10897 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010898
Jeff Johnson76052702013-04-16 13:55:05 -070010899module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010900 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010901
10902module_param(enable_dfs_chan_scan, int,
10903 S_IRUSR | S_IRGRP | S_IROTH);
10904
10905module_param(enable_11d, int,
10906 S_IRUSR | S_IRGRP | S_IROTH);
10907
10908module_param(country_code, charp,
10909 S_IRUSR | S_IRGRP | S_IROTH);