blob: bb026b627cd593efa63214a5c29e8753c2aa6bf1 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800197#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700200/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700201static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700202
203//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700204static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
206static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
207void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800208void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700209
Jeff Johnson295189b2012-06-20 16:38:30 -0700210v_U16_t hdd_select_queue(struct net_device *dev,
211 struct sk_buff *skb);
212
213#ifdef WLAN_FEATURE_PACKET_FILTERING
214static void hdd_set_multicast_list(struct net_device *dev);
215#endif
216
217void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
218
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800219#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800220void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
221static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700222static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
223 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
224 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700225static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
226 tANI_U8 *pTargetApBssid,
227 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800228#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800229#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700230VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800231#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700232
Mihir Shetee1093ba2014-01-21 20:13:32 +0530233static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530234const char * hdd_device_modetoString(v_U8_t device_mode)
235{
236 switch(device_mode)
237 {
238 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
239 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
240 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
241 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
242 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
243 CASE_RETURN_STRING( WLAN_HDD_FTM );
244 CASE_RETURN_STRING( WLAN_HDD_IBSS );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
246 default:
247 return "device_mode Unknown";
248 }
249}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530250
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{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530463
464 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
465 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530467 "%s: HDD context is Null", __func__);
468 return -ENODEV;
469 }
470
471 if (pHddCtx->isLogpInProgress)
472 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530474 "%s: LOGP %s. Ignore!!", __func__,
475 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
476 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530477 return -EAGAIN;
478 }
479
Mihir Shete18156292014-03-11 15:38:30 +0530480 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530481 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530483 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
484 return -EAGAIN;
485 }
486 return 0;
487}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700488#ifdef CONFIG_ENABLE_LINUX_REG
489void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
490{
491 hdd_adapter_t *pAdapter = NULL;
492 hdd_station_ctx_t *pHddStaCtx = NULL;
493 eCsrPhyMode phyMode;
494 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530495
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700496 if (NULL == pHddCtx)
497 {
498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
499 "HDD Context is null !!");
500 return ;
501 }
502
503 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
504 if (NULL == pAdapter)
505 {
506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
507 "pAdapter is null !!");
508 return ;
509 }
510
511 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
512 if (NULL == pHddStaCtx)
513 {
514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
515 "pHddStaCtx is null !!");
516 return ;
517 }
518
519 cfg_param = pHddCtx->cfg_ini;
520 if (NULL == cfg_param)
521 {
522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
523 "cfg_params not available !!");
524 return ;
525 }
526
527 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
528
529 if (!pHddCtx->isVHT80Allowed)
530 {
531 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
532 (eCSR_DOT11_MODE_11ac == phyMode) ||
533 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
534 {
535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
536 "Setting phymode to 11n!!");
537 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
538 }
539 }
540 else
541 {
542 /*New country Supports 11ac as well resetting value back from .ini*/
543 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
544 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
545 return ;
546 }
547
548 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
549 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
550 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
551 {
552 VOS_STATUS vosStatus;
553
554 // need to issue a disconnect to CSR.
555 INIT_COMPLETION(pAdapter->disconnect_comp_var);
556 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
557 pAdapter->sessionId,
558 eCSR_DISCONNECT_REASON_UNSPECIFIED );
559
560 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530561 {
562 long ret;
563
564 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700565 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530566 if (0 >= ret)
567 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
568 ret);
569 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700570
571 }
572}
573#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530574void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
575{
576 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
577 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
578 hdd_config_t *cfg_param;
579 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530580 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530581
582 if (NULL == pHddCtx)
583 {
584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
585 "HDD Context is null !!");
586 return ;
587 }
588
589 cfg_param = pHddCtx->cfg_ini;
590
591 if (NULL == cfg_param)
592 {
593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
594 "cfg_params not available !!");
595 return ;
596 }
597
598 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
599
600 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
601 {
602 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
603 (eCSR_DOT11_MODE_11ac == phyMode) ||
604 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
605 {
606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
607 "Setting phymode to 11n!!");
608 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
609 }
610 }
611 else
612 {
613 /*New country Supports 11ac as well resetting value back from .ini*/
614 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
615 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
616 return ;
617 }
618
619 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
620 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
621 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
622 {
623 VOS_STATUS vosStatus;
624
625 // need to issue a disconnect to CSR.
626 INIT_COMPLETION(pAdapter->disconnect_comp_var);
627 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
628 pAdapter->sessionId,
629 eCSR_DISCONNECT_REASON_UNSPECIFIED );
630
631 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530632 {
633 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530634 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530635 if (ret <= 0)
636 {
637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
638 "wait on disconnect_comp_var is failed %ld", ret);
639 }
640 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530641
642 }
643}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700644#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530645
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700646void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
647{
648 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
649 hdd_config_t *cfg_param;
650
651 if (NULL == pHddCtx)
652 {
653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
654 "HDD Context is null !!");
655 return ;
656 }
657
658 cfg_param = pHddCtx->cfg_ini;
659
660 if (NULL == cfg_param)
661 {
662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
663 "cfg_params not available !!");
664 return ;
665 }
666
Agarwal Ashish738843c2014-09-25 12:27:56 +0530667 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
668 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700669 {
670 /*New country doesn't support DFS */
671 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
672 }
673 else
674 {
675 /*New country Supports DFS as well resetting value back from .ini*/
676 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
677 }
678
679}
680
Rajeev79dbe4c2013-10-05 11:03:42 +0530681#ifdef FEATURE_WLAN_BATCH_SCAN
682
683/**---------------------------------------------------------------------------
684
685 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
686 input string
687
688 This function extracts assigned integer from string in below format:
689 "STRING=10" : extracts integer 10 from this string
690
691 \param - pInPtr Pointer to input string
692 \param - base Base for string to int conversion(10 for decimal 16 for hex)
693 \param - pOutPtr Pointer to variable in which extracted integer needs to be
694 assigned
695 \param - pLastArg to tell whether it is last arguement in input string or
696 not
697
698 \return - NULL for failure cases
699 pointer to next arguement in input string for success cases
700 --------------------------------------------------------------------------*/
701static tANI_U8 *
702hdd_extract_assigned_int_from_str
703(
704 tANI_U8 *pInPtr,
705 tANI_U8 base,
706 tANI_U32 *pOutPtr,
707 tANI_U8 *pLastArg
708)
709{
710 int tempInt;
711 int v = 0;
712 char buf[32];
713 int val = 0;
714 *pLastArg = FALSE;
715
716 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
717 if (NULL == pInPtr)
718 {
719 return NULL;
720 }
721
722 pInPtr++;
723
724 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
725
726 val = sscanf(pInPtr, "%32s ", buf);
727 if (val < 0 && val > strlen(pInPtr))
728 {
729 return NULL;
730 }
731 pInPtr += val;
732 v = kstrtos32(buf, base, &tempInt);
733 if (v < 0)
734 {
735 return NULL;
736 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800737 if (tempInt < 0)
738 {
739 tempInt = 0;
740 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530741 *pOutPtr = tempInt;
742
743 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
744 if (NULL == pInPtr)
745 {
746 *pLastArg = TRUE;
747 return NULL;
748 }
749 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
750
751 return pInPtr;
752}
753
754/**---------------------------------------------------------------------------
755
756 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
757 input string
758
759 This function extracts assigned character from string in below format:
760 "STRING=A" : extracts char 'A' from this string
761
762 \param - pInPtr Pointer to input string
763 \param - pOutPtr Pointer to variable in which extracted char needs to be
764 assigned
765 \param - pLastArg to tell whether it is last arguement in input string or
766 not
767
768 \return - NULL for failure cases
769 pointer to next arguement in input string for success cases
770 --------------------------------------------------------------------------*/
771static tANI_U8 *
772hdd_extract_assigned_char_from_str
773(
774 tANI_U8 *pInPtr,
775 tANI_U8 *pOutPtr,
776 tANI_U8 *pLastArg
777)
778{
779 *pLastArg = FALSE;
780
781 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
782 if (NULL == pInPtr)
783 {
784 return NULL;
785 }
786
787 pInPtr++;
788
789 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
790
791 *pOutPtr = *pInPtr;
792
793 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
794 if (NULL == pInPtr)
795 {
796 *pLastArg = TRUE;
797 return NULL;
798 }
799 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
800
801 return pInPtr;
802}
803
804
805/**---------------------------------------------------------------------------
806
807 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
808
809 This function parses set batch scan command in below format:
810 WLS_BATCHING_SET <space> followed by below arguements
811 "SCANFREQ=XX" : Optional defaults to 30 sec
812 "MSCAN=XX" : Required number of scans to attempt to batch
813 "BESTN=XX" : Best Network (RSSI) defaults to 16
814 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
815 A. implies only 5 GHz , B. implies only 2.4GHz
816 "RTT=X" : optional defaults to 0
817 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
818 error
819
820 For example input commands:
821 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
822 translated into set batch scan with following parameters:
823 a) Frequence 60 seconds
824 b) Batch 10 scans together
825 c) Best RSSI to be 20
826 d) 5GHz band only
827 e) RTT is equal to 0
828
829 \param - pValue Pointer to input channel list
830 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
831
832 \return - 0 for success non-zero for failure
833
834 --------------------------------------------------------------------------*/
835static int
836hdd_parse_set_batchscan_command
837(
838 tANI_U8 *pValue,
839 tSirSetBatchScanReq *pHddSetBatchScanReq
840)
841{
842 tANI_U8 *inPtr = pValue;
843 tANI_U8 val = 0;
844 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800845 tANI_U32 nScanFreq;
846 tANI_U32 nMscan;
847 tANI_U32 nBestN;
848 tANI_U8 ucRfBand;
849 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800850 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530851
852 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800853 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
854 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
855 nRtt = 0;
856 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530857
858 /*go to space after WLS_BATCHING_SET command*/
859 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
860 /*no argument after the command*/
861 if (NULL == inPtr)
862 {
863 return -EINVAL;
864 }
865
866 /*no space after the command*/
867 else if (SPACE_ASCII_VALUE != *inPtr)
868 {
869 return -EINVAL;
870 }
871
872 /*removing empty spaces*/
873 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
874
875 /*no argument followed by spaces*/
876 if ('\0' == *inPtr)
877 {
878 return -EINVAL;
879 }
880
881 /*check and parse SCANFREQ*/
882 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
883 {
884 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800885 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800886
Rajeev Kumarc933d982013-11-18 20:04:20 -0800887 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800888 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800889 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800890 }
891
Rajeev79dbe4c2013-10-05 11:03:42 +0530892 if ( (NULL == inPtr) || (TRUE == lastArg))
893 {
894 return -EINVAL;
895 }
896 }
897
898 /*check and parse MSCAN*/
899 if ((strncmp(inPtr, "MSCAN", 5) == 0))
900 {
901 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800902 &nMscan, &lastArg);
903
904 if (0 == nMscan)
905 {
906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
907 "invalid MSCAN=%d", nMscan);
908 return -EINVAL;
909 }
910
Rajeev79dbe4c2013-10-05 11:03:42 +0530911 if (TRUE == lastArg)
912 {
913 goto done;
914 }
915 else if (NULL == inPtr)
916 {
917 return -EINVAL;
918 }
919 }
920 else
921 {
922 return -EINVAL;
923 }
924
925 /*check and parse BESTN*/
926 if ((strncmp(inPtr, "BESTN", 5) == 0))
927 {
928 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800929 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800930
Rajeev Kumarc933d982013-11-18 20:04:20 -0800931 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800932 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800933 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800934 }
935
Rajeev79dbe4c2013-10-05 11:03:42 +0530936 if (TRUE == lastArg)
937 {
938 goto done;
939 }
940 else if (NULL == inPtr)
941 {
942 return -EINVAL;
943 }
944 }
945
946 /*check and parse CHANNEL*/
947 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
948 {
949 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800950
Rajeev79dbe4c2013-10-05 11:03:42 +0530951 if (('A' == val) || ('a' == val))
952 {
c_hpothuebf89732014-02-25 13:00:24 +0530953 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530954 }
955 else if (('B' == val) || ('b' == val))
956 {
c_hpothuebf89732014-02-25 13:00:24 +0530957 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530958 }
959 else
960 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800961 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
962 }
963
964 if (TRUE == lastArg)
965 {
966 goto done;
967 }
968 else if (NULL == inPtr)
969 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530970 return -EINVAL;
971 }
972 }
973
974 /*check and parse RTT*/
975 if ((strncmp(inPtr, "RTT", 3) == 0))
976 {
977 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800978 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530979 if (TRUE == lastArg)
980 {
981 goto done;
982 }
983 if (NULL == inPtr)
984 {
985 return -EINVAL;
986 }
987 }
988
989
990done:
991
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800992 pHddSetBatchScanReq->scanFrequency = nScanFreq;
993 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
994 pHddSetBatchScanReq->bestNetwork = nBestN;
995 pHddSetBatchScanReq->rfBand = ucRfBand;
996 pHddSetBatchScanReq->rtt = nRtt;
997
Rajeev79dbe4c2013-10-05 11:03:42 +0530998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
999 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1000 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1001 pHddSetBatchScanReq->scanFrequency,
1002 pHddSetBatchScanReq->numberOfScansToBatch,
1003 pHddSetBatchScanReq->bestNetwork,
1004 pHddSetBatchScanReq->rfBand,
1005 pHddSetBatchScanReq->rtt);
1006
1007 return 0;
1008}/*End of hdd_parse_set_batchscan_command*/
1009
1010/**---------------------------------------------------------------------------
1011
1012 \brief hdd_set_batch_scan_req_callback () - This function is called after
1013 receiving set batch scan response from FW and it saves set batch scan
1014 response data FW to HDD context and sets the completion event on
1015 which hdd_ioctl is waiting
1016
1017 \param - callbackContext Pointer to HDD adapter
1018 \param - pRsp Pointer to set batch scan response data received from FW
1019
1020 \return - nothing
1021
1022 --------------------------------------------------------------------------*/
1023static void hdd_set_batch_scan_req_callback
1024(
1025 void *callbackContext,
1026 tSirSetBatchScanRsp *pRsp
1027)
1028{
1029 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1030 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1031
1032 /*sanity check*/
1033 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1034 {
1035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1036 "%s: Invalid pAdapter magic", __func__);
1037 VOS_ASSERT(0);
1038 return;
1039 }
1040 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1041
1042 /*save set batch scan response*/
1043 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1044
1045 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1046 "Received set batch scan rsp from FW with nScansToBatch=%d",
1047 pHddSetBatchScanRsp->nScansToBatch);
1048
1049 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1050 complete(&pAdapter->hdd_set_batch_scan_req_var);
1051
1052 return;
1053}/*End of hdd_set_batch_scan_req_callback*/
1054
1055
1056/**---------------------------------------------------------------------------
1057
1058 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1059 info in hdd batch scan response queue
1060
1061 \param - pAdapter Pointer to hdd adapter
1062 \param - pAPMetaInfo Pointer to access point meta info
1063 \param - scanId scan ID of batch scan response
1064 \param - isLastAp tells whether AP is last AP in batch scan response or not
1065
1066 \return - nothing
1067
1068 --------------------------------------------------------------------------*/
1069static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1070 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1071{
1072 tHddBatchScanRsp *pHead;
1073 tHddBatchScanRsp *pNode;
1074 tHddBatchScanRsp *pPrev;
1075 tHddBatchScanRsp *pTemp;
1076 tANI_U8 ssidLen;
1077
1078 /*head of hdd batch scan response queue*/
1079 pHead = pAdapter->pBatchScanRsp;
1080
1081 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1082 if (NULL == pNode)
1083 {
1084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1085 "%s: Could not allocate memory", __func__);
1086 VOS_ASSERT(0);
1087 return;
1088 }
1089
1090 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1091 sizeof(pNode->ApInfo.bssid));
1092 ssidLen = strlen(pApMetaInfo->ssid);
1093 if (SIR_MAX_SSID_SIZE < ssidLen)
1094 {
1095 /*invalid scan result*/
1096 vos_mem_free(pNode);
1097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1098 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1099 return;
1100 }
1101 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1102 /*null terminate ssid*/
1103 pNode->ApInfo.ssid[ssidLen] = '\0';
1104 pNode->ApInfo.ch = pApMetaInfo->ch;
1105 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1106 pNode->ApInfo.age = pApMetaInfo->timestamp;
1107 pNode->ApInfo.batchId = scanId;
1108 pNode->ApInfo.isLastAp = isLastAp;
1109
1110 pNode->pNext = NULL;
1111 if (NULL == pHead)
1112 {
1113 pAdapter->pBatchScanRsp = pNode;
1114 }
1115 else
1116 {
1117 pTemp = pHead;
1118 while (NULL != pTemp)
1119 {
1120 pPrev = pTemp;
1121 pTemp = pTemp->pNext;
1122 }
1123 pPrev->pNext = pNode;
1124 }
1125
1126 return;
1127}/*End of hdd_populate_batch_scan_rsp_queue*/
1128
1129/**---------------------------------------------------------------------------
1130
1131 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1132 receiving batch scan response indication from FW. It saves get batch scan
1133 response data in HDD batch scan response queue. This callback sets the
1134 completion event on which hdd_ioctl is waiting only after getting complete
1135 batch scan response data from FW
1136
1137 \param - callbackContext Pointer to HDD adapter
1138 \param - pRsp Pointer to get batch scan response data received from FW
1139
1140 \return - nothing
1141
1142 --------------------------------------------------------------------------*/
1143static void hdd_batch_scan_result_ind_callback
1144(
1145 void *callbackContext,
1146 void *pRsp
1147)
1148{
1149 v_BOOL_t isLastAp;
1150 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001151 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301152 tANI_U32 numberScanList;
1153 tANI_U32 nextScanListOffset;
1154 tANI_U32 nextApMetaInfoOffset;
1155 hdd_adapter_t* pAdapter;
1156 tpSirBatchScanList pScanList;
1157 tpSirBatchScanNetworkInfo pApMetaInfo;
1158 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1159 tSirSetBatchScanReq *pReq;
1160
1161 pAdapter = (hdd_adapter_t *)callbackContext;
1162 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001163 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301164 {
1165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1166 "%s: Invalid pAdapter magic", __func__);
1167 VOS_ASSERT(0);
1168 return;
1169 }
1170
1171 /*initialize locals*/
1172 pReq = &pAdapter->hddSetBatchScanReq;
1173 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1174 isLastAp = FALSE;
1175 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001176 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301177 numberScanList = 0;
1178 nextScanListOffset = 0;
1179 nextApMetaInfoOffset = 0;
1180 pScanList = NULL;
1181 pApMetaInfo = NULL;
1182
1183 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1184 {
1185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1186 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1187 isLastAp = TRUE;
1188 goto done;
1189 }
1190
1191 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1193 "Batch scan rsp: numberScalList %d", numberScanList);
1194
1195 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1196 {
1197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1198 "%s: numberScanList %d", __func__, numberScanList);
1199 isLastAp = TRUE;
1200 goto done;
1201 }
1202
1203 while (numberScanList)
1204 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001205 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301206 nextScanListOffset);
1207 if (NULL == pScanList)
1208 {
1209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1210 "%s: pScanList is %p", __func__, pScanList);
1211 isLastAp = TRUE;
1212 goto done;
1213 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001214 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001216 "Batch scan rsp: numApMetaInfo %d scanId %d",
1217 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301218
1219 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1220 {
1221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1222 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1223 isLastAp = TRUE;
1224 goto done;
1225 }
1226
Rajeev Kumarce651e42013-10-21 18:57:15 -07001227 /*Initialize next AP meta info offset for next scan list*/
1228 nextApMetaInfoOffset = 0;
1229
Rajeev79dbe4c2013-10-05 11:03:42 +05301230 while (numApMetaInfo)
1231 {
1232 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1233 nextApMetaInfoOffset);
1234 if (NULL == pApMetaInfo)
1235 {
1236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1237 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1238 isLastAp = TRUE;
1239 goto done;
1240 }
1241 /*calculate AP age*/
1242 pApMetaInfo->timestamp =
1243 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1244
1245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001246 "%s: bssId "MAC_ADDRESS_STR
1247 " ch %d rssi %d timestamp %d", __func__,
1248 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1249 pApMetaInfo->ch, pApMetaInfo->rssi,
1250 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301251
1252 /*mark last AP in batch scan response*/
1253 if ((TRUE == pBatchScanRsp->isLastResult) &&
1254 (1 == numberScanList) && (1 == numApMetaInfo))
1255 {
1256 isLastAp = TRUE;
1257 }
1258
1259 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1260 /*store batch scan repsonse in hdd queue*/
1261 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1262 pScanList->scanId, isLastAp);
1263 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1264
1265 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1266 numApMetaInfo--;
1267 }
1268
Rajeev Kumarce651e42013-10-21 18:57:15 -07001269 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1270 + (sizeof(tSirBatchScanNetworkInfo)
1271 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301272 numberScanList--;
1273 }
1274
1275done:
1276
1277 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1278 requested from hdd_ioctl*/
1279 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1280 (TRUE == isLastAp))
1281 {
1282 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1283 complete(&pAdapter->hdd_get_batch_scan_req_var);
1284 }
1285
1286 return;
1287}/*End of hdd_batch_scan_result_ind_callback*/
1288
1289/**---------------------------------------------------------------------------
1290
1291 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1292 response as per batch scan FR request format by putting proper markers
1293
1294 \param - pDest pointer to destination buffer
1295 \param - cur_len current length
1296 \param - tot_len total remaining size which can be written to user space
1297 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1298 \param - pAdapter Pointer to HDD adapter
1299
1300 \return - ret no of characters written
1301
1302 --------------------------------------------------------------------------*/
1303static tANI_U32
1304hdd_format_batch_scan_rsp
1305(
1306 tANI_U8 *pDest,
1307 tANI_U32 cur_len,
1308 tANI_U32 tot_len,
1309 tHddBatchScanRsp *pApMetaInfo,
1310 hdd_adapter_t* pAdapter
1311)
1312{
1313 tANI_U32 ret = 0;
1314 tANI_U32 rem_len = 0;
1315 tANI_U8 temp_len = 0;
1316 tANI_U8 temp_total_len = 0;
1317 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1318 tANI_U8 *pTemp = temp;
1319
1320 /*Batch scan reponse needs to be returned to user space in
1321 following format:
1322 "scancount=X\n" where X is the number of scans in current batch
1323 batch
1324 "trunc\n" optional present if current scan truncated
1325 "bssid=XX:XX:XX:XX:XX:XX\n"
1326 "ssid=XXXX\n"
1327 "freq=X\n" frequency in Mhz
1328 "level=XX\n"
1329 "age=X\n" ms
1330 "dist=X\n" cm (-1 if not available)
1331 "errror=X\n" (-1if not available)
1332 "====\n" (end of ap marker)
1333 "####\n" (end of scan marker)
1334 "----\n" (end of results)*/
1335 /*send scan result in above format to user space based on
1336 available length*/
1337 /*The GET response may have more data than the driver can return in its
1338 buffer. In that case the buffer should be filled to the nearest complete
1339 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1340 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1341 The final buffer should end with "----\n"*/
1342
1343 /*sanity*/
1344 if (cur_len > tot_len)
1345 {
1346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1347 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1348 return 0;
1349 }
1350 else
1351 {
1352 rem_len = (tot_len - cur_len);
1353 }
1354
1355 /*end scan marker*/
1356 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1357 {
1358 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1359 pTemp += temp_len;
1360 temp_total_len += temp_len;
1361 }
1362
1363 /*bssid*/
1364 temp_len = snprintf(pTemp, sizeof(temp),
1365 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1366 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1367 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1368 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1369 pTemp += temp_len;
1370 temp_total_len += temp_len;
1371
1372 /*ssid*/
1373 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1374 pApMetaInfo->ApInfo.ssid);
1375 pTemp += temp_len;
1376 temp_total_len += temp_len;
1377
1378 /*freq*/
1379 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001380 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301381 pTemp += temp_len;
1382 temp_total_len += temp_len;
1383
1384 /*level*/
1385 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1386 pApMetaInfo->ApInfo.rssi);
1387 pTemp += temp_len;
1388 temp_total_len += temp_len;
1389
1390 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001391 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301392 pApMetaInfo->ApInfo.age);
1393 pTemp += temp_len;
1394 temp_total_len += temp_len;
1395
1396 /*dist*/
1397 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1398 pTemp += temp_len;
1399 temp_total_len += temp_len;
1400
1401 /*error*/
1402 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1403 pTemp += temp_len;
1404 temp_total_len += temp_len;
1405
1406 /*end AP marker*/
1407 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1408 pTemp += temp_len;
1409 temp_total_len += temp_len;
1410
1411 /*last AP in batch scan response*/
1412 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1413 {
1414 /*end scan marker*/
1415 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1416 pTemp += temp_len;
1417 temp_total_len += temp_len;
1418
1419 /*end batch scan result marker*/
1420 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1421 pTemp += temp_len;
1422 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001423
Rajeev79dbe4c2013-10-05 11:03:42 +05301424 }
1425
1426 if (temp_total_len < rem_len)
1427 {
1428 ret = temp_total_len + 1;
1429 strlcpy(pDest, temp, ret);
1430 pAdapter->isTruncated = FALSE;
1431 }
1432 else
1433 {
1434 pAdapter->isTruncated = TRUE;
1435 if (rem_len >= strlen("%%%%"))
1436 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001437 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301438 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001439 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301440 {
1441 ret = 0;
1442 }
1443 }
1444
1445 return ret;
1446
1447}/*End of hdd_format_batch_scan_rsp*/
1448
1449/**---------------------------------------------------------------------------
1450
1451 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1452 buffer starting with head of hdd batch scan response queue
1453
1454 \param - pAdapter Pointer to HDD adapter
1455 \param - pDest Pointer to user data buffer
1456 \param - cur_len current offset in user buffer
1457 \param - rem_len remaining no of bytes in user buffer
1458
1459 \return - number of bytes written in user buffer
1460
1461 --------------------------------------------------------------------------*/
1462
1463tANI_U32 hdd_populate_user_batch_scan_rsp
1464(
1465 hdd_adapter_t* pAdapter,
1466 tANI_U8 *pDest,
1467 tANI_U32 cur_len,
1468 tANI_U32 rem_len
1469)
1470{
1471 tHddBatchScanRsp *pHead;
1472 tHddBatchScanRsp *pPrev;
1473 tANI_U32 len;
1474
Rajeev79dbe4c2013-10-05 11:03:42 +05301475 pAdapter->isTruncated = FALSE;
1476
1477 /*head of hdd batch scan response queue*/
1478 pHead = pAdapter->pBatchScanRsp;
1479 while (pHead)
1480 {
1481 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1482 pAdapter);
1483 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001484 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301485 cur_len += len;
1486 if(TRUE == pAdapter->isTruncated)
1487 {
1488 /*result is truncated return rest of scan rsp in next req*/
1489 cur_len = rem_len;
1490 break;
1491 }
1492 pPrev = pHead;
1493 pHead = pHead->pNext;
1494 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001495 if (TRUE == pPrev->ApInfo.isLastAp)
1496 {
1497 pAdapter->prev_batch_id = 0;
1498 }
1499 else
1500 {
1501 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1502 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301503 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001504 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301505 }
1506
1507 return cur_len;
1508}/*End of hdd_populate_user_batch_scan_rsp*/
1509
1510/**---------------------------------------------------------------------------
1511
1512 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1513 scan response data from HDD queue to user space
1514 It does following in detail:
1515 a) if HDD has enough data in its queue then it 1st copies data to user
1516 space and then send get batch scan indication message to FW. In this
1517 case it does not wait on any event and batch scan response data will
1518 be populated in HDD response queue in MC thread context after receiving
1519 indication from FW
1520 b) else send get batch scan indication message to FW and wait on an event
1521 which will be set once HDD receives complete batch scan response from
1522 FW and then this function returns batch scan response to user space
1523
1524 \param - pAdapter Pointer to HDD adapter
1525 \param - pPrivData Pointer to priv_data
1526
1527 \return - 0 for success -EFAULT for failure
1528
1529 --------------------------------------------------------------------------*/
1530
1531int hdd_return_batch_scan_rsp_to_user
1532(
1533 hdd_adapter_t* pAdapter,
1534 hdd_priv_data_t *pPrivData,
1535 tANI_U8 *command
1536)
1537{
1538 tANI_U8 *pDest;
1539 tANI_U32 count = 0;
1540 tANI_U32 len = 0;
1541 tANI_U32 cur_len = 0;
1542 tANI_U32 rem_len = 0;
1543 eHalStatus halStatus;
1544 unsigned long rc;
1545 tSirTriggerBatchScanResultInd *pReq;
1546
1547 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1548 pReq->param = 0;/*batch scan client*/
1549 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1550 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1551
1552 cur_len = pPrivData->used_len;
1553 if (pPrivData->total_len > pPrivData->used_len)
1554 {
1555 rem_len = pPrivData->total_len - pPrivData->used_len;
1556 }
1557 else
1558 {
1559 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1560 "%s: Invalid user data buffer total_len %d used_len %d",
1561 __func__, pPrivData->total_len, pPrivData->used_len);
1562 return -EFAULT;
1563 }
1564
1565 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1566 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1567 cur_len, rem_len);
1568 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1569
1570 /*enough scan result available in cache to return to user space or
1571 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001572 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301573 {
1574 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1575 halStatus = sme_TriggerBatchScanResultInd(
1576 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1577 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1578 pAdapter);
1579 if ( eHAL_STATUS_SUCCESS == halStatus )
1580 {
1581 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1582 {
1583 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1584 rc = wait_for_completion_timeout(
1585 &pAdapter->hdd_get_batch_scan_req_var,
1586 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1587 if (0 == rc)
1588 {
1589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1590 "%s: Timeout waiting to fetch batch scan rsp from fw",
1591 __func__);
1592 return -EFAULT;
1593 }
1594 }
1595
1596 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001597 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301598 pDest += len;
1599 cur_len += len;
1600
1601 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1602 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1603 cur_len, rem_len);
1604 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1605
1606 count = 0;
1607 len = (len - pPrivData->used_len);
1608 pDest = (command + pPrivData->used_len);
1609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001610 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301611 while(count < len)
1612 {
1613 printk("%c", *(pDest + count));
1614 count++;
1615 }
1616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1617 "%s: copy %d data to user buffer", __func__, len);
1618 if (copy_to_user(pPrivData->buf, pDest, len))
1619 {
1620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1621 "%s: failed to copy data to user buffer", __func__);
1622 return -EFAULT;
1623 }
1624 }
1625 else
1626 {
1627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1628 "sme_GetBatchScanScan returned failure halStatus %d",
1629 halStatus);
1630 return -EINVAL;
1631 }
1632 }
1633 else
1634 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301635 count = 0;
1636 len = (len - pPrivData->used_len);
1637 pDest = (command + pPrivData->used_len);
1638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001639 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301640 while(count < len)
1641 {
1642 printk("%c", *(pDest + count));
1643 count++;
1644 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1646 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301647 if (copy_to_user(pPrivData->buf, pDest, len))
1648 {
1649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1650 "%s: failed to copy data to user buffer", __func__);
1651 return -EFAULT;
1652 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301653 }
1654
1655 return 0;
1656} /*End of hdd_return_batch_scan_rsp_to_user*/
1657
Rajeev Kumar8b373292014-01-08 20:36:55 -08001658
1659/**---------------------------------------------------------------------------
1660
1661 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1662 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1663 WLS_BATCHING VERSION
1664 WLS_BATCHING SET
1665 WLS_BATCHING GET
1666 WLS_BATCHING STOP
1667
1668 \param - pAdapter Pointer to HDD adapter
1669 \param - pPrivdata Pointer to priv_data
1670 \param - command Pointer to command
1671
1672 \return - 0 for success -EFAULT for failure
1673
1674 --------------------------------------------------------------------------*/
1675
1676int hdd_handle_batch_scan_ioctl
1677(
1678 hdd_adapter_t *pAdapter,
1679 hdd_priv_data_t *pPrivdata,
1680 tANI_U8 *command
1681)
1682{
1683 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001684 hdd_context_t *pHddCtx;
1685
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301686 ENTER();
1687
Yue Mae36e3552014-03-05 17:06:20 -08001688 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1689 ret = wlan_hdd_validate_context(pHddCtx);
1690 if (ret)
1691 {
Yue Mae36e3552014-03-05 17:06:20 -08001692 goto exit;
1693 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001694
1695 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1696 {
1697 char extra[32];
1698 tANI_U8 len = 0;
1699 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1700
1701 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1702 {
1703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1704 "%s: Batch scan feature is not supported by FW", __func__);
1705 ret = -EINVAL;
1706 goto exit;
1707 }
1708
1709 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1710 version);
1711 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1712 {
1713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1714 "%s: failed to copy data to user buffer", __func__);
1715 ret = -EFAULT;
1716 goto exit;
1717 }
1718 ret = HDD_BATCH_SCAN_VERSION;
1719 }
1720 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1721 {
1722 int status;
1723 tANI_U8 *value = (command + 16);
1724 eHalStatus halStatus;
1725 unsigned long rc;
1726 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1727 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1728
1729 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1730 {
1731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1732 "%s: Batch scan feature is not supported by FW", __func__);
1733 ret = -EINVAL;
1734 goto exit;
1735 }
1736
1737 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1738 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1739 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1740 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1741 {
1742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301743 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001744 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301745 hdd_device_modetoString(pAdapter->device_mode),
1746 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001747 ret = -EINVAL;
1748 goto exit;
1749 }
1750
1751 status = hdd_parse_set_batchscan_command(value, pReq);
1752 if (status)
1753 {
1754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1755 "Invalid WLS_BATCHING SET command");
1756 ret = -EINVAL;
1757 goto exit;
1758 }
1759
1760
1761 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1762 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1763 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1764 pAdapter);
1765
1766 if ( eHAL_STATUS_SUCCESS == halStatus )
1767 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301768 char extra[32];
1769 tANI_U8 len = 0;
1770 tANI_U8 mScan = 0;
1771
Rajeev Kumar8b373292014-01-08 20:36:55 -08001772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1773 "sme_SetBatchScanReq returned success halStatus %d",
1774 halStatus);
1775 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1776 {
1777 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1778 rc = wait_for_completion_timeout(
1779 &pAdapter->hdd_set_batch_scan_req_var,
1780 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1781 if (0 == rc)
1782 {
1783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1784 "%s: Timeout waiting for set batch scan to complete",
1785 __func__);
1786 ret = -EINVAL;
1787 goto exit;
1788 }
1789 }
1790 if ( !pRsp->nScansToBatch )
1791 {
1792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1793 "%s: Received set batch scan failure response from FW",
1794 __func__);
1795 ret = -EINVAL;
1796 goto exit;
1797 }
1798 /*As per the Batch Scan Framework API we should return the MIN of
1799 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301800 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001801
1802 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1803
1804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1805 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301806 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1807 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1808 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1809 {
1810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1811 "%s: failed to copy MSCAN value to user buffer", __func__);
1812 ret = -EFAULT;
1813 goto exit;
1814 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001815 }
1816 else
1817 {
1818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1819 "sme_SetBatchScanReq returned failure halStatus %d",
1820 halStatus);
1821 ret = -EINVAL;
1822 goto exit;
1823 }
1824 }
1825 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1826 {
1827 eHalStatus halStatus;
1828 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1829 pInd->param = 0;
1830
1831 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1832 {
1833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1834 "%s: Batch scan feature is not supported by FW", __func__);
1835 ret = -EINVAL;
1836 goto exit;
1837 }
1838
1839 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1840 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001842 "Batch scan is not yet enabled batch scan state %d",
1843 pAdapter->batchScanState);
1844 ret = -EINVAL;
1845 goto exit;
1846 }
1847
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001848 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1849 hdd_deinit_batch_scan(pAdapter);
1850 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1851
Rajeev Kumar8b373292014-01-08 20:36:55 -08001852 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1853
1854 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1855 pAdapter->sessionId);
1856 if ( eHAL_STATUS_SUCCESS == halStatus )
1857 {
1858 ret = 0;
1859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1860 "sme_StopBatchScanInd returned success halStatus %d",
1861 halStatus);
1862 }
1863 else
1864 {
1865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1866 "sme_StopBatchScanInd returned failure halStatus %d",
1867 halStatus);
1868 ret = -EINVAL;
1869 goto exit;
1870 }
1871 }
1872 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1873 {
1874 tANI_U32 remain_len;
1875
1876 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1877 {
1878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1879 "%s: Batch scan feature is not supported by FW", __func__);
1880 ret = -EINVAL;
1881 goto exit;
1882 }
1883
1884 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1885 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001887 "Batch scan is not yet enabled could not return results"
1888 "Batch Scan state %d",
1889 pAdapter->batchScanState);
1890 ret = -EINVAL;
1891 goto exit;
1892 }
1893
1894 pPrivdata->used_len = 16;
1895 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1896 if (remain_len < pPrivdata->total_len)
1897 {
1898 /*Clear previous batch scan response data if any*/
1899 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1900 }
1901 else
1902 {
1903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1904 "Invalid total length from user space can't fetch batch"
1905 " scan response total_len %d used_len %d remain len %d",
1906 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1907 ret = -EINVAL;
1908 goto exit;
1909 }
1910 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1911 }
1912
1913exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301914 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001915 return ret;
1916}
1917
1918
Rajeev79dbe4c2013-10-05 11:03:42 +05301919#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1920
c_hpothu92367912014-05-01 15:18:17 +05301921static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1922{
c_hpothu39eb1e32014-06-26 16:31:50 +05301923 bcnMissRateContext_t *pCBCtx;
1924
1925 if (NULL == data)
1926 {
1927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1928 return;
1929 }
c_hpothu92367912014-05-01 15:18:17 +05301930
1931 /* there is a race condition that exists between this callback
1932 function and the caller since the caller could time out either
1933 before or while this code is executing. we use a spinlock to
1934 serialize these actions */
1935 spin_lock(&hdd_context_lock);
1936
c_hpothu39eb1e32014-06-26 16:31:50 +05301937 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301938 gbcnMissRate = -1;
1939
c_hpothu39eb1e32014-06-26 16:31:50 +05301940 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301941 {
1942 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301943 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301944 spin_unlock(&hdd_context_lock);
1945 return ;
1946 }
1947
1948 if (VOS_STATUS_SUCCESS == status)
1949 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301950 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301951 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301952 else
1953 {
1954 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1955 }
1956
c_hpothu92367912014-05-01 15:18:17 +05301957 complete(&(pCBCtx->completion));
1958 spin_unlock(&hdd_context_lock);
1959
1960 return;
1961}
1962
Abhishek Singh08aa7762014-12-16 13:59:03 +05301963void hdd_FWStatisCB( VOS_STATUS status,
1964 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301965{
1966 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301967 hdd_adapter_t *pAdapter;
1968
1969 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1970
Abhishek Singh08aa7762014-12-16 13:59:03 +05301971 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301972 {
1973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1974 return;
1975 }
1976 /* there is a race condition that exists between this callback
1977 function and the caller since the caller could time out either
1978 before or while this code is executing. we use a spinlock to
1979 serialize these actions */
1980 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301981 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301982 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1983 {
1984 hddLog(VOS_TRACE_LEVEL_ERROR,
1985 FL("invalid context magic: %08x"), fwStatsCtx->magic);
1986 spin_unlock(&hdd_context_lock);
1987 return;
1988 }
1989 pAdapter = fwStatsCtx->pAdapter;
1990 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1991 {
1992 hddLog(VOS_TRACE_LEVEL_ERROR,
1993 FL("pAdapter returned is NULL or invalid"));
1994 spin_unlock(&hdd_context_lock);
1995 return;
1996 }
1997 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05301998 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05301999 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302000 switch( fwStatsResult->type )
2001 {
2002 case FW_UBSP_STATS:
2003 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302004 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302005 hddLog(VOS_TRACE_LEVEL_INFO,
2006 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302007 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2008 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302009 }
2010 break;
2011 default:
2012 {
2013 hddLog(VOS_TRACE_LEVEL_ERROR,
2014 FL(" No handling for stats type %d"),fwStatsResult->type);
2015 }
2016 }
2017 }
2018 complete(&(fwStatsCtx->completion));
2019 spin_unlock(&hdd_context_lock);
2020 return;
2021}
2022
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302023static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2024{
2025 int ret = 0;
2026
2027 if (!pCfg || !command || !extra || !len)
2028 {
2029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2030 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2031 ret = -EINVAL;
2032 return ret;
2033 }
2034
2035 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2036 {
2037 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2038 (int)pCfg->nActiveMaxChnTime);
2039 return ret;
2040 }
2041 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2042 {
2043 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2044 (int)pCfg->nActiveMinChnTime);
2045 return ret;
2046 }
2047 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2048 {
2049 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2050 (int)pCfg->nPassiveMaxChnTime);
2051 return ret;
2052 }
2053 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2054 {
2055 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2056 (int)pCfg->nPassiveMinChnTime);
2057 return ret;
2058 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302059 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2060 {
2061 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2062 (int)pCfg->nActiveMaxChnTime);
2063 return ret;
2064 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302065 else
2066 {
2067 ret = -EINVAL;
2068 }
2069
2070 return ret;
2071}
2072
2073static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2074{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302075 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302076 hdd_config_t *pCfg;
2077 tANI_U8 *value = command;
2078 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302079 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302080
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302081 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2082 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302083 {
2084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2085 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2086 ret = -EINVAL;
2087 return ret;
2088 }
2089
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302090 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2091 sme_GetConfigParam(hHal, &smeConfig);
2092
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302093 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2094 {
2095 value = value + 24;
2096 temp = kstrtou32(value, 10, &val);
2097 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2098 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2099 {
2100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2101 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2102 ret = -EFAULT;
2103 return ret;
2104 }
2105 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302106 smeConfig.csrConfig.nActiveMaxChnTime = val;
2107 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302108 }
2109 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2110 {
2111 value = value + 24;
2112 temp = kstrtou32(value, 10, &val);
2113 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2114 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2115 {
2116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2117 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2118 ret = -EFAULT;
2119 return ret;
2120 }
2121 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302122 smeConfig.csrConfig.nActiveMinChnTime = val;
2123 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302124 }
2125 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2126 {
2127 value = value + 25;
2128 temp = kstrtou32(value, 10, &val);
2129 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2130 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2131 {
2132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2133 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2134 ret = -EFAULT;
2135 return ret;
2136 }
2137 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302138 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2139 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302140 }
2141 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2142 {
2143 value = value + 25;
2144 temp = kstrtou32(value, 10, &val);
2145 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2146 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2147 {
2148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2149 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2150 ret = -EFAULT;
2151 return ret;
2152 }
2153 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302154 smeConfig.csrConfig.nPassiveMinChnTime = val;
2155 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302156 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302157 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2158 {
2159 value = value + 13;
2160 temp = kstrtou32(value, 10, &val);
2161 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2162 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2163 {
2164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2165 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2166 ret = -EFAULT;
2167 return ret;
2168 }
2169 pCfg->nActiveMaxChnTime = val;
2170 smeConfig.csrConfig.nActiveMaxChnTime = val;
2171 sme_UpdateConfig(hHal, &smeConfig);
2172 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302173 else
2174 {
2175 ret = -EINVAL;
2176 }
2177
2178 return ret;
2179}
2180
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002181static int hdd_driver_command(hdd_adapter_t *pAdapter,
2182 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002183{
Jeff Johnson295189b2012-06-20 16:38:30 -07002184 hdd_priv_data_t priv_data;
2185 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302186 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2187 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002188 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302189 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302190
2191 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002192 /*
2193 * Note that valid pointers are provided by caller
2194 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002195
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002196 /* copy to local struct to avoid numerous changes to legacy code */
2197 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002198
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002199 if (priv_data.total_len <= 0 ||
2200 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002201 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002202 hddLog(VOS_TRACE_LEVEL_WARN,
2203 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2204 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002205 ret = -EINVAL;
2206 goto exit;
2207 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302208 status = wlan_hdd_validate_context(pHddCtx);
2209 if (0 != status)
2210 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302211 ret = -EINVAL;
2212 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302213 }
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],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303576 (tSmeFastRoamTrigger)(trigger),
3577 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303578 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003579#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003580#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003581 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3582 {
3583 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003584 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003585
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003586 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003587 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003588 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003589 hdd_is_okc_mode_enabled(pHddCtx) &&
3590 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3591 {
3592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003593 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003594 " hence this operation is not permitted!", __func__);
3595 ret = -EPERM;
3596 goto exit;
3597 }
3598
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003599 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3600 value = value + 11;
3601 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003602 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003603 if (ret < 0)
3604 {
3605 /* If the input value is greater than max value of datatype, then also
3606 kstrtou8 fails */
3607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3608 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003609 CFG_ESE_FEATURE_ENABLED_MIN,
3610 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003611 ret = -EINVAL;
3612 goto exit;
3613 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003614 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3615 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003616 {
3617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003618 "Ese mode value %d is out of range"
3619 " (Min: %d Max: %d)", eseMode,
3620 CFG_ESE_FEATURE_ENABLED_MIN,
3621 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003622 ret = -EINVAL;
3623 goto exit;
3624 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003626 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003627
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003628 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3629 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003630 }
3631#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003632 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3633 {
3634 tANI_U8 *value = command;
3635 tANI_BOOLEAN roamScanControl = 0;
3636
3637 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3638 value = value + 19;
3639 /* Convert the value from ascii to integer */
3640 ret = kstrtou8(value, 10, &roamScanControl);
3641 if (ret < 0)
3642 {
3643 /* If the input value is greater than max value of datatype, then also
3644 kstrtou8 fails */
3645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3646 "%s: kstrtou8 failed ", __func__);
3647 ret = -EINVAL;
3648 goto exit;
3649 }
3650
3651 if (0 != roamScanControl)
3652 {
3653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3654 "roam scan control invalid value = %d",
3655 roamScanControl);
3656 ret = -EINVAL;
3657 goto exit;
3658 }
3659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3660 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3661
3662 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3663 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003664#ifdef FEATURE_WLAN_OKC
3665 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3666 {
3667 tANI_U8 *value = command;
3668 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3669
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003670 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003671 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003672 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003673 hdd_is_okc_mode_enabled(pHddCtx) &&
3674 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3675 {
3676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003677 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003678 " hence this operation is not permitted!", __func__);
3679 ret = -EPERM;
3680 goto exit;
3681 }
3682
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003683 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3684 value = value + 11;
3685 /* Convert the value from ascii to integer */
3686 ret = kstrtou8(value, 10, &okcMode);
3687 if (ret < 0)
3688 {
3689 /* If the input value is greater than max value of datatype, then also
3690 kstrtou8 fails */
3691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3692 "%s: kstrtou8 failed range [%d - %d]", __func__,
3693 CFG_OKC_FEATURE_ENABLED_MIN,
3694 CFG_OKC_FEATURE_ENABLED_MAX);
3695 ret = -EINVAL;
3696 goto exit;
3697 }
3698
3699 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3700 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3701 {
3702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3703 "Okc mode value %d is out of range"
3704 " (Min: %d Max: %d)", okcMode,
3705 CFG_OKC_FEATURE_ENABLED_MIN,
3706 CFG_OKC_FEATURE_ENABLED_MAX);
3707 ret = -EINVAL;
3708 goto exit;
3709 }
3710
3711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3712 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3713
3714 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3715 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003716#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003717 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3718 {
3719 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3720 char extra[32];
3721 tANI_U8 len = 0;
3722
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003723 len = scnprintf(extra, sizeof(extra), "%s %d",
3724 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003725 if (copy_to_user(priv_data.buf, &extra, len + 1))
3726 {
3727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3728 "%s: failed to copy data to user buffer", __func__);
3729 ret = -EFAULT;
3730 goto exit;
3731 }
3732 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303733#ifdef WLAN_FEATURE_PACKET_FILTERING
3734 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3735 {
3736 tANI_U8 filterType = 0;
3737 tANI_U8 *value = command;
3738
3739 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3740 value = value + 22;
3741
3742 /* Convert the value from ascii to integer */
3743 ret = kstrtou8(value, 10, &filterType);
3744 if (ret < 0)
3745 {
3746 /* If the input value is greater than max value of datatype,
3747 * then also kstrtou8 fails
3748 */
3749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3750 "%s: kstrtou8 failed range ", __func__);
3751 ret = -EINVAL;
3752 goto exit;
3753 }
3754
3755 if (filterType != 0 && filterType != 1)
3756 {
3757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3758 "%s: Accepted Values are 0 and 1 ", __func__);
3759 ret = -EINVAL;
3760 goto exit;
3761 }
3762 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3763 pAdapter->sessionId);
3764 }
3765#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303766 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3767 {
Kiet Lamad161252014-07-22 11:23:32 -07003768 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303769 int ret;
3770
Kiet Lamad161252014-07-22 11:23:32 -07003771 dhcpPhase = command + 11;
3772 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303773 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303774 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003775 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303776
3777 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003778
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303779 ret = wlan_hdd_scan_abort(pAdapter);
3780 if (ret < 0)
3781 {
3782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3783 FL("failed to abort existing scan %d"), ret);
3784 }
3785
Kiet Lamad161252014-07-22 11:23:32 -07003786 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3787 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303788 }
Kiet Lamad161252014-07-22 11:23:32 -07003789 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303790 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003792 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303793
3794 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003795
3796 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3797 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303798 }
3799 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003800 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3801 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3803 FL("making default scan to ACTIVE"));
3804 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003805 }
3806 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3807 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3809 FL("making default scan to PASSIVE"));
3810 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003811 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303812 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3813 {
3814 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3815 char extra[32];
3816 tANI_U8 len = 0;
3817
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303818 memset(extra, 0, sizeof(extra));
3819 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3820 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303821 {
3822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3823 "%s: failed to copy data to user buffer", __func__);
3824 ret = -EFAULT;
3825 goto exit;
3826 }
3827 ret = len;
3828 }
3829 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3830 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303831 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303832 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003833 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3834 {
3835 tANI_U8 filterType = 0;
3836 tANI_U8 *value;
3837 value = command + 9;
3838
3839 /* Convert the value from ascii to integer */
3840 ret = kstrtou8(value, 10, &filterType);
3841 if (ret < 0)
3842 {
3843 /* If the input value is greater than max value of datatype,
3844 * then also kstrtou8 fails
3845 */
3846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3847 "%s: kstrtou8 failed range ", __func__);
3848 ret = -EINVAL;
3849 goto exit;
3850 }
3851 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3852 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3853 {
3854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3855 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3856 " 2-Sink ", __func__);
3857 ret = -EINVAL;
3858 goto exit;
3859 }
3860 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3861 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303862 pScanInfo = &pHddCtx->scan_info;
3863 if (filterType && pScanInfo != NULL &&
3864 pHddCtx->scan_info.mScanPending)
3865 {
3866 /*Miracast Session started. Abort Scan */
3867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3868 "%s, Aborting Scan For Miracast",__func__);
3869 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3870 eCSR_SCAN_ABORT_DEFAULT);
3871 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003872 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303873 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003874 }
Leo Chang614d2072013-08-22 14:59:44 -07003875 else if (strncmp(command, "SETMCRATE", 9) == 0)
3876 {
Leo Chang614d2072013-08-22 14:59:44 -07003877 tANI_U8 *value = command;
3878 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003879 tSirRateUpdateInd *rateUpdate;
3880 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003881
3882 /* Only valid for SAP mode */
3883 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3884 {
3885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3886 "%s: SAP mode is not running", __func__);
3887 ret = -EFAULT;
3888 goto exit;
3889 }
3890
3891 /* Move pointer to ahead of SETMCRATE<delimiter> */
3892 /* input value is in units of hundred kbps */
3893 value = value + 10;
3894 /* Convert the value from ascii to integer, decimal base */
3895 ret = kstrtouint(value, 10, &targetRate);
3896
Leo Chang1f98cbd2013-10-17 15:03:52 -07003897 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3898 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003899 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003900 hddLog(VOS_TRACE_LEVEL_ERROR,
3901 "%s: SETMCRATE indication alloc fail", __func__);
3902 ret = -EFAULT;
3903 goto exit;
3904 }
3905 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3906
3907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3908 "MC Target rate %d", targetRate);
3909 /* Ignore unicast */
3910 rateUpdate->ucastDataRate = -1;
3911 rateUpdate->mcastDataRate24GHz = targetRate;
3912 rateUpdate->mcastDataRate5GHz = targetRate;
3913 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3914 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3915 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3916 if (eHAL_STATUS_SUCCESS != status)
3917 {
3918 hddLog(VOS_TRACE_LEVEL_ERROR,
3919 "%s: SET_MC_RATE failed", __func__);
3920 vos_mem_free(rateUpdate);
3921 ret = -EFAULT;
3922 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003923 }
3924 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303925#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003926 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303927 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003928 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303929 }
3930#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003931#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003932 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3933 {
3934 tANI_U8 *value = command;
3935 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3936 tANI_U8 numChannels = 0;
3937 eHalStatus status = eHAL_STATUS_SUCCESS;
3938
3939 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3940 if (eHAL_STATUS_SUCCESS != status)
3941 {
3942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3943 "%s: Failed to parse channel list information", __func__);
3944 ret = -EINVAL;
3945 goto exit;
3946 }
3947
3948 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3949 {
3950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3951 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3952 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3953 ret = -EINVAL;
3954 goto exit;
3955 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003956 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003957 ChannelList,
3958 numChannels);
3959 if (eHAL_STATUS_SUCCESS != status)
3960 {
3961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3962 "%s: Failed to update channel list information", __func__);
3963 ret = -EINVAL;
3964 goto exit;
3965 }
3966 }
3967 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3968 {
3969 tANI_U8 *value = command;
3970 char extra[128] = {0};
3971 int len = 0;
3972 tANI_U8 tid = 0;
3973 hdd_station_ctx_t *pHddStaCtx = NULL;
3974 tAniTrafStrmMetrics tsmMetrics;
3975 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3976
3977 /* if not associated, return error */
3978 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3979 {
3980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3981 ret = -EINVAL;
3982 goto exit;
3983 }
3984
3985 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3986 value = value + 12;
3987 /* Convert the value from ascii to integer */
3988 ret = kstrtou8(value, 10, &tid);
3989 if (ret < 0)
3990 {
3991 /* If the input value is greater than max value of datatype, then also
3992 kstrtou8 fails */
3993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3994 "%s: kstrtou8 failed range [%d - %d]", __func__,
3995 TID_MIN_VALUE,
3996 TID_MAX_VALUE);
3997 ret = -EINVAL;
3998 goto exit;
3999 }
4000
4001 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4002 {
4003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4004 "tid value %d is out of range"
4005 " (Min: %d Max: %d)", tid,
4006 TID_MIN_VALUE,
4007 TID_MAX_VALUE);
4008 ret = -EINVAL;
4009 goto exit;
4010 }
4011
4012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4013 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4014
4015 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4016 {
4017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4018 "%s: failed to get tsm stats", __func__);
4019 ret = -EFAULT;
4020 goto exit;
4021 }
4022
4023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4024 "UplinkPktQueueDly(%d)\n"
4025 "UplinkPktQueueDlyHist[0](%d)\n"
4026 "UplinkPktQueueDlyHist[1](%d)\n"
4027 "UplinkPktQueueDlyHist[2](%d)\n"
4028 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304029 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004030 "UplinkPktLoss(%d)\n"
4031 "UplinkPktCount(%d)\n"
4032 "RoamingCount(%d)\n"
4033 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4034 tsmMetrics.UplinkPktQueueDlyHist[0],
4035 tsmMetrics.UplinkPktQueueDlyHist[1],
4036 tsmMetrics.UplinkPktQueueDlyHist[2],
4037 tsmMetrics.UplinkPktQueueDlyHist[3],
4038 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4039 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4040
4041 /* Output TSM stats is of the format
4042 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4043 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004044 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004045 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4046 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4047 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4048 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4049 tsmMetrics.RoamingDly);
4050
4051 if (copy_to_user(priv_data.buf, &extra, len + 1))
4052 {
4053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4054 "%s: failed to copy data to user buffer", __func__);
4055 ret = -EFAULT;
4056 goto exit;
4057 }
4058 }
4059 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4060 {
4061 tANI_U8 *value = command;
4062 tANI_U8 *cckmIe = NULL;
4063 tANI_U8 cckmIeLen = 0;
4064 eHalStatus status = eHAL_STATUS_SUCCESS;
4065
4066 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4067 if (eHAL_STATUS_SUCCESS != status)
4068 {
4069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4070 "%s: Failed to parse cckm ie data", __func__);
4071 ret = -EINVAL;
4072 goto exit;
4073 }
4074
4075 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4076 {
4077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4078 "%s: CCKM Ie input length is more than max[%d]", __func__,
4079 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004080 vos_mem_free(cckmIe);
4081 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004082 ret = -EINVAL;
4083 goto exit;
4084 }
4085 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004086 vos_mem_free(cckmIe);
4087 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004088 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004089 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4090 {
4091 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004092 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004093 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004094
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004095 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004096 if (eHAL_STATUS_SUCCESS != status)
4097 {
4098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004099 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004100 ret = -EINVAL;
4101 goto exit;
4102 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004103 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4104 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4105 hdd_indicateEseBcnReportNoResults (pAdapter,
4106 eseBcnReq.bcnReq[0].measurementToken,
4107 0x02, //BIT(1) set for measurement done
4108 0); // no BSS
4109 goto exit;
4110 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004111
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004112 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4113 if (eHAL_STATUS_SUCCESS != status)
4114 {
4115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4116 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4117 ret = -EINVAL;
4118 goto exit;
4119 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004120 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004121#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304122 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4123 {
4124 eHalStatus status;
4125 char buf[32], len;
4126 long waitRet;
4127 bcnMissRateContext_t getBcnMissRateCtx;
4128
4129 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4130
4131 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4132 {
4133 hddLog(VOS_TRACE_LEVEL_WARN,
4134 FL("GETBCNMISSRATE: STA is not in connected state"));
4135 ret = -1;
4136 goto exit;
4137 }
4138
4139 init_completion(&(getBcnMissRateCtx.completion));
4140 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4141
4142 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4143 pAdapter->sessionId,
4144 (void *)getBcnMissRateCB,
4145 (void *)(&getBcnMissRateCtx));
4146 if( eHAL_STATUS_SUCCESS != status)
4147 {
4148 hddLog(VOS_TRACE_LEVEL_INFO,
4149 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4150 ret = -EINVAL;
4151 goto exit;
4152 }
4153
4154 waitRet = wait_for_completion_interruptible_timeout
4155 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4156 if(waitRet <= 0)
4157 {
4158 hddLog(VOS_TRACE_LEVEL_ERROR,
4159 FL("failed to wait on bcnMissRateComp %d"), ret);
4160
4161 //Make magic number to zero so that callback is not called.
4162 spin_lock(&hdd_context_lock);
4163 getBcnMissRateCtx.magic = 0x0;
4164 spin_unlock(&hdd_context_lock);
4165 ret = -EINVAL;
4166 goto exit;
4167 }
4168
4169 hddLog(VOS_TRACE_LEVEL_INFO,
4170 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4171
4172 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4173 if (copy_to_user(priv_data.buf, &buf, len + 1))
4174 {
4175 hddLog(VOS_TRACE_LEVEL_ERROR,
4176 "%s: failed to copy data to user buffer", __func__);
4177 ret = -EFAULT;
4178 goto exit;
4179 }
4180 ret = len;
4181 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304182#ifdef FEATURE_WLAN_TDLS
4183 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4184 tANI_U8 *value = command;
4185 int set_value;
4186 /* Move pointer to ahead of TDLSOFFCH*/
4187 value += 26;
4188 sscanf(value, "%d", &set_value);
4189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4190 "%s: Tdls offchannel offset:%d",
4191 __func__, set_value);
4192 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4193 if (ret < 0)
4194 {
4195 ret = -EINVAL;
4196 goto exit;
4197 }
4198
4199 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4200 tANI_U8 *value = command;
4201 int set_value;
4202 /* Move pointer to ahead of tdlsoffchnmode*/
4203 value += 18;
4204 sscanf(value, "%d", &set_value);
4205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4206 "%s: Tdls offchannel mode:%d",
4207 __func__, set_value);
4208 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4209 if (ret < 0)
4210 {
4211 ret = -EINVAL;
4212 goto exit;
4213 }
4214 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4215 tANI_U8 *value = command;
4216 int set_value;
4217 /* Move pointer to ahead of TDLSOFFCH*/
4218 value += 14;
4219 sscanf(value, "%d", &set_value);
4220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4221 "%s: Tdls offchannel num: %d",
4222 __func__, set_value);
4223 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4224 if (ret < 0)
4225 {
4226 ret = -EINVAL;
4227 goto exit;
4228 }
4229 }
4230#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304231 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4232 {
4233 eHalStatus status;
4234 char *buf = NULL;
4235 char len;
4236 long waitRet;
4237 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304238 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304239 tANI_U8 *ptr = command;
4240 int stats = *(ptr + 11) - '0';
4241
4242 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4243 if (!IS_FEATURE_FW_STATS_ENABLE)
4244 {
4245 hddLog(VOS_TRACE_LEVEL_INFO,
4246 FL("Get Firmware stats feature not supported"));
4247 ret = -EINVAL;
4248 goto exit;
4249 }
4250
4251 if (FW_STATS_MAX <= stats || 0 >= stats)
4252 {
4253 hddLog(VOS_TRACE_LEVEL_INFO,
4254 FL(" stats %d not supported"),stats);
4255 ret = -EINVAL;
4256 goto exit;
4257 }
4258
4259 init_completion(&(fwStatsCtx.completion));
4260 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4261 fwStatsCtx.pAdapter = pAdapter;
4262 fwStatsRsp->type = 0;
4263 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304264 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304265 if (eHAL_STATUS_SUCCESS != status)
4266 {
4267 hddLog(VOS_TRACE_LEVEL_ERROR,
4268 FL(" fail to post WDA cmd status = %d"), status);
4269 ret = -EINVAL;
4270 goto exit;
4271 }
4272 waitRet = wait_for_completion_timeout
4273 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4274 if (waitRet <= 0)
4275 {
4276 hddLog(VOS_TRACE_LEVEL_ERROR,
4277 FL("failed to wait on GwtFwstats"));
4278 //Make magic number to zero so that callback is not executed.
4279 spin_lock(&hdd_context_lock);
4280 fwStatsCtx.magic = 0x0;
4281 spin_unlock(&hdd_context_lock);
4282 ret = -EINVAL;
4283 goto exit;
4284 }
4285 if (fwStatsRsp->type)
4286 {
4287 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4288 if (!buf)
4289 {
4290 hddLog(VOS_TRACE_LEVEL_ERROR,
4291 FL(" failed to allocate memory"));
4292 ret = -ENOMEM;
4293 goto exit;
4294 }
4295 switch( fwStatsRsp->type )
4296 {
4297 case FW_UBSP_STATS:
4298 {
4299 len = snprintf(buf, FW_STATE_RSP_LEN,
4300 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304301 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4302 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304303 }
4304 break;
4305 default:
4306 {
4307 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4308 ret = -EFAULT;
4309 kfree(buf);
4310 goto exit;
4311 }
4312 }
4313 if (copy_to_user(priv_data.buf, buf, len + 1))
4314 {
4315 hddLog(VOS_TRACE_LEVEL_ERROR,
4316 FL(" failed to copy data to user buffer"));
4317 ret = -EFAULT;
4318 kfree(buf);
4319 goto exit;
4320 }
4321 ret = len;
4322 kfree(buf);
4323 }
4324 else
4325 {
4326 hddLog(VOS_TRACE_LEVEL_ERROR,
4327 FL("failed to fetch the stats"));
4328 ret = -EFAULT;
4329 goto exit;
4330 }
4331
4332 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004333 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304334 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4335 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4336 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304337 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4338 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004339 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004340 }
4341exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304342 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004343 if (command)
4344 {
4345 kfree(command);
4346 }
4347 return ret;
4348}
4349
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004350#ifdef CONFIG_COMPAT
4351static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4352{
4353 struct {
4354 compat_uptr_t buf;
4355 int used_len;
4356 int total_len;
4357 } compat_priv_data;
4358 hdd_priv_data_t priv_data;
4359 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004360
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004361 /*
4362 * Note that pAdapter and ifr have already been verified by caller,
4363 * and HDD context has also been validated
4364 */
4365 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4366 sizeof(compat_priv_data))) {
4367 ret = -EFAULT;
4368 goto exit;
4369 }
4370 priv_data.buf = compat_ptr(compat_priv_data.buf);
4371 priv_data.used_len = compat_priv_data.used_len;
4372 priv_data.total_len = compat_priv_data.total_len;
4373 ret = hdd_driver_command(pAdapter, &priv_data);
4374 exit:
4375 return ret;
4376}
4377#else /* CONFIG_COMPAT */
4378static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4379{
4380 /* will never be invoked */
4381 return 0;
4382}
4383#endif /* CONFIG_COMPAT */
4384
4385static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4386{
4387 hdd_priv_data_t priv_data;
4388 int ret = 0;
4389
4390 /*
4391 * Note that pAdapter and ifr have already been verified by caller,
4392 * and HDD context has also been validated
4393 */
4394 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4395 ret = -EFAULT;
4396 } else {
4397 ret = hdd_driver_command(pAdapter, &priv_data);
4398 }
4399 return ret;
4400}
4401
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304402int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004403{
4404 hdd_adapter_t *pAdapter;
4405 hdd_context_t *pHddCtx;
4406 int ret;
4407
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304408 ENTER();
4409
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004410 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4411 if (NULL == pAdapter) {
4412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4413 "%s: HDD adapter context is Null", __func__);
4414 ret = -ENODEV;
4415 goto exit;
4416 }
4417 if (dev != pAdapter->dev) {
4418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4419 "%s: HDD adapter/dev inconsistency", __func__);
4420 ret = -ENODEV;
4421 goto exit;
4422 }
4423
4424 if ((!ifr) || (!ifr->ifr_data)) {
4425 ret = -EINVAL;
4426 goto exit;
4427 }
4428
4429 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4430 ret = wlan_hdd_validate_context(pHddCtx);
4431 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004432 ret = -EBUSY;
4433 goto exit;
4434 }
4435
4436 switch (cmd) {
4437 case (SIOCDEVPRIVATE + 1):
4438 if (is_compat_task())
4439 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4440 else
4441 ret = hdd_driver_ioctl(pAdapter, ifr);
4442 break;
4443 default:
4444 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4445 __func__, cmd);
4446 ret = -EINVAL;
4447 break;
4448 }
4449 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304450 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004451 return ret;
4452}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004453
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304454int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4455{
4456 int ret;
4457
4458 vos_ssr_protect(__func__);
4459 ret = __hdd_ioctl(dev, ifr, cmd);
4460 vos_ssr_unprotect(__func__);
4461
4462 return ret;
4463}
4464
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004465#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004466/**---------------------------------------------------------------------------
4467
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004468 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004469
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004470 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004471 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4472 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4473 <space>Scan Mode N<space>Meas Duration N
4474 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4475 then take N.
4476 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4477 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4478 This function does not take care of removing duplicate channels from the list
4479
4480 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004481 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004482
4483 \return - 0 for success non-zero for failure
4484
4485 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004486static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4487 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004488{
4489 tANI_U8 *inPtr = pValue;
4490 int tempInt = 0;
4491 int j = 0, i = 0, v = 0;
4492 char buf[32];
4493
4494 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4495 /*no argument after the command*/
4496 if (NULL == inPtr)
4497 {
4498 return -EINVAL;
4499 }
4500 /*no space after the command*/
4501 else if (SPACE_ASCII_VALUE != *inPtr)
4502 {
4503 return -EINVAL;
4504 }
4505
4506 /*removing empty spaces*/
4507 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4508
4509 /*no argument followed by spaces*/
4510 if ('\0' == *inPtr) return -EINVAL;
4511
4512 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004513 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004514 if (1 != v) return -EINVAL;
4515
4516 v = kstrtos32(buf, 10, &tempInt);
4517 if ( v < 0) return -EINVAL;
4518
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004519 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004520
4521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004522 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004523
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004524 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004525 {
4526 for (i = 0; i < 4; i++)
4527 {
4528 /*inPtr pointing to the beginning of first space after number of ie fields*/
4529 inPtr = strpbrk( inPtr, " " );
4530 /*no ie data after the number of ie fields argument*/
4531 if (NULL == inPtr) return -EINVAL;
4532
4533 /*removing empty space*/
4534 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4535
4536 /*no ie data after the number of ie fields argument and spaces*/
4537 if ( '\0' == *inPtr ) return -EINVAL;
4538
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004539 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004540 if (1 != v) return -EINVAL;
4541
4542 v = kstrtos32(buf, 10, &tempInt);
4543 if (v < 0) return -EINVAL;
4544
4545 switch (i)
4546 {
4547 case 0: /* Measurement token */
4548 if (tempInt <= 0)
4549 {
4550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4551 "Invalid Measurement Token(%d)", tempInt);
4552 return -EINVAL;
4553 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004554 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004555 break;
4556
4557 case 1: /* Channel number */
4558 if ((tempInt <= 0) ||
4559 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4560 {
4561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4562 "Invalid Channel Number(%d)", tempInt);
4563 return -EINVAL;
4564 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004565 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004566 break;
4567
4568 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004569 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004570 {
4571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4572 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4573 return -EINVAL;
4574 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004575 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004576 break;
4577
4578 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004579 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4580 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004581 {
4582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4583 "Invalid Measurement Duration(%d)", tempInt);
4584 return -EINVAL;
4585 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004586 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004587 break;
4588 }
4589 }
4590 }
4591
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004592 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004593 {
4594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304595 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004596 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597 pEseBcnReq->bcnReq[j].measurementToken,
4598 pEseBcnReq->bcnReq[j].channel,
4599 pEseBcnReq->bcnReq[j].scanMode,
4600 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004601 }
4602
4603 return VOS_STATUS_SUCCESS;
4604}
4605
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004606static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4607{
4608 struct statsContext *pStatsContext = NULL;
4609 hdd_adapter_t *pAdapter = NULL;
4610
4611 if (NULL == pContext)
4612 {
4613 hddLog(VOS_TRACE_LEVEL_ERROR,
4614 "%s: Bad param, pContext [%p]",
4615 __func__, pContext);
4616 return;
4617 }
4618
Jeff Johnson72a40512013-12-19 10:14:15 -08004619 /* there is a race condition that exists between this callback
4620 function and the caller since the caller could time out either
4621 before or while this code is executing. we use a spinlock to
4622 serialize these actions */
4623 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004624
4625 pStatsContext = pContext;
4626 pAdapter = pStatsContext->pAdapter;
4627 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4628 {
4629 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004630 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004631 hddLog(VOS_TRACE_LEVEL_WARN,
4632 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4633 __func__, pAdapter, pStatsContext->magic);
4634 return;
4635 }
4636
Jeff Johnson72a40512013-12-19 10:14:15 -08004637 /* context is valid so caller is still waiting */
4638
4639 /* paranoia: invalidate the magic */
4640 pStatsContext->magic = 0;
4641
4642 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004643 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4644 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4645 tsmMetrics.UplinkPktQueueDlyHist,
4646 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4647 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4648 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4649 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4650 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4651 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4652 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4653
Jeff Johnson72a40512013-12-19 10:14:15 -08004654 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004655 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004656
4657 /* serialization is complete */
4658 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004659}
4660
4661
4662
4663static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4664 tAniTrafStrmMetrics* pTsmMetrics)
4665{
4666 hdd_station_ctx_t *pHddStaCtx = NULL;
4667 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004668 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004669 long lrc;
4670 struct statsContext context;
4671 hdd_context_t *pHddCtx = NULL;
4672
4673 if (NULL == pAdapter)
4674 {
4675 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4676 return VOS_STATUS_E_FAULT;
4677 }
4678
4679 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4680 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4681
4682 /* we are connected prepare our callback context */
4683 init_completion(&context.completion);
4684 context.pAdapter = pAdapter;
4685 context.magic = STATS_CONTEXT_MAGIC;
4686
4687 /* query tsm stats */
4688 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4689 pHddStaCtx->conn_info.staId[ 0 ],
4690 pHddStaCtx->conn_info.bssId,
4691 &context, pHddCtx->pvosContext, tid);
4692
4693 if (eHAL_STATUS_SUCCESS != hstatus)
4694 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4696 __func__);
4697 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004698 }
4699 else
4700 {
4701 /* request was sent -- wait for the response */
4702 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4703 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004704 if (lrc <= 0)
4705 {
4706 hddLog(VOS_TRACE_LEVEL_ERROR,
4707 "%s: SME %s while retrieving statistics",
4708 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004709 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004710 }
4711 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004712
Jeff Johnson72a40512013-12-19 10:14:15 -08004713 /* either we never sent a request, we sent a request and received a
4714 response or we sent a request and timed out. if we never sent a
4715 request or if we sent a request and got a response, we want to
4716 clear the magic out of paranoia. if we timed out there is a
4717 race condition such that the callback function could be
4718 executing at the same time we are. of primary concern is if the
4719 callback function had already verified the "magic" but had not
4720 yet set the completion variable when a timeout occurred. we
4721 serialize these activities by invalidating the magic while
4722 holding a shared spinlock which will cause us to block if the
4723 callback is currently executing */
4724 spin_lock(&hdd_context_lock);
4725 context.magic = 0;
4726 spin_unlock(&hdd_context_lock);
4727
4728 if (VOS_STATUS_SUCCESS == vstatus)
4729 {
4730 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4731 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4732 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4733 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4734 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4735 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4736 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4737 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4738 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4739 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4740 }
4741 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004742}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004743#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004744
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004745#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004746void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4747{
4748 eCsrBand band = -1;
4749 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4750 switch (band)
4751 {
4752 case eCSR_BAND_ALL:
4753 *pBand = WLAN_HDD_UI_BAND_AUTO;
4754 break;
4755
4756 case eCSR_BAND_24:
4757 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4758 break;
4759
4760 case eCSR_BAND_5G:
4761 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4762 break;
4763
4764 default:
4765 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4766 *pBand = -1;
4767 break;
4768 }
4769}
4770
4771/**---------------------------------------------------------------------------
4772
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004773 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4774
4775 This function parses the send action frame data passed in the format
4776 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4777
Srinivas Girigowda56076852013-08-20 14:00:50 -07004778 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004779 \param - pTargetApBssid Pointer to target Ap bssid
4780 \param - pChannel Pointer to the Target AP channel
4781 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4782 \param - pBuf Pointer to data
4783 \param - pBufLen Pointer to data length
4784
4785 \return - 0 for success non-zero for failure
4786
4787 --------------------------------------------------------------------------*/
4788VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4789 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4790{
4791 tANI_U8 *inPtr = pValue;
4792 tANI_U8 *dataEnd;
4793 int tempInt;
4794 int j = 0;
4795 int i = 0;
4796 int v = 0;
4797 tANI_U8 tempBuf[32];
4798 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004799 /* 12 hexa decimal digits, 5 ':' and '\0' */
4800 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004801
4802 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4803 /*no argument after the command*/
4804 if (NULL == inPtr)
4805 {
4806 return -EINVAL;
4807 }
4808
4809 /*no space after the command*/
4810 else if (SPACE_ASCII_VALUE != *inPtr)
4811 {
4812 return -EINVAL;
4813 }
4814
4815 /*removing empty spaces*/
4816 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4817
4818 /*no argument followed by spaces*/
4819 if ('\0' == *inPtr)
4820 {
4821 return -EINVAL;
4822 }
4823
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004824 v = sscanf(inPtr, "%17s", macAddress);
4825 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004826 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4828 "Invalid MAC address or All hex inputs are not read (%d)", v);
4829 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004830 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004831
4832 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4833 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4834 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4835 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4836 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4837 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004838
4839 /* point to the next argument */
4840 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4841 /*no argument after the command*/
4842 if (NULL == inPtr) return -EINVAL;
4843
4844 /*removing empty spaces*/
4845 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4846
4847 /*no argument followed by spaces*/
4848 if ('\0' == *inPtr)
4849 {
4850 return -EINVAL;
4851 }
4852
4853 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004854 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004855 if (1 != v) return -EINVAL;
4856
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004857 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304858 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304859 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004860
4861 *pChannel = tempInt;
4862
4863 /* point to the next argument */
4864 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4865 /*no argument after the command*/
4866 if (NULL == inPtr) return -EINVAL;
4867 /*removing empty spaces*/
4868 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4869
4870 /*no argument followed by spaces*/
4871 if ('\0' == *inPtr)
4872 {
4873 return -EINVAL;
4874 }
4875
4876 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004877 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004878 if (1 != v) return -EINVAL;
4879
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004880 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004881 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004882
4883 *pDwellTime = tempInt;
4884
4885 /* point to the next argument */
4886 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4887 /*no argument after the command*/
4888 if (NULL == inPtr) return -EINVAL;
4889 /*removing empty spaces*/
4890 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4891
4892 /*no argument followed by spaces*/
4893 if ('\0' == *inPtr)
4894 {
4895 return -EINVAL;
4896 }
4897
4898 /* find the length of data */
4899 dataEnd = inPtr;
4900 while(('\0' != *dataEnd) )
4901 {
4902 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004903 }
Kiet Lambe150c22013-11-21 16:30:32 +05304904 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004905 if ( *pBufLen <= 0) return -EINVAL;
4906
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004907 /* Allocate the number of bytes based on the number of input characters
4908 whether it is even or odd.
4909 if the number of input characters are even, then we need N/2 byte.
4910 if the number of input characters are odd, then we need do (N+1)/2 to
4911 compensate rounding off.
4912 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4913 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4914 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004915 if (NULL == *pBuf)
4916 {
4917 hddLog(VOS_TRACE_LEVEL_FATAL,
4918 "%s: vos_mem_alloc failed ", __func__);
4919 return -EINVAL;
4920 }
4921
4922 /* the buffer received from the upper layer is character buffer,
4923 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4924 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4925 and f0 in 3rd location */
4926 for (i = 0, j = 0; j < *pBufLen; j += 2)
4927 {
Kiet Lambe150c22013-11-21 16:30:32 +05304928 if( j+1 == *pBufLen)
4929 {
4930 tempByte = hdd_parse_hex(inPtr[j]);
4931 }
4932 else
4933 {
4934 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4935 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004936 (*pBuf)[i++] = tempByte;
4937 }
4938 *pBufLen = i;
4939 return VOS_STATUS_SUCCESS;
4940}
4941
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004942/**---------------------------------------------------------------------------
4943
Srinivas Girigowdade697412013-02-14 16:31:48 -08004944 \brief hdd_parse_channellist() - HDD Parse channel list
4945
4946 This function parses the channel list passed in the format
4947 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004948 if the Number of channels (N) does not match with the actual number of channels passed
4949 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4950 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4951 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4952 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004953
4954 \param - pValue Pointer to input channel list
4955 \param - ChannelList Pointer to local output array to record channel list
4956 \param - pNumChannels Pointer to number of roam scan channels
4957
4958 \return - 0 for success non-zero for failure
4959
4960 --------------------------------------------------------------------------*/
4961VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4962{
4963 tANI_U8 *inPtr = pValue;
4964 int tempInt;
4965 int j = 0;
4966 int v = 0;
4967 char buf[32];
4968
4969 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4970 /*no argument after the command*/
4971 if (NULL == inPtr)
4972 {
4973 return -EINVAL;
4974 }
4975
4976 /*no space after the command*/
4977 else if (SPACE_ASCII_VALUE != *inPtr)
4978 {
4979 return -EINVAL;
4980 }
4981
4982 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004983 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004984
4985 /*no argument followed by spaces*/
4986 if ('\0' == *inPtr)
4987 {
4988 return -EINVAL;
4989 }
4990
4991 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004992 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004993 if (1 != v) return -EINVAL;
4994
Srinivas Girigowdade697412013-02-14 16:31:48 -08004995 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004996 if ((v < 0) ||
4997 (tempInt <= 0) ||
4998 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
4999 {
5000 return -EINVAL;
5001 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005002
5003 *pNumChannels = tempInt;
5004
5005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5006 "Number of channels are: %d", *pNumChannels);
5007
5008 for (j = 0; j < (*pNumChannels); j++)
5009 {
5010 /*inPtr pointing to the beginning of first space after number of channels*/
5011 inPtr = strpbrk( inPtr, " " );
5012 /*no channel list after the number of channels argument*/
5013 if (NULL == inPtr)
5014 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005015 if (0 != j)
5016 {
5017 *pNumChannels = j;
5018 return VOS_STATUS_SUCCESS;
5019 }
5020 else
5021 {
5022 return -EINVAL;
5023 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005024 }
5025
5026 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005027 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005028
5029 /*no channel list after the number of channels argument and spaces*/
5030 if ( '\0' == *inPtr )
5031 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005032 if (0 != j)
5033 {
5034 *pNumChannels = j;
5035 return VOS_STATUS_SUCCESS;
5036 }
5037 else
5038 {
5039 return -EINVAL;
5040 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005041 }
5042
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005043 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005044 if (1 != v) return -EINVAL;
5045
Srinivas Girigowdade697412013-02-14 16:31:48 -08005046 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005047 if ((v < 0) ||
5048 (tempInt <= 0) ||
5049 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5050 {
5051 return -EINVAL;
5052 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005053 pChannelList[j] = tempInt;
5054
5055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5056 "Channel %d added to preferred channel list",
5057 pChannelList[j] );
5058 }
5059
Srinivas Girigowdade697412013-02-14 16:31:48 -08005060 return VOS_STATUS_SUCCESS;
5061}
5062
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005063
5064/**---------------------------------------------------------------------------
5065
5066 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5067
5068 This function parses the reasoc command data passed in the format
5069 REASSOC<space><bssid><space><channel>
5070
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005071 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005072 \param - pTargetApBssid Pointer to target Ap bssid
5073 \param - pChannel Pointer to the Target AP channel
5074
5075 \return - 0 for success non-zero for failure
5076
5077 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005078VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5079 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005080{
5081 tANI_U8 *inPtr = pValue;
5082 int tempInt;
5083 int v = 0;
5084 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005085 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005086 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005087
5088 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5089 /*no argument after the command*/
5090 if (NULL == inPtr)
5091 {
5092 return -EINVAL;
5093 }
5094
5095 /*no space after the command*/
5096 else if (SPACE_ASCII_VALUE != *inPtr)
5097 {
5098 return -EINVAL;
5099 }
5100
5101 /*removing empty spaces*/
5102 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5103
5104 /*no argument followed by spaces*/
5105 if ('\0' == *inPtr)
5106 {
5107 return -EINVAL;
5108 }
5109
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005110 v = sscanf(inPtr, "%17s", macAddress);
5111 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005112 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5114 "Invalid MAC address or All hex inputs are not read (%d)", v);
5115 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005116 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005117
5118 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5119 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5120 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5121 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5122 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5123 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005124
5125 /* point to the next argument */
5126 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5127 /*no argument after the command*/
5128 if (NULL == inPtr) return -EINVAL;
5129
5130 /*removing empty spaces*/
5131 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5132
5133 /*no argument followed by spaces*/
5134 if ('\0' == *inPtr)
5135 {
5136 return -EINVAL;
5137 }
5138
5139 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005140 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005141 if (1 != v) return -EINVAL;
5142
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005143 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005144 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305145 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005146 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5147 {
5148 return -EINVAL;
5149 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005150
5151 *pChannel = tempInt;
5152 return VOS_STATUS_SUCCESS;
5153}
5154
5155#endif
5156
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005157#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005158/**---------------------------------------------------------------------------
5159
5160 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5161
5162 This function parses the SETCCKM IE command
5163 SETCCKMIE<space><ie data>
5164
5165 \param - pValue Pointer to input data
5166 \param - pCckmIe Pointer to output cckm Ie
5167 \param - pCckmIeLen Pointer to output cckm ie length
5168
5169 \return - 0 for success non-zero for failure
5170
5171 --------------------------------------------------------------------------*/
5172VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5173 tANI_U8 *pCckmIeLen)
5174{
5175 tANI_U8 *inPtr = pValue;
5176 tANI_U8 *dataEnd;
5177 int j = 0;
5178 int i = 0;
5179 tANI_U8 tempByte = 0;
5180
5181 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5182 /*no argument after the command*/
5183 if (NULL == inPtr)
5184 {
5185 return -EINVAL;
5186 }
5187
5188 /*no space after the command*/
5189 else if (SPACE_ASCII_VALUE != *inPtr)
5190 {
5191 return -EINVAL;
5192 }
5193
5194 /*removing empty spaces*/
5195 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5196
5197 /*no argument followed by spaces*/
5198 if ('\0' == *inPtr)
5199 {
5200 return -EINVAL;
5201 }
5202
5203 /* find the length of data */
5204 dataEnd = inPtr;
5205 while(('\0' != *dataEnd) )
5206 {
5207 dataEnd++;
5208 ++(*pCckmIeLen);
5209 }
5210 if ( *pCckmIeLen <= 0) return -EINVAL;
5211
5212 /* Allocate the number of bytes based on the number of input characters
5213 whether it is even or odd.
5214 if the number of input characters are even, then we need N/2 byte.
5215 if the number of input characters are odd, then we need do (N+1)/2 to
5216 compensate rounding off.
5217 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5218 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5219 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5220 if (NULL == *pCckmIe)
5221 {
5222 hddLog(VOS_TRACE_LEVEL_FATAL,
5223 "%s: vos_mem_alloc failed ", __func__);
5224 return -EINVAL;
5225 }
5226 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5227 /* the buffer received from the upper layer is character buffer,
5228 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5229 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5230 and f0 in 3rd location */
5231 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5232 {
5233 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5234 (*pCckmIe)[i++] = tempByte;
5235 }
5236 *pCckmIeLen = i;
5237
5238 return VOS_STATUS_SUCCESS;
5239}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005240#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005241
Jeff Johnson295189b2012-06-20 16:38:30 -07005242/**---------------------------------------------------------------------------
5243
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005244 \brief hdd_is_valid_mac_address() - Validate MAC address
5245
5246 This function validates whether the given MAC address is valid or not
5247 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5248 where X is the hexa decimal digit character and separated by ':'
5249 This algorithm works even if MAC address is not separated by ':'
5250
5251 This code checks given input string mac contains exactly 12 hexadecimal digits.
5252 and a separator colon : appears in the input string only after
5253 an even number of hex digits.
5254
5255 \param - pMacAddr pointer to the input MAC address
5256 \return - 1 for valid and 0 for invalid
5257
5258 --------------------------------------------------------------------------*/
5259
5260v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5261{
5262 int xdigit = 0;
5263 int separator = 0;
5264 while (*pMacAddr)
5265 {
5266 if (isxdigit(*pMacAddr))
5267 {
5268 xdigit++;
5269 }
5270 else if (':' == *pMacAddr)
5271 {
5272 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5273 break;
5274
5275 ++separator;
5276 }
5277 else
5278 {
5279 separator = -1;
5280 /* Invalid MAC found */
5281 return 0;
5282 }
5283 ++pMacAddr;
5284 }
5285 return (xdigit == 12 && (separator == 5 || separator == 0));
5286}
5287
5288/**---------------------------------------------------------------------------
5289
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305290 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005291
5292 \param - dev Pointer to net_device structure
5293
5294 \return - 0 for success non-zero for failure
5295
5296 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305297int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005298{
5299 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5300 hdd_context_t *pHddCtx;
5301 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5302 VOS_STATUS status;
5303 v_BOOL_t in_standby = TRUE;
5304
5305 if (NULL == pAdapter)
5306 {
5307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305308 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 return -ENODEV;
5310 }
5311
5312 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305313 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5314 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005315 if (NULL == pHddCtx)
5316 {
5317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005318 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005319 return -ENODEV;
5320 }
5321
5322 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5323 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5324 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005325 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5326 {
5327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305328 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005329 in_standby = FALSE;
5330 break;
5331 }
5332 else
5333 {
5334 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5335 pAdapterNode = pNext;
5336 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 }
5338
5339 if (TRUE == in_standby)
5340 {
5341 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5342 {
5343 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5344 "wlan out of power save", __func__);
5345 return -EINVAL;
5346 }
5347 }
5348
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005349 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005350 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5351 {
5352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005353 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005354 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305355 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005356 netif_tx_start_all_queues(dev);
5357 }
5358
5359 return 0;
5360}
5361
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305362/**---------------------------------------------------------------------------
5363
5364 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5365
5366 This is called in response to ifconfig up
5367
5368 \param - dev Pointer to net_device structure
5369
5370 \return - 0 for success non-zero for failure
5371
5372 --------------------------------------------------------------------------*/
5373int hdd_open(struct net_device *dev)
5374{
5375 int ret;
5376
5377 vos_ssr_protect(__func__);
5378 ret = __hdd_open(dev);
5379 vos_ssr_unprotect(__func__);
5380
5381 return ret;
5382}
5383
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305384int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005385{
5386 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5387
5388 if(pAdapter == NULL) {
5389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005390 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005391 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 }
5393
5394 netif_start_queue(dev);
5395
5396 return 0;
5397}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305398
5399int hdd_mon_open (struct net_device *dev)
5400{
5401 int ret;
5402
5403 vos_ssr_protect(__func__);
5404 ret = __hdd_mon_open(dev);
5405 vos_ssr_unprotect(__func__);
5406
5407 return ret;
5408}
5409
Jeff Johnson295189b2012-06-20 16:38:30 -07005410/**---------------------------------------------------------------------------
5411
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305412 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005413
5414 \param - dev Pointer to net_device structure
5415
5416 \return - 0 for success non-zero for failure
5417
5418 --------------------------------------------------------------------------*/
5419
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305420int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005421{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305422 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5424 hdd_context_t *pHddCtx;
5425 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5426 VOS_STATUS status;
5427 v_BOOL_t enter_standby = TRUE;
5428
5429 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005430 if (NULL == pAdapter)
5431 {
5432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305433 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 return -ENODEV;
5435 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305436 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305437 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305438
5439 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5440 ret = wlan_hdd_validate_context(pHddCtx);
5441 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005442 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305443 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005444 }
5445
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305446 /* Nothing to be done if the interface is not opened */
5447 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5448 {
5449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5450 "%s: NETDEV Interface is not OPENED", __func__);
5451 return -ENODEV;
5452 }
5453
5454 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005455 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005456 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305457
5458 /* Disable TX on the interface, after this hard_start_xmit() will not
5459 * be called on that interface
5460 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305461 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305463
5464 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005465 netif_carrier_off(pAdapter->dev);
5466
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305467 /* The interface is marked as down for outside world (aka kernel)
5468 * But the driver is pretty much alive inside. The driver needs to
5469 * tear down the existing connection on the netdev (session)
5470 * cleanup the data pipes and wait until the control plane is stabilized
5471 * for this interface. The call also needs to wait until the above
5472 * mentioned actions are completed before returning to the caller.
5473 * Notice that the hdd_stop_adapter is requested not to close the session
5474 * That is intentional to be able to scan if it is a STA/P2P interface
5475 */
5476 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305477#ifdef FEATURE_WLAN_TDLS
5478 mutex_lock(&pHddCtx->tdls_lock);
5479#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305480 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305481 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305482#ifdef FEATURE_WLAN_TDLS
5483 mutex_unlock(&pHddCtx->tdls_lock);
5484#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005485 /* SoftAP ifaces should never go in power save mode
5486 making sure same here. */
5487 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5488 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005489 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 )
5491 {
5492 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5494 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005495 EXIT();
5496 return 0;
5497 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305498 /* Find if any iface is up. If any iface is up then can't put device to
5499 * sleep/power save mode
5500 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005501 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5502 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5503 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005504 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5505 {
5506 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305507 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005508 enter_standby = FALSE;
5509 break;
5510 }
5511 else
5512 {
5513 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5514 pAdapterNode = pNext;
5515 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 }
5517
5518 if (TRUE == enter_standby)
5519 {
5520 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5521 "entering standby", __func__);
5522 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5523 {
5524 /*log and return success*/
5525 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5526 "wlan in power save", __func__);
5527 }
5528 }
5529
5530 EXIT();
5531 return 0;
5532}
5533
5534/**---------------------------------------------------------------------------
5535
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305536 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005537
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305538 This is called in response to ifconfig down
5539
5540 \param - dev Pointer to net_device structure
5541
5542 \return - 0 for success non-zero for failure
5543-----------------------------------------------------------------------------*/
5544int hdd_stop (struct net_device *dev)
5545{
5546 int ret;
5547
5548 vos_ssr_protect(__func__);
5549 ret = __hdd_stop(dev);
5550 vos_ssr_unprotect(__func__);
5551
5552 return ret;
5553}
5554
5555/**---------------------------------------------------------------------------
5556
5557 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005558
5559 \param - dev Pointer to net_device structure
5560
5561 \return - void
5562
5563 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305564static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005565{
5566 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305567 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005568 ENTER();
5569
5570 do
5571 {
5572 if (NULL == pAdapter)
5573 {
5574 hddLog(VOS_TRACE_LEVEL_FATAL,
5575 "%s: NULL pAdapter", __func__);
5576 break;
5577 }
5578
5579 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5580 {
5581 hddLog(VOS_TRACE_LEVEL_FATAL,
5582 "%s: Invalid magic", __func__);
5583 break;
5584 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305585 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5586 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005587 {
5588 hddLog(VOS_TRACE_LEVEL_FATAL,
5589 "%s: NULL pHddCtx", __func__);
5590 break;
5591 }
5592
5593 if (dev != pAdapter->dev)
5594 {
5595 hddLog(VOS_TRACE_LEVEL_FATAL,
5596 "%s: Invalid device reference", __func__);
5597 /* we haven't validated all cases so let this go for now */
5598 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305599#ifdef FEATURE_WLAN_TDLS
5600 mutex_lock(&pHddCtx->tdls_lock);
5601#endif
c_hpothu002231a2015-02-05 14:58:51 +05305602 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305603#ifdef FEATURE_WLAN_TDLS
5604 mutex_unlock(&pHddCtx->tdls_lock);
5605#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005606
5607 /* after uninit our adapter structure will no longer be valid */
5608 pAdapter->dev = NULL;
5609 pAdapter->magic = 0;
5610 } while (0);
5611
5612 EXIT();
5613}
5614
5615/**---------------------------------------------------------------------------
5616
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305617 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5618
5619 This is called during the netdev unregister to uninitialize all data
5620associated with the device
5621
5622 \param - dev Pointer to net_device structure
5623
5624 \return - void
5625
5626 --------------------------------------------------------------------------*/
5627static void hdd_uninit (struct net_device *dev)
5628{
5629 vos_ssr_protect(__func__);
5630 __hdd_uninit(dev);
5631 vos_ssr_unprotect(__func__);
5632}
5633
5634/**---------------------------------------------------------------------------
5635
Jeff Johnson295189b2012-06-20 16:38:30 -07005636 \brief hdd_release_firmware() -
5637
5638 This function calls the release firmware API to free the firmware buffer.
5639
5640 \param - pFileName Pointer to the File Name.
5641 pCtx - Pointer to the adapter .
5642
5643
5644 \return - 0 for success, non zero for failure
5645
5646 --------------------------------------------------------------------------*/
5647
5648VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5649{
5650 VOS_STATUS status = VOS_STATUS_SUCCESS;
5651 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5652 ENTER();
5653
5654
5655 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5656
5657 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5658
5659 if(pHddCtx->fw) {
5660 release_firmware(pHddCtx->fw);
5661 pHddCtx->fw = NULL;
5662 }
5663 else
5664 status = VOS_STATUS_E_FAILURE;
5665 }
5666 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5667 if(pHddCtx->nv) {
5668 release_firmware(pHddCtx->nv);
5669 pHddCtx->nv = NULL;
5670 }
5671 else
5672 status = VOS_STATUS_E_FAILURE;
5673
5674 }
5675
5676 EXIT();
5677 return status;
5678}
5679
5680/**---------------------------------------------------------------------------
5681
5682 \brief hdd_request_firmware() -
5683
5684 This function reads the firmware file using the request firmware
5685 API and returns the the firmware data and the firmware file size.
5686
5687 \param - pfileName - Pointer to the file name.
5688 - pCtx - Pointer to the adapter .
5689 - ppfw_data - Pointer to the pointer of the firmware data.
5690 - pSize - Pointer to the file size.
5691
5692 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5693
5694 --------------------------------------------------------------------------*/
5695
5696
5697VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5698{
5699 int status;
5700 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5701 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5702 ENTER();
5703
5704 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5705
5706 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5707
5708 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5709 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5710 __func__, pfileName);
5711 retval = VOS_STATUS_E_FAILURE;
5712 }
5713
5714 else {
5715 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5716 *pSize = pHddCtx->fw->size;
5717 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5718 __func__, *pSize);
5719 }
5720 }
5721 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5722
5723 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5724
5725 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5726 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5727 __func__, pfileName);
5728 retval = VOS_STATUS_E_FAILURE;
5729 }
5730
5731 else {
5732 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5733 *pSize = pHddCtx->nv->size;
5734 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5735 __func__, *pSize);
5736 }
5737 }
5738
5739 EXIT();
5740 return retval;
5741}
5742/**---------------------------------------------------------------------------
5743 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5744
5745 This is the function invoked by SME to inform the result of a full power
5746 request issued by HDD
5747
5748 \param - callbackcontext - Pointer to cookie
5749 status - result of request
5750
5751 \return - None
5752
5753--------------------------------------------------------------------------*/
5754void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5755{
5756 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5757
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005758 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 if(&pHddCtx->full_pwr_comp_var)
5760 {
5761 complete(&pHddCtx->full_pwr_comp_var);
5762 }
5763}
5764
5765/**---------------------------------------------------------------------------
5766
5767 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5768
5769 This is the function invoked by SME to inform the result of BMPS
5770 request issued by HDD
5771
5772 \param - callbackcontext - Pointer to cookie
5773 status - result of request
5774
5775 \return - None
5776
5777--------------------------------------------------------------------------*/
5778void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5779{
5780
5781 struct completion *completion_var = (struct completion*) callbackContext;
5782
Arif Hussain6d2a3322013-11-17 19:50:10 -08005783 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005784 if(completion_var != NULL)
5785 {
5786 complete(completion_var);
5787 }
5788}
5789
5790/**---------------------------------------------------------------------------
5791
5792 \brief hdd_get_cfg_file_size() -
5793
5794 This function reads the configuration file using the request firmware
5795 API and returns the configuration file size.
5796
5797 \param - pCtx - Pointer to the adapter .
5798 - pFileName - Pointer to the file name.
5799 - pBufSize - Pointer to the buffer size.
5800
5801 \return - 0 for success, non zero for failure
5802
5803 --------------------------------------------------------------------------*/
5804
5805VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5806{
5807 int status;
5808 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5809
5810 ENTER();
5811
5812 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5813
5814 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5815 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5816 status = VOS_STATUS_E_FAILURE;
5817 }
5818 else {
5819 *pBufSize = pHddCtx->fw->size;
5820 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5821 release_firmware(pHddCtx->fw);
5822 pHddCtx->fw = NULL;
5823 }
5824
5825 EXIT();
5826 return VOS_STATUS_SUCCESS;
5827}
5828
5829/**---------------------------------------------------------------------------
5830
5831 \brief hdd_read_cfg_file() -
5832
5833 This function reads the configuration file using the request firmware
5834 API and returns the cfg data and the buffer size of the configuration file.
5835
5836 \param - pCtx - Pointer to the adapter .
5837 - pFileName - Pointer to the file name.
5838 - pBuffer - Pointer to the data buffer.
5839 - pBufSize - Pointer to the buffer size.
5840
5841 \return - 0 for success, non zero for failure
5842
5843 --------------------------------------------------------------------------*/
5844
5845VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5846 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5847{
5848 int status;
5849 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5850
5851 ENTER();
5852
5853 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5854
5855 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5856 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5857 return VOS_STATUS_E_FAILURE;
5858 }
5859 else {
5860 if(*pBufSize != pHddCtx->fw->size) {
5861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5862 "file size", __func__);
5863 release_firmware(pHddCtx->fw);
5864 pHddCtx->fw = NULL;
5865 return VOS_STATUS_E_FAILURE;
5866 }
5867 else {
5868 if(pBuffer) {
5869 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5870 }
5871 release_firmware(pHddCtx->fw);
5872 pHddCtx->fw = NULL;
5873 }
5874 }
5875
5876 EXIT();
5877
5878 return VOS_STATUS_SUCCESS;
5879}
5880
5881/**---------------------------------------------------------------------------
5882
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305883 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005884
5885 This function sets the user specified mac address using
5886 the command ifconfig wlanX hw ether <mac adress>.
5887
5888 \param - dev - Pointer to the net device.
5889 - addr - Pointer to the sockaddr.
5890 \return - 0 for success, non zero for failure
5891
5892 --------------------------------------------------------------------------*/
5893
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305894static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005895{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305896 hdd_adapter_t *pAdapter;
5897 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005898 struct sockaddr *psta_mac_addr = addr;
5899 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305900 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005901
5902 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305903 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5904 if (NULL == pAdapter)
5905 {
5906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5907 "%s: Adapter is NULL",__func__);
5908 return -EINVAL;
5909 }
5910 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5911 ret = wlan_hdd_validate_context(pHddCtx);
5912 if (0 != ret)
5913 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305914 return ret;
5915 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005916
5917 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005918 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5919
5920 EXIT();
5921 return halStatus;
5922}
5923
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305924/**---------------------------------------------------------------------------
5925
5926 \brief hdd_set_mac_address() -
5927
5928 Wrapper function to protect __hdd_set_mac_address() function from ssr
5929
5930 \param - dev - Pointer to the net device.
5931 - addr - Pointer to the sockaddr.
5932 \return - 0 for success, non zero for failure
5933
5934 --------------------------------------------------------------------------*/
5935static int hdd_set_mac_address(struct net_device *dev, void *addr)
5936{
5937 int ret;
5938
5939 vos_ssr_protect(__func__);
5940 ret = __hdd_set_mac_address(dev, addr);
5941 vos_ssr_unprotect(__func__);
5942
5943 return ret;
5944}
5945
Jeff Johnson295189b2012-06-20 16:38:30 -07005946tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5947{
5948 int i;
5949 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5950 {
Abhishek Singheb183782014-02-06 13:37:21 +05305951 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 break;
5953 }
5954
5955 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5956 return NULL;
5957
5958 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5959 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5960}
5961
5962void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5963{
5964 int i;
5965 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5966 {
5967 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5968 {
5969 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5970 break;
5971 }
5972 }
5973 return;
5974}
5975
5976#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5977 static struct net_device_ops wlan_drv_ops = {
5978 .ndo_open = hdd_open,
5979 .ndo_stop = hdd_stop,
5980 .ndo_uninit = hdd_uninit,
5981 .ndo_start_xmit = hdd_hard_start_xmit,
5982 .ndo_tx_timeout = hdd_tx_timeout,
5983 .ndo_get_stats = hdd_stats,
5984 .ndo_do_ioctl = hdd_ioctl,
5985 .ndo_set_mac_address = hdd_set_mac_address,
5986 .ndo_select_queue = hdd_select_queue,
5987#ifdef WLAN_FEATURE_PACKET_FILTERING
5988#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
5989 .ndo_set_rx_mode = hdd_set_multicast_list,
5990#else
5991 .ndo_set_multicast_list = hdd_set_multicast_list,
5992#endif //LINUX_VERSION_CODE
5993#endif
5994 };
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 static struct net_device_ops wlan_mon_drv_ops = {
5996 .ndo_open = hdd_mon_open,
5997 .ndo_stop = hdd_stop,
5998 .ndo_uninit = hdd_uninit,
5999 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6000 .ndo_tx_timeout = hdd_tx_timeout,
6001 .ndo_get_stats = hdd_stats,
6002 .ndo_do_ioctl = hdd_ioctl,
6003 .ndo_set_mac_address = hdd_set_mac_address,
6004 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306005
Jeff Johnson295189b2012-06-20 16:38:30 -07006006#endif
6007
6008void hdd_set_station_ops( struct net_device *pWlanDev )
6009{
6010#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006011 pWlanDev->netdev_ops = &wlan_drv_ops;
6012#else
6013 pWlanDev->open = hdd_open;
6014 pWlanDev->stop = hdd_stop;
6015 pWlanDev->uninit = hdd_uninit;
6016 pWlanDev->hard_start_xmit = NULL;
6017 pWlanDev->tx_timeout = hdd_tx_timeout;
6018 pWlanDev->get_stats = hdd_stats;
6019 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006020 pWlanDev->set_mac_address = hdd_set_mac_address;
6021#endif
6022}
6023
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006024static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006025{
6026 struct net_device *pWlanDev = NULL;
6027 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 /*
6029 * cfg80211 initialization and registration....
6030 */
6031 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6032
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 if(pWlanDev != NULL)
6034 {
6035
6036 //Save the pointer to the net_device in the HDD adapter
6037 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6038
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6040
6041 pAdapter->dev = pWlanDev;
6042 pAdapter->pHddCtx = pHddCtx;
6043 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306044 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006045
6046 init_completion(&pAdapter->session_open_comp_var);
6047 init_completion(&pAdapter->session_close_comp_var);
6048 init_completion(&pAdapter->disconnect_comp_var);
6049 init_completion(&pAdapter->linkup_event_var);
6050 init_completion(&pAdapter->cancel_rem_on_chan_var);
6051 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306052 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006053#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6054 init_completion(&pAdapter->offchannel_tx_event);
6055#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006056 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006057#ifdef FEATURE_WLAN_TDLS
6058 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006059 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006060 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306061 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006062#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 init_completion(&pHddCtx->mc_sus_event_var);
6064 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306065 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006066 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006067 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006068
Rajeev79dbe4c2013-10-05 11:03:42 +05306069#ifdef FEATURE_WLAN_BATCH_SCAN
6070 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6071 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6072 pAdapter->pBatchScanRsp = NULL;
6073 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006074 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006075 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306076 mutex_init(&pAdapter->hdd_batch_scan_lock);
6077#endif
6078
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 pAdapter->isLinkUpSvcNeeded = FALSE;
6080 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6081 //Init the net_device structure
6082 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6083
6084 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6085 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6086 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6087 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6088
6089 hdd_set_station_ops( pAdapter->dev );
6090
6091 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006092 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6093 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6094 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006095 /* set pWlanDev's parent to underlying device */
6096 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006097
6098 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 }
6100
6101 return pAdapter;
6102}
6103
6104VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6105{
6106 struct net_device *pWlanDev = pAdapter->dev;
6107 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6108 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6109 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6110
6111 if( rtnl_lock_held )
6112 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006113 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6115 {
6116 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6117 return VOS_STATUS_E_FAILURE;
6118 }
6119 }
6120 if (register_netdevice(pWlanDev))
6121 {
6122 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6123 return VOS_STATUS_E_FAILURE;
6124 }
6125 }
6126 else
6127 {
6128 if(register_netdev(pWlanDev))
6129 {
6130 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6131 return VOS_STATUS_E_FAILURE;
6132 }
6133 }
6134 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6135
6136 return VOS_STATUS_SUCCESS;
6137}
6138
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006139static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006140{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006141 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006142
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006143 if (NULL == pAdapter)
6144 {
6145 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6146 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006147 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006148
6149 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6150 {
6151 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6152 return eHAL_STATUS_NOT_INITIALIZED;
6153 }
6154
6155 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6156
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006157#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006158 /* need to make sure all of our scheduled work has completed.
6159 * This callback is called from MC thread context, so it is safe to
6160 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006161 *
6162 * Even though this is called from MC thread context, if there is a faulty
6163 * work item in the system, that can hang this call forever. So flushing
6164 * this global work queue is not safe; and now we make sure that
6165 * individual work queues are stopped correctly. But the cancel work queue
6166 * is a GPL only API, so the proprietary version of the driver would still
6167 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006168 */
6169 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006170#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006171
6172 /* We can be blocked while waiting for scheduled work to be
6173 * flushed, and the adapter structure can potentially be freed, in
6174 * which case the magic will have been reset. So make sure the
6175 * magic is still good, and hence the adapter structure is still
6176 * valid, before signaling completion */
6177 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6178 {
6179 complete(&pAdapter->session_close_comp_var);
6180 }
6181
Jeff Johnson295189b2012-06-20 16:38:30 -07006182 return eHAL_STATUS_SUCCESS;
6183}
6184
6185VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6186{
6187 struct net_device *pWlanDev = pAdapter->dev;
6188 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6189 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6190 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6191 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306192 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006193
6194 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006195 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006196 //Open a SME session for future operation
6197 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006198 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006199 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6200 {
6201 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006202 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 halStatus, halStatus );
6204 status = VOS_STATUS_E_FAILURE;
6205 goto error_sme_open;
6206 }
6207
6208 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306209 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006210 &pAdapter->session_open_comp_var,
6211 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306212 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 {
6214 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306215 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006216 status = VOS_STATUS_E_FAILURE;
6217 goto error_sme_open;
6218 }
6219
6220 // Register wireless extensions
6221 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6222 {
6223 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006224 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 halStatus, halStatus );
6226 status = VOS_STATUS_E_FAILURE;
6227 goto error_register_wext;
6228 }
6229 //Safe to register the hard_start_xmit function again
6230#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6231 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6232#else
6233 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6234#endif
6235
6236 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306237 hddLog(VOS_TRACE_LEVEL_INFO,
6238 "%s: Set HDD connState to eConnectionState_NotConnected",
6239 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006240 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6241
6242 //Set the default operation channel
6243 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6244
6245 /* Make the default Auth Type as OPEN*/
6246 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6247
6248 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6249 {
6250 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006251 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 status, status );
6253 goto error_init_txrx;
6254 }
6255
6256 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6257
6258 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6259 {
6260 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006261 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006262 status, status );
6263 goto error_wmm_init;
6264 }
6265
6266 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6267
6268 return VOS_STATUS_SUCCESS;
6269
6270error_wmm_init:
6271 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6272 hdd_deinit_tx_rx(pAdapter);
6273error_init_txrx:
6274 hdd_UnregisterWext(pWlanDev);
6275error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006276 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006277 {
6278 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006279 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006281 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006282 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306283 unsigned long rc;
6284
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306286 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006287 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006288 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306289 if (rc <= 0)
6290 hddLog(VOS_TRACE_LEVEL_ERROR,
6291 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 }
6293}
6294error_sme_open:
6295 return status;
6296}
6297
Jeff Johnson295189b2012-06-20 16:38:30 -07006298void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6299{
6300 hdd_cfg80211_state_t *cfgState;
6301
6302 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6303
6304 if( NULL != cfgState->buf )
6305 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306306 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6308 rc = wait_for_completion_interruptible_timeout(
6309 &pAdapter->tx_action_cnf_event,
6310 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306311 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006312 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306314 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6315 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 }
6317 }
6318 return;
6319}
Jeff Johnson295189b2012-06-20 16:38:30 -07006320
c_hpothu002231a2015-02-05 14:58:51 +05306321void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006322{
6323 ENTER();
6324 switch ( pAdapter->device_mode )
6325 {
6326 case WLAN_HDD_INFRA_STATION:
6327 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006328 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 {
6330 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6331 {
6332 hdd_deinit_tx_rx( pAdapter );
6333 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6334 }
6335
6336 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6337 {
6338 hdd_wmm_adapter_close( pAdapter );
6339 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6340 }
6341
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006343 break;
6344 }
6345
6346 case WLAN_HDD_SOFTAP:
6347 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306349
6350 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6351 {
6352 hdd_wmm_adapter_close( pAdapter );
6353 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6354 }
6355
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006357
c_hpothu002231a2015-02-05 14:58:51 +05306358 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 break;
6362 }
6363
6364 case WLAN_HDD_MONITOR:
6365 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6368 {
6369 hdd_deinit_tx_rx( pAdapter );
6370 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6371 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 if(NULL != pAdapterforTx)
6373 {
6374 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6375 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006376 break;
6377 }
6378
6379
6380 default:
6381 break;
6382 }
6383
6384 EXIT();
6385}
6386
6387void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6388{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006389 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306390
6391 ENTER();
6392 if (NULL == pAdapter)
6393 {
6394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6395 "%s: HDD adapter is Null", __func__);
6396 return;
6397 }
6398
6399 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006400
Rajeev79dbe4c2013-10-05 11:03:42 +05306401#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306402 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6403 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006404 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306405 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6406 )
6407 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006408 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306409 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006410 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6411 {
6412 hdd_deinit_batch_scan(pAdapter);
6413 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306414 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006415 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306416#endif
6417
Jeff Johnson295189b2012-06-20 16:38:30 -07006418 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6419 if( rtnl_held )
6420 {
6421 unregister_netdevice(pWlanDev);
6422 }
6423 else
6424 {
6425 unregister_netdev(pWlanDev);
6426 }
6427 // note that the pAdapter is no longer valid at this point
6428 // since the memory has been reclaimed
6429 }
6430
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306431 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006432}
6433
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006434void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6435{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306436 VOS_STATUS status;
6437 hdd_adapter_t *pAdapter = NULL;
6438 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006439
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306440 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006441
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306442 /*loop through all adapters.*/
6443 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006444 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306445 pAdapter = pAdapterNode->pAdapter;
6446 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6447 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006448
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306449 { // we skip this registration for modes other than STA and P2P client modes.
6450 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6451 pAdapterNode = pNext;
6452 continue;
6453 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006454
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306455 //Apply Dynamic DTIM For P2P
6456 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6457 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6458 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6459 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6460 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6461 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6462 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6463 (eConnectionState_Associated ==
6464 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6465 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6466 {
6467 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006468
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306469 powerRequest.uIgnoreDTIM = 1;
6470 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6471
6472 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6473 {
6474 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6475 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6476 }
6477 else
6478 {
6479 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6480 }
6481
6482 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6483 * specified during Enter/Exit BMPS when LCD off*/
6484 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6485 NULL, eANI_BOOLEAN_FALSE);
6486 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6487 NULL, eANI_BOOLEAN_FALSE);
6488
6489 /* switch to the DTIM specified in cfg.ini */
6490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6491 "Switch to DTIM %d", powerRequest.uListenInterval);
6492 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6493 break;
6494
6495 }
6496
6497 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6498 pAdapterNode = pNext;
6499 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006500}
6501
6502void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6503{
6504 /*Switch back to DTIM 1*/
6505 tSirSetPowerParamsReq powerRequest = { 0 };
6506
6507 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6508 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006509 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006510
6511 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6512 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6513 NULL, eANI_BOOLEAN_FALSE);
6514 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6515 NULL, eANI_BOOLEAN_FALSE);
6516
6517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6518 "Switch to DTIM%d",powerRequest.uListenInterval);
6519 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6520
6521}
6522
Jeff Johnson295189b2012-06-20 16:38:30 -07006523VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6524{
6525 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306526 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6527 {
6528 hddLog( LOGE, FL("Wlan Unload in progress"));
6529 return VOS_STATUS_E_PERM;
6530 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006531 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6532 {
6533 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6534 }
6535
6536 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6537 {
6538 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6539 }
6540
6541 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6542 {
6543 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6544 }
6545
6546 return status;
6547}
6548
6549VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6550{
6551 hdd_adapter_t *pAdapter = NULL;
6552 eHalStatus halStatus;
6553 VOS_STATUS status = VOS_STATUS_E_INVAL;
6554 v_BOOL_t disableBmps = FALSE;
6555 v_BOOL_t disableImps = FALSE;
6556
6557 switch(session_type)
6558 {
6559 case WLAN_HDD_INFRA_STATION:
6560 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006561 case WLAN_HDD_P2P_CLIENT:
6562 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 //Exit BMPS -> Is Sta/P2P Client is already connected
6564 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6565 if((NULL != pAdapter)&&
6566 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6567 {
6568 disableBmps = TRUE;
6569 }
6570
6571 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6572 if((NULL != pAdapter)&&
6573 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6574 {
6575 disableBmps = TRUE;
6576 }
6577
6578 //Exit both Bmps and Imps incase of Go/SAP Mode
6579 if((WLAN_HDD_SOFTAP == session_type) ||
6580 (WLAN_HDD_P2P_GO == session_type))
6581 {
6582 disableBmps = TRUE;
6583 disableImps = TRUE;
6584 }
6585
6586 if(TRUE == disableImps)
6587 {
6588 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6589 {
6590 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6591 }
6592 }
6593
6594 if(TRUE == disableBmps)
6595 {
6596 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6597 {
6598 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6599
6600 if(eHAL_STATUS_SUCCESS != halStatus)
6601 {
6602 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006603 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006604 VOS_ASSERT(0);
6605 return status;
6606 }
6607 }
6608
6609 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6610 {
6611 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6612
6613 if(eHAL_STATUS_SUCCESS != halStatus)
6614 {
6615 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006616 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006617 VOS_ASSERT(0);
6618 return status;
6619 }
6620 }
6621 }
6622
6623 if((TRUE == disableBmps) ||
6624 (TRUE == disableImps))
6625 {
6626 /* Now, get the chip into Full Power now */
6627 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6628 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6629 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6630
6631 if(halStatus != eHAL_STATUS_SUCCESS)
6632 {
6633 if(halStatus == eHAL_STATUS_PMC_PENDING)
6634 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306635 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006636 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306637 ret = wait_for_completion_interruptible_timeout(
6638 &pHddCtx->full_pwr_comp_var,
6639 msecs_to_jiffies(1000));
6640 if (ret <= 0)
6641 {
6642 hddLog(VOS_TRACE_LEVEL_ERROR,
6643 "%s: wait on full_pwr_comp_var failed %ld",
6644 __func__, ret);
6645 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006646 }
6647 else
6648 {
6649 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006650 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 VOS_ASSERT(0);
6652 return status;
6653 }
6654 }
6655
6656 status = VOS_STATUS_SUCCESS;
6657 }
6658
6659 break;
6660 }
6661 return status;
6662}
6663
6664hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006665 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006666 tANI_U8 rtnl_held )
6667{
6668 hdd_adapter_t *pAdapter = NULL;
6669 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6670 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6671 VOS_STATUS exitbmpsStatus;
6672
Arif Hussain6d2a3322013-11-17 19:50:10 -08006673 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006674
Nirav Shah436658f2014-02-28 17:05:45 +05306675 if(macAddr == NULL)
6676 {
6677 /* Not received valid macAddr */
6678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6679 "%s:Unable to add virtual intf: Not able to get"
6680 "valid mac address",__func__);
6681 return NULL;
6682 }
6683
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 //Disable BMPS incase of Concurrency
6685 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6686
6687 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6688 {
6689 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306690 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006691 VOS_ASSERT(0);
6692 return NULL;
6693 }
6694
6695 switch(session_type)
6696 {
6697 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006698 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006699 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006700 {
6701 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6702
6703 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306704 {
6705 hddLog(VOS_TRACE_LEVEL_FATAL,
6706 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006707 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306708 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006709
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306710#ifdef FEATURE_WLAN_TDLS
6711 /* A Mutex Lock is introduced while changing/initializing the mode to
6712 * protect the concurrent access for the Adapters by TDLS module.
6713 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306714 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306715#endif
6716
Jeff Johnsone7245742012-09-05 17:12:55 -07006717 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6718 NL80211_IFTYPE_P2P_CLIENT:
6719 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006720
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306722#ifdef FEATURE_WLAN_TDLS
6723 mutex_unlock(&pHddCtx->tdls_lock);
6724#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306725
6726 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006727 if( VOS_STATUS_SUCCESS != status )
6728 goto err_free_netdev;
6729
6730 status = hdd_register_interface( pAdapter, rtnl_held );
6731 if( VOS_STATUS_SUCCESS != status )
6732 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306733#ifdef FEATURE_WLAN_TDLS
6734 mutex_lock(&pHddCtx->tdls_lock);
6735#endif
c_hpothu002231a2015-02-05 14:58:51 +05306736 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306737#ifdef FEATURE_WLAN_TDLS
6738 mutex_unlock(&pHddCtx->tdls_lock);
6739#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006740 goto err_free_netdev;
6741 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306742
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306743 // Workqueue which gets scheduled in IPv4 notification callback.
6744 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6745
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306746#ifdef WLAN_NS_OFFLOAD
6747 // Workqueue which gets scheduled in IPv6 notification callback.
6748 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6749#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006750 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306751 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 netif_tx_disable(pAdapter->dev);
6753 //netif_tx_disable(pWlanDev);
6754 netif_carrier_off(pAdapter->dev);
6755
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306756 if (WLAN_HDD_P2P_CLIENT == session_type ||
6757 WLAN_HDD_P2P_DEVICE == session_type)
6758 {
6759 /* Initialize the work queue to defer the
6760 * back to back RoC request */
6761 INIT_DELAYED_WORK(&pAdapter->roc_work,
6762 hdd_p2p_roc_work_queue);
6763 }
6764
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 break;
6766 }
6767
Jeff Johnson295189b2012-06-20 16:38:30 -07006768 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 case WLAN_HDD_SOFTAP:
6770 {
6771 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6772 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306773 {
6774 hddLog(VOS_TRACE_LEVEL_FATAL,
6775 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006776 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306777 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006778
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6780 NL80211_IFTYPE_AP:
6781 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 pAdapter->device_mode = session_type;
6783
6784 status = hdd_init_ap_mode(pAdapter);
6785 if( VOS_STATUS_SUCCESS != status )
6786 goto err_free_netdev;
6787
6788 status = hdd_register_hostapd( pAdapter, rtnl_held );
6789 if( VOS_STATUS_SUCCESS != status )
6790 {
c_hpothu002231a2015-02-05 14:58:51 +05306791 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006792 goto err_free_netdev;
6793 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306794 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006795 netif_tx_disable(pAdapter->dev);
6796 netif_carrier_off(pAdapter->dev);
6797
6798 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306799
6800 if (WLAN_HDD_P2P_GO == session_type)
6801 {
6802 /* Initialize the work queue to
6803 * defer the back to back RoC request */
6804 INIT_DELAYED_WORK(&pAdapter->roc_work,
6805 hdd_p2p_roc_work_queue);
6806 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 break;
6808 }
6809 case WLAN_HDD_MONITOR:
6810 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006811 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6812 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306813 {
6814 hddLog(VOS_TRACE_LEVEL_FATAL,
6815 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306817 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006818
6819 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6820 pAdapter->device_mode = session_type;
6821 status = hdd_register_interface( pAdapter, rtnl_held );
6822#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6823 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6824#else
6825 pAdapter->dev->open = hdd_mon_open;
6826 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6827#endif
6828 hdd_init_tx_rx( pAdapter );
6829 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6830 //Set adapter to be used for data tx. It will use either GO or softap.
6831 pAdapter->sessionCtx.monitor.pAdapterForTx =
6832 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006833 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6834 {
6835 pAdapter->sessionCtx.monitor.pAdapterForTx =
6836 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6837 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006838 /* This workqueue will be used to transmit management packet over
6839 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006840 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6841 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6842 return NULL;
6843 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006844
Jeff Johnson295189b2012-06-20 16:38:30 -07006845 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6846 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 }
6848 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 case WLAN_HDD_FTM:
6850 {
6851 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6852
6853 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306854 {
6855 hddLog(VOS_TRACE_LEVEL_FATAL,
6856 FL("failed to allocate adapter for session %d"), session_type);
6857 return NULL;
6858 }
6859
Jeff Johnson295189b2012-06-20 16:38:30 -07006860 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6861 * message while loading driver in FTM mode. */
6862 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6863 pAdapter->device_mode = session_type;
6864 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306865
6866 hdd_init_tx_rx( pAdapter );
6867
6868 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306869 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306870 netif_tx_disable(pAdapter->dev);
6871 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 }
6873 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 default:
6875 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306876 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6877 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 VOS_ASSERT(0);
6879 return NULL;
6880 }
6881 }
6882
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 if( VOS_STATUS_SUCCESS == status )
6884 {
6885 //Add it to the hdd's session list.
6886 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6887 if( NULL == pHddAdapterNode )
6888 {
6889 status = VOS_STATUS_E_NOMEM;
6890 }
6891 else
6892 {
6893 pHddAdapterNode->pAdapter = pAdapter;
6894 status = hdd_add_adapter_back ( pHddCtx,
6895 pHddAdapterNode );
6896 }
6897 }
6898
6899 if( VOS_STATUS_SUCCESS != status )
6900 {
6901 if( NULL != pAdapter )
6902 {
6903 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6904 pAdapter = NULL;
6905 }
6906 if( NULL != pHddAdapterNode )
6907 {
6908 vos_mem_free( pHddAdapterNode );
6909 }
6910
6911 goto resume_bmps;
6912 }
6913
6914 if(VOS_STATUS_SUCCESS == status)
6915 {
6916 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6917
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006918 //Initialize the WoWL service
6919 if(!hdd_init_wowl(pAdapter))
6920 {
6921 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6922 goto err_free_netdev;
6923 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006925 return pAdapter;
6926
6927err_free_netdev:
6928 free_netdev(pAdapter->dev);
6929 wlan_hdd_release_intf_addr( pHddCtx,
6930 pAdapter->macAddressCurrent.bytes );
6931
6932resume_bmps:
6933 //If bmps disabled enable it
6934 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6935 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306936 if (pHddCtx->hdd_wlan_suspended)
6937 {
6938 hdd_set_pwrparams(pHddCtx);
6939 }
6940 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006941 }
6942 return NULL;
6943}
6944
6945VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6946 tANI_U8 rtnl_held )
6947{
6948 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6949 VOS_STATUS status;
6950
6951 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6952 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306953 {
6954 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6955 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306957 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006958
6959 while ( pCurrent->pAdapter != pAdapter )
6960 {
6961 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6962 if( VOS_STATUS_SUCCESS != status )
6963 break;
6964
6965 pCurrent = pNext;
6966 }
6967 pAdapterNode = pCurrent;
6968 if( VOS_STATUS_SUCCESS == status )
6969 {
6970 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6971 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306972
6973#ifdef FEATURE_WLAN_TDLS
6974
6975 /* A Mutex Lock is introduced while changing/initializing the mode to
6976 * protect the concurrent access for the Adapters by TDLS module.
6977 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306978 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306979#endif
6980
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 hdd_remove_adapter( pHddCtx, pAdapterNode );
6982 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006983 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006984
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306985#ifdef FEATURE_WLAN_TDLS
6986 mutex_unlock(&pHddCtx->tdls_lock);
6987#endif
6988
Jeff Johnson295189b2012-06-20 16:38:30 -07006989
6990 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05306991 if ((!vos_concurrent_open_sessions_running()) &&
6992 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
6993 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306995 if (pHddCtx->hdd_wlan_suspended)
6996 {
6997 hdd_set_pwrparams(pHddCtx);
6998 }
6999 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 }
7001
7002 return VOS_STATUS_SUCCESS;
7003 }
7004
7005 return VOS_STATUS_E_FAILURE;
7006}
7007
7008VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7009{
7010 hdd_adapter_list_node_t *pHddAdapterNode;
7011 VOS_STATUS status;
7012
7013 ENTER();
7014
7015 do
7016 {
7017 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7018 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7019 {
7020 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7021 vos_mem_free( pHddAdapterNode );
7022 }
7023 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7024
7025 EXIT();
7026
7027 return VOS_STATUS_SUCCESS;
7028}
7029
7030void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7031{
7032 v_U8_t addIE[1] = {0};
7033
7034 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7035 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7036 eANI_BOOLEAN_FALSE) )
7037 {
7038 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007039 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 }
7041
7042 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7043 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7044 eANI_BOOLEAN_FALSE) )
7045 {
7046 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007047 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007048 }
7049
7050 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7051 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7052 eANI_BOOLEAN_FALSE) )
7053 {
7054 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007055 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 }
7057}
7058
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307059VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7060 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007061{
7062 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7063 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307064 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307066 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307067 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007068
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307069 if (pHddCtx->isLogpInProgress) {
7070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7071 "%s:LOGP in Progress. Ignore!!!",__func__);
7072 return VOS_STATUS_E_FAILURE;
7073 }
7074
Jeff Johnson295189b2012-06-20 16:38:30 -07007075 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307076
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307077 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 switch(pAdapter->device_mode)
7079 {
7080 case WLAN_HDD_INFRA_STATION:
7081 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007082 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307083 {
7084 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7085 if( hdd_connIsConnected(pstation) ||
7086 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007087 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307088#ifdef FEATURE_WLAN_TDLS
7089 mutex_lock(&pHddCtx->tdls_lock);
7090 wlan_hdd_tdls_exit(pAdapter);
7091 mutex_unlock(&pHddCtx->tdls_lock);
7092#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7094 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7095 pAdapter->sessionId,
7096 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7097 else
7098 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7099 pAdapter->sessionId,
7100 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7101 //success implies disconnect command got queued up successfully
7102 if(halStatus == eHAL_STATUS_SUCCESS)
7103 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307104 ret = wait_for_completion_interruptible_timeout(
7105 &pAdapter->disconnect_comp_var,
7106 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7107 if (ret <= 0)
7108 {
7109 hddLog(VOS_TRACE_LEVEL_ERROR,
7110 "%s: wait on disconnect_comp_var failed %ld",
7111 __func__, ret);
7112 }
7113 }
7114 else
7115 {
7116 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7117 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007118 }
7119 memset(&wrqu, '\0', sizeof(wrqu));
7120 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7121 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7122 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7123 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307124 else if(pstation->conn_info.connState ==
7125 eConnectionState_Disconnecting)
7126 {
7127 ret = wait_for_completion_interruptible_timeout(
7128 &pAdapter->disconnect_comp_var,
7129 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7130 if (ret <= 0)
7131 {
7132 hddLog(VOS_TRACE_LEVEL_ERROR,
7133 FL("wait on disconnect_comp_var failed %ld"), ret);
7134 }
7135 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307136 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307138 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307139 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007140 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307141 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7142 {
7143 while (pAdapter->is_roc_inprogress)
7144 {
7145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7146 "%s: ROC in progress for session %d!!!",
7147 __func__, pAdapter->sessionId);
7148 // waiting for ROC to expire
7149 msleep(500);
7150 /* In GO present case , if retry exceeds 3,
7151 it means something went wrong. */
7152 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7153 {
7154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7155 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307156 if (eHAL_STATUS_SUCCESS !=
7157 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7158 pAdapter->sessionId ))
7159 {
7160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7161 FL("Failed to Cancel Remain on Channel"));
7162 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307163 wait_for_completion_interruptible_timeout(
7164 &pAdapter->cancel_rem_on_chan_var,
7165 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7166 break;
7167 }
7168 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307169#ifdef WLAN_OPEN_SOURCE
7170 cancel_delayed_work_sync(&pAdapter->roc_work);
7171#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307172 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307173#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307174#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307175 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7176#endif
7177#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307178
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307179#ifdef WLAN_OPEN_SOURCE
7180 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7181#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307182
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307183 /* It is possible that the caller of this function does not
7184 * wish to close the session
7185 */
7186 if (VOS_TRUE == bCloseSession &&
7187 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007188 {
7189 INIT_COMPLETION(pAdapter->session_close_comp_var);
7190 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307191 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7192 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007193 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307194 unsigned long ret;
7195
Jeff Johnson295189b2012-06-20 16:38:30 -07007196 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307197 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307198 &pAdapter->session_close_comp_var,
7199 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307200 if ( 0 >= ret)
7201 {
7202 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307203 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307204 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007205 }
7206 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307207 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007208 break;
7209
7210 case WLAN_HDD_SOFTAP:
7211 case WLAN_HDD_P2P_GO:
7212 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307213 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7214 while (pAdapter->is_roc_inprogress) {
7215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7216 "%s: ROC in progress for session %d!!!",
7217 __func__, pAdapter->sessionId);
7218 msleep(500);
7219 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7221 "%s: ROC completion is not received.!!!", __func__);
7222 WLANSAP_CancelRemainOnChannel(
7223 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7224 wait_for_completion_interruptible_timeout(
7225 &pAdapter->cancel_rem_on_chan_var,
7226 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7227 break;
7228 }
7229 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307230
7231#ifdef WLAN_OPEN_SOURCE
7232 cancel_delayed_work_sync(&pAdapter->roc_work);
7233#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307234 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007235 mutex_lock(&pHddCtx->sap_lock);
7236 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7237 {
7238 VOS_STATUS status;
7239 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7240
7241 //Stop Bss.
7242 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7243 if (VOS_IS_STATUS_SUCCESS(status))
7244 {
7245 hdd_hostapd_state_t *pHostapdState =
7246 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7247
7248 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7249
7250 if (!VOS_IS_STATUS_SUCCESS(status))
7251 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307252 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7253 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007254 }
7255 }
7256 else
7257 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007258 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007259 }
7260 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307261 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007262
7263 if (eHAL_STATUS_FAILURE ==
7264 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7265 0, NULL, eANI_BOOLEAN_FALSE))
7266 {
7267 hddLog(LOGE,
7268 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007269 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007270 }
7271
7272 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7273 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7274 eANI_BOOLEAN_FALSE) )
7275 {
7276 hddLog(LOGE,
7277 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7278 }
7279
7280 // Reset WNI_CFG_PROBE_RSP Flags
7281 wlan_hdd_reset_prob_rspies(pAdapter);
7282 kfree(pAdapter->sessionCtx.ap.beacon);
7283 pAdapter->sessionCtx.ap.beacon = NULL;
7284 }
7285 mutex_unlock(&pHddCtx->sap_lock);
7286 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007287
Jeff Johnson295189b2012-06-20 16:38:30 -07007288 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007289#ifdef WLAN_OPEN_SOURCE
7290 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7291#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007293
Jeff Johnson295189b2012-06-20 16:38:30 -07007294 default:
7295 break;
7296 }
7297
7298 EXIT();
7299 return VOS_STATUS_SUCCESS;
7300}
7301
7302VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7303{
7304 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7305 VOS_STATUS status;
7306 hdd_adapter_t *pAdapter;
7307
7308 ENTER();
7309
7310 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7311
7312 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7313 {
7314 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007315
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307316 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007317
7318 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7319 pAdapterNode = pNext;
7320 }
7321
7322 EXIT();
7323
7324 return VOS_STATUS_SUCCESS;
7325}
7326
Rajeev Kumarf999e582014-01-09 17:33:29 -08007327
7328#ifdef FEATURE_WLAN_BATCH_SCAN
7329/**---------------------------------------------------------------------------
7330
7331 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7332 structures
7333
7334 \param - pAdapter Pointer to HDD adapter
7335
7336 \return - None
7337
7338 --------------------------------------------------------------------------*/
7339void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7340{
7341 tHddBatchScanRsp *pNode;
7342 tHddBatchScanRsp *pPrev;
7343
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307344 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007345 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307346 hddLog(VOS_TRACE_LEVEL_ERROR,
7347 "%s: Adapter context is Null", __func__);
7348 return;
7349 }
7350
7351 pNode = pAdapter->pBatchScanRsp;
7352 while (pNode)
7353 {
7354 pPrev = pNode;
7355 pNode = pNode->pNext;
7356 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007357 }
7358
7359 pAdapter->pBatchScanRsp = NULL;
7360 pAdapter->numScanList = 0;
7361 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7362 pAdapter->prev_batch_id = 0;
7363
7364 return;
7365}
7366#endif
7367
7368
Jeff Johnson295189b2012-06-20 16:38:30 -07007369VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7370{
7371 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7372 VOS_STATUS status;
7373 hdd_adapter_t *pAdapter;
7374
7375 ENTER();
7376
7377 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7378
7379 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7380 {
7381 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307382 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007383 netif_tx_disable(pAdapter->dev);
7384 netif_carrier_off(pAdapter->dev);
7385
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007386 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7387
Jeff Johnson295189b2012-06-20 16:38:30 -07007388 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307389
7390 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7391
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307392 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7393 {
7394 hdd_wmm_adapter_close( pAdapter );
7395 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7396 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007397
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307398 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7399 {
7400 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7401 }
7402
Rajeev Kumarf999e582014-01-09 17:33:29 -08007403#ifdef FEATURE_WLAN_BATCH_SCAN
7404 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7405 {
7406 hdd_deinit_batch_scan(pAdapter);
7407 }
7408#endif
7409
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307410#ifdef FEATURE_WLAN_TDLS
7411 mutex_lock(&pHddCtx->tdls_lock);
7412 wlan_hdd_tdls_exit(pAdapter);
7413 mutex_unlock(&pHddCtx->tdls_lock);
7414#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007415 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7416 pAdapterNode = pNext;
7417 }
7418
7419 EXIT();
7420
7421 return VOS_STATUS_SUCCESS;
7422}
7423
7424VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7425{
7426 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7427 VOS_STATUS status;
7428 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307429 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007430
7431 ENTER();
7432
7433 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7434
7435 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7436 {
7437 pAdapter = pAdapterNode->pAdapter;
7438
Kumar Anand82c009f2014-05-29 00:29:42 -07007439 hdd_wmm_init( pAdapter );
7440
Jeff Johnson295189b2012-06-20 16:38:30 -07007441 switch(pAdapter->device_mode)
7442 {
7443 case WLAN_HDD_INFRA_STATION:
7444 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007445 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307446
7447 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7448
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 hdd_init_station_mode(pAdapter);
7450 /* Open the gates for HDD to receive Wext commands */
7451 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007452 pHddCtx->scan_info.mScanPending = FALSE;
7453 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007454
7455 //Trigger the initial scan
7456 hdd_wlan_initial_scan(pAdapter);
7457
7458 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307459 if (eConnectionState_Associated == connState ||
7460 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 {
7462 union iwreq_data wrqu;
7463 memset(&wrqu, '\0', sizeof(wrqu));
7464 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7465 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7466 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007467 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007468
Jeff Johnson295189b2012-06-20 16:38:30 -07007469 /* indicate disconnected event to nl80211 */
7470 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7471 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007472 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307473 else if (eConnectionState_Connecting == connState)
7474 {
7475 /*
7476 * Indicate connect failure to supplicant if we were in the
7477 * process of connecting
7478 */
7479 cfg80211_connect_result(pAdapter->dev, NULL,
7480 NULL, 0, NULL, 0,
7481 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7482 GFP_KERNEL);
7483 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007484 break;
7485
7486 case WLAN_HDD_SOFTAP:
7487 /* softAP can handle SSR */
7488 break;
7489
7490 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007492 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007493 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 break;
7495
7496 case WLAN_HDD_MONITOR:
7497 /* monitor interface start */
7498 break;
7499 default:
7500 break;
7501 }
7502
7503 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7504 pAdapterNode = pNext;
7505 }
7506
7507 EXIT();
7508
7509 return VOS_STATUS_SUCCESS;
7510}
7511
7512VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7513{
7514 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7515 hdd_adapter_t *pAdapter;
7516 VOS_STATUS status;
7517 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307518 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007519
7520 ENTER();
7521
7522 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7523
7524 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7525 {
7526 pAdapter = pAdapterNode->pAdapter;
7527
7528 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7529 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7530 {
7531 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7532 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7533
Abhishek Singhf4669da2014-05-26 15:07:49 +05307534 hddLog(VOS_TRACE_LEVEL_INFO,
7535 "%s: Set HDD connState to eConnectionState_NotConnected",
7536 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7538 init_completion(&pAdapter->disconnect_comp_var);
7539 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7540 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7541
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307542 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007543 &pAdapter->disconnect_comp_var,
7544 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307545 if (0 >= ret)
7546 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7547 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007548
7549 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7550 pHddCtx->isAmpAllowed = VOS_FALSE;
7551 sme_RoamConnect(pHddCtx->hHal,
7552 pAdapter->sessionId, &(pWextState->roamProfile),
7553 &roamId);
7554 }
7555
7556 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7557 pAdapterNode = pNext;
7558 }
7559
7560 EXIT();
7561
7562 return VOS_STATUS_SUCCESS;
7563}
7564
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007565void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7566{
7567 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7568 VOS_STATUS status;
7569 hdd_adapter_t *pAdapter;
7570 hdd_station_ctx_t *pHddStaCtx;
7571 hdd_ap_ctx_t *pHddApCtx;
7572 hdd_hostapd_state_t * pHostapdState;
7573 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7574 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7575 const char *p2pMode = "DEV";
7576 const char *ccMode = "Standalone";
7577 int n;
7578
7579 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7580 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7581 {
7582 pAdapter = pAdapterNode->pAdapter;
7583 switch (pAdapter->device_mode) {
7584 case WLAN_HDD_INFRA_STATION:
7585 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7586 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7587 staChannel = pHddStaCtx->conn_info.operationChannel;
7588 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7589 }
7590 break;
7591 case WLAN_HDD_P2P_CLIENT:
7592 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7593 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7594 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7595 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7596 p2pMode = "CLI";
7597 }
7598 break;
7599 case WLAN_HDD_P2P_GO:
7600 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7601 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7602 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7603 p2pChannel = pHddApCtx->operatingChannel;
7604 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7605 }
7606 p2pMode = "GO";
7607 break;
7608 case WLAN_HDD_SOFTAP:
7609 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7610 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7611 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7612 apChannel = pHddApCtx->operatingChannel;
7613 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7614 }
7615 break;
7616 default:
7617 break;
7618 }
7619 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7620 pAdapterNode = pNext;
7621 }
7622 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7623 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7624 }
7625 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7626 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7627 if (p2pChannel > 0) {
7628 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7629 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7630 }
7631 if (apChannel > 0) {
7632 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7633 apChannel, MAC_ADDR_ARRAY(apBssid));
7634 }
7635
7636 if (p2pChannel > 0 && apChannel > 0) {
7637 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7638 }
7639}
7640
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007641bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007642{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007643 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007644}
7645
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007646/* Once SSR is disabled then it cannot be set. */
7647void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007648{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007649 if (HDD_SSR_DISABLED == isSsrRequired)
7650 return;
7651
Jeff Johnson295189b2012-06-20 16:38:30 -07007652 isSsrRequired = value;
7653}
7654
7655VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7656 hdd_adapter_list_node_t** ppAdapterNode)
7657{
7658 VOS_STATUS status;
7659 spin_lock(&pHddCtx->hddAdapters.lock);
7660 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7661 (hdd_list_node_t**) ppAdapterNode );
7662 spin_unlock(&pHddCtx->hddAdapters.lock);
7663 return status;
7664}
7665
7666VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7667 hdd_adapter_list_node_t* pAdapterNode,
7668 hdd_adapter_list_node_t** pNextAdapterNode)
7669{
7670 VOS_STATUS status;
7671 spin_lock(&pHddCtx->hddAdapters.lock);
7672 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7673 (hdd_list_node_t*) pAdapterNode,
7674 (hdd_list_node_t**)pNextAdapterNode );
7675
7676 spin_unlock(&pHddCtx->hddAdapters.lock);
7677 return status;
7678}
7679
7680VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7681 hdd_adapter_list_node_t* pAdapterNode)
7682{
7683 VOS_STATUS status;
7684 spin_lock(&pHddCtx->hddAdapters.lock);
7685 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7686 &pAdapterNode->node );
7687 spin_unlock(&pHddCtx->hddAdapters.lock);
7688 return status;
7689}
7690
7691VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7692 hdd_adapter_list_node_t** ppAdapterNode)
7693{
7694 VOS_STATUS status;
7695 spin_lock(&pHddCtx->hddAdapters.lock);
7696 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7697 (hdd_list_node_t**) ppAdapterNode );
7698 spin_unlock(&pHddCtx->hddAdapters.lock);
7699 return status;
7700}
7701
7702VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7703 hdd_adapter_list_node_t* pAdapterNode)
7704{
7705 VOS_STATUS status;
7706 spin_lock(&pHddCtx->hddAdapters.lock);
7707 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7708 (hdd_list_node_t*) pAdapterNode );
7709 spin_unlock(&pHddCtx->hddAdapters.lock);
7710 return status;
7711}
7712
7713VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7714 hdd_adapter_list_node_t* pAdapterNode)
7715{
7716 VOS_STATUS status;
7717 spin_lock(&pHddCtx->hddAdapters.lock);
7718 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7719 (hdd_list_node_t*) pAdapterNode );
7720 spin_unlock(&pHddCtx->hddAdapters.lock);
7721 return status;
7722}
7723
7724hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7725 tSirMacAddr macAddr )
7726{
7727 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7728 hdd_adapter_t *pAdapter;
7729 VOS_STATUS status;
7730
7731 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7732
7733 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7734 {
7735 pAdapter = pAdapterNode->pAdapter;
7736
7737 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7738 macAddr, sizeof(tSirMacAddr) ) )
7739 {
7740 return pAdapter;
7741 }
7742 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7743 pAdapterNode = pNext;
7744 }
7745
7746 return NULL;
7747
7748}
7749
7750hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7751{
7752 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7753 hdd_adapter_t *pAdapter;
7754 VOS_STATUS status;
7755
7756 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7757
7758 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7759 {
7760 pAdapter = pAdapterNode->pAdapter;
7761
7762 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7763 IFNAMSIZ ) )
7764 {
7765 return pAdapter;
7766 }
7767 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7768 pAdapterNode = pNext;
7769 }
7770
7771 return NULL;
7772
7773}
7774
7775hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7776{
7777 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7778 hdd_adapter_t *pAdapter;
7779 VOS_STATUS status;
7780
7781 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7782
7783 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7784 {
7785 pAdapter = pAdapterNode->pAdapter;
7786
7787 if( pAdapter && (mode == pAdapter->device_mode) )
7788 {
7789 return pAdapter;
7790 }
7791 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7792 pAdapterNode = pNext;
7793 }
7794
7795 return NULL;
7796
7797}
7798
7799//Remove this function later
7800hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7801{
7802 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7803 hdd_adapter_t *pAdapter;
7804 VOS_STATUS status;
7805
7806 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7807
7808 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7809 {
7810 pAdapter = pAdapterNode->pAdapter;
7811
7812 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7813 {
7814 return pAdapter;
7815 }
7816
7817 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7818 pAdapterNode = pNext;
7819 }
7820
7821 return NULL;
7822
7823}
7824
Jeff Johnson295189b2012-06-20 16:38:30 -07007825/**---------------------------------------------------------------------------
7826
7827 \brief hdd_set_monitor_tx_adapter() -
7828
7829 This API initializes the adapter to be used while transmitting on monitor
7830 adapter.
7831
7832 \param - pHddCtx - Pointer to the HDD context.
7833 pAdapter - Adapter that will used for TX. This can be NULL.
7834 \return - None.
7835 --------------------------------------------------------------------------*/
7836void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7837{
7838 hdd_adapter_t *pMonAdapter;
7839
7840 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7841
7842 if( NULL != pMonAdapter )
7843 {
7844 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7845 }
7846}
Jeff Johnson295189b2012-06-20 16:38:30 -07007847/**---------------------------------------------------------------------------
7848
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307849 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007850
7851 This API returns the operating channel of the requested device mode
7852
7853 \param - pHddCtx - Pointer to the HDD context.
7854 - mode - Device mode for which operating channel is required
7855 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7856 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7857 \return - channel number. "0" id the requested device is not found OR it is not connected.
7858 --------------------------------------------------------------------------*/
7859v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7860{
7861 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7862 VOS_STATUS status;
7863 hdd_adapter_t *pAdapter;
7864 v_U8_t operatingChannel = 0;
7865
7866 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7867
7868 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7869 {
7870 pAdapter = pAdapterNode->pAdapter;
7871
7872 if( mode == pAdapter->device_mode )
7873 {
7874 switch(pAdapter->device_mode)
7875 {
7876 case WLAN_HDD_INFRA_STATION:
7877 case WLAN_HDD_P2P_CLIENT:
7878 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7879 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7880 break;
7881 case WLAN_HDD_SOFTAP:
7882 case WLAN_HDD_P2P_GO:
7883 /*softap connection info */
7884 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7885 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7886 break;
7887 default:
7888 break;
7889 }
7890
7891 break; //Found the device of interest. break the loop
7892 }
7893
7894 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7895 pAdapterNode = pNext;
7896 }
7897 return operatingChannel;
7898}
7899
7900#ifdef WLAN_FEATURE_PACKET_FILTERING
7901/**---------------------------------------------------------------------------
7902
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307903 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007904
7905 This used to set the multicast address list.
7906
7907 \param - dev - Pointer to the WLAN device.
7908 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307909 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07007910
7911 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307912static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007913{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307914 hdd_adapter_t *pAdapter;
7915 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307917 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007918 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307919
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307920 ENTER();
7921
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307922 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307923 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007924 {
7925 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307926 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007927 return;
7928 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307929 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7930 ret = wlan_hdd_validate_context(pHddCtx);
7931 if (0 != ret)
7932 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307933 return;
7934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 if (dev->flags & IFF_ALLMULTI)
7936 {
7937 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007938 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307939 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007940 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307941 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007942 {
7943 mc_count = netdev_mc_count(dev);
7944 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007945 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007946 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7947 {
7948 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007949 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307950 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 return;
7952 }
7953
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307954 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007955
7956 netdev_for_each_mc_addr(ha, dev) {
7957 if (i == mc_count)
7958 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307959 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7960 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007961 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307962 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307963 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 i++;
7965 }
7966 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307967
7968 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007969 return;
7970}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307971
7972static void hdd_set_multicast_list(struct net_device *dev)
7973{
7974 vos_ssr_protect(__func__);
7975 __hdd_set_multicast_list(dev);
7976 vos_ssr_unprotect(__func__);
7977}
Jeff Johnson295189b2012-06-20 16:38:30 -07007978#endif
7979
7980/**---------------------------------------------------------------------------
7981
7982 \brief hdd_select_queue() -
7983
7984 This function is registered with the Linux OS for network
7985 core to decide which queue to use first.
7986
7987 \param - dev - Pointer to the WLAN device.
7988 - skb - Pointer to OS packet (sk_buff).
7989 \return - ac, Queue Index/access category corresponding to UP in IP header
7990
7991 --------------------------------------------------------------------------*/
7992v_U16_t hdd_select_queue(struct net_device *dev,
7993 struct sk_buff *skb)
7994{
7995 return hdd_wmm_select_queue(dev, skb);
7996}
7997
7998
7999/**---------------------------------------------------------------------------
8000
8001 \brief hdd_wlan_initial_scan() -
8002
8003 This function triggers the initial scan
8004
8005 \param - pAdapter - Pointer to the HDD adapter.
8006
8007 --------------------------------------------------------------------------*/
8008void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8009{
8010 tCsrScanRequest scanReq;
8011 tCsrChannelInfo channelInfo;
8012 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008013 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8015
8016 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8017 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8018 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8019
8020 if(sme_Is11dSupported(pHddCtx->hHal))
8021 {
8022 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8023 if ( HAL_STATUS_SUCCESS( halStatus ) )
8024 {
8025 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8026 if( !scanReq.ChannelInfo.ChannelList )
8027 {
8028 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8029 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008030 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008031 return;
8032 }
8033 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8034 channelInfo.numOfChannels);
8035 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8036 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008037 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008038 }
8039
8040 scanReq.scanType = eSIR_PASSIVE_SCAN;
8041 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8042 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8043 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8044 }
8045 else
8046 {
8047 scanReq.scanType = eSIR_ACTIVE_SCAN;
8048 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8049 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8050 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8051 }
8052
8053 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8054 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8055 {
8056 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8057 __func__, halStatus );
8058 }
8059
8060 if(sme_Is11dSupported(pHddCtx->hHal))
8061 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8062}
8063
Jeff Johnson295189b2012-06-20 16:38:30 -07008064/**---------------------------------------------------------------------------
8065
8066 \brief hdd_full_power_callback() - HDD full power callback function
8067
8068 This is the function invoked by SME to inform the result of a full power
8069 request issued by HDD
8070
8071 \param - callbackcontext - Pointer to cookie
8072 \param - status - result of request
8073
8074 \return - None
8075
8076 --------------------------------------------------------------------------*/
8077static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8078{
Jeff Johnson72a40512013-12-19 10:14:15 -08008079 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008080
8081 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308082 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008083
8084 if (NULL == callbackContext)
8085 {
8086 hddLog(VOS_TRACE_LEVEL_ERROR,
8087 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008088 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008089 return;
8090 }
8091
Jeff Johnson72a40512013-12-19 10:14:15 -08008092 /* there is a race condition that exists between this callback
8093 function and the caller since the caller could time out either
8094 before or while this code is executing. we use a spinlock to
8095 serialize these actions */
8096 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008097
8098 if (POWER_CONTEXT_MAGIC != pContext->magic)
8099 {
8100 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008101 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008102 hddLog(VOS_TRACE_LEVEL_WARN,
8103 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008104 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008105 return;
8106 }
8107
Jeff Johnson72a40512013-12-19 10:14:15 -08008108 /* context is valid so caller is still waiting */
8109
8110 /* paranoia: invalidate the magic */
8111 pContext->magic = 0;
8112
8113 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008115
8116 /* serialization is complete */
8117 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008118}
8119
8120/**---------------------------------------------------------------------------
8121
8122 \brief hdd_wlan_exit() - HDD WLAN exit function
8123
8124 This is the driver exit point (invoked during rmmod)
8125
8126 \param - pHddCtx - Pointer to the HDD Context
8127
8128 \return - None
8129
8130 --------------------------------------------------------------------------*/
8131void hdd_wlan_exit(hdd_context_t *pHddCtx)
8132{
8133 eHalStatus halStatus;
8134 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8135 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308136 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008137 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008138 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008139 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308140 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008141
8142 ENTER();
8143
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308144#ifdef WLAN_NS_OFFLOAD
8145 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8146 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8147#endif
8148 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8149 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8150
Jeff Johnson88ba7742013-02-27 14:36:02 -08008151 if (VOS_FTM_MODE != hdd_get_conparam())
8152 {
Katya Nigamdc373382015-02-25 18:52:19 +05308153 /* This will issue a dump command which will clean up
8154 BTQM queues and unblock MC thread */
8155 WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
8156
Jeff Johnson88ba7742013-02-27 14:36:02 -08008157 // Unloading, restart logic is no more required.
8158 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008159
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308160#ifdef FEATURE_WLAN_TDLS
8161 /* At the time of driver unloading; if tdls connection is present;
8162 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8163 * wlan_hdd_tdls_find_peer always checks for valid context;
8164 * as load/unload in progress there can be a race condition.
8165 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8166 * when tdls state is enabled.
8167 * As soon as driver set load/unload flag; tdls flag also needs
8168 * to be disabled so that hdd_rx_packet_cbk won't call
8169 * wlan_hdd_tdls_find_peer.
8170 */
8171 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8172#endif
8173
c_hpothu5ab05e92014-06-13 17:34:05 +05308174 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8175 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308177 pAdapter = pAdapterNode->pAdapter;
8178 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008179 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308180 /* Disable TX on the interface, after this hard_start_xmit() will
8181 * not be called on that interface
8182 */
8183 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8184 netif_tx_disable(pAdapter->dev);
8185
8186 /* Mark the interface status as "down" for outside world */
8187 netif_carrier_off(pAdapter->dev);
8188
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308189 /* DeInit the adapter. This ensures that all data packets
8190 * are freed.
8191 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308192#ifdef FEATURE_WLAN_TDLS
8193 mutex_lock(&pHddCtx->tdls_lock);
8194#endif
c_hpothu002231a2015-02-05 14:58:51 +05308195 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308196#ifdef FEATURE_WLAN_TDLS
8197 mutex_unlock(&pHddCtx->tdls_lock);
8198#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308199
c_hpothu5ab05e92014-06-13 17:34:05 +05308200 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8201 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8202 {
8203 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8204 hdd_UnregisterWext(pAdapter->dev);
8205 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308206
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308208 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8209 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008210 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308211 // Cancel any outstanding scan requests. We are about to close all
8212 // of our adapters, but an adapter structure is what SME passes back
8213 // to our callback function. Hence if there are any outstanding scan
8214 // requests then there is a race condition between when the adapter
8215 // is closed and when the callback is invoked.We try to resolve that
8216 // race condition here by canceling any outstanding scans before we
8217 // close the adapters.
8218 // Note that the scans may be cancelled in an asynchronous manner,
8219 // so ideally there needs to be some kind of synchronization. Rather
8220 // than introduce a new synchronization here, we will utilize the
8221 // fact that we are about to Request Full Power, and since that is
8222 // synchronized, the expectation is that by the time Request Full
8223 // Power has completed all scans will be cancelled.
8224 if (pHddCtx->scan_info.mScanPending)
8225 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308226 if(NULL != pAdapter)
8227 {
8228 hddLog(VOS_TRACE_LEVEL_INFO,
8229 FL("abort scan mode: %d sessionId: %d"),
8230 pAdapter->device_mode,
8231 pAdapter->sessionId);
8232 }
8233 hdd_abort_mac_scan(pHddCtx,
8234 pHddCtx->scan_info.sessionId,
8235 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308236 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008237 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308238 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008239 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308240 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308241 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8242 {
8243 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8245 "%s: in middle of FTM START", __func__);
8246 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8247 msecs_to_jiffies(20000));
8248 if(!lrc)
8249 {
8250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8251 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8252 }
8253 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008254 wlan_hdd_ftm_close(pHddCtx);
8255 goto free_hdd_ctx;
8256 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308257
Jeff Johnson295189b2012-06-20 16:38:30 -07008258 /* DeRegister with platform driver as client for Suspend/Resume */
8259 vosStatus = hddDeregisterPmOps(pHddCtx);
8260 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8261 {
8262 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8263 VOS_ASSERT(0);
8264 }
8265
8266 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8267 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8268 {
8269 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8270 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008271
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008272 //Stop the traffic monitor timer
8273 if ( VOS_TIMER_STATE_RUNNING ==
8274 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8275 {
8276 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8277 }
8278
8279 // Destroy the traffic monitor timer
8280 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8281 &pHddCtx->tx_rx_trafficTmr)))
8282 {
8283 hddLog(VOS_TRACE_LEVEL_ERROR,
8284 "%s: Cannot deallocate Traffic monitor timer", __func__);
8285 }
8286
Jeff Johnson295189b2012-06-20 16:38:30 -07008287 //Disable IMPS/BMPS as we do not want the device to enter any power
8288 //save mode during shutdown
8289 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8290 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8291 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8292
8293 //Ensure that device is in full power as we will touch H/W during vos_Stop
8294 init_completion(&powerContext.completion);
8295 powerContext.magic = POWER_CONTEXT_MAGIC;
8296
8297 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8298 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8299
8300 if (eHAL_STATUS_SUCCESS != halStatus)
8301 {
8302 if (eHAL_STATUS_PMC_PENDING == halStatus)
8303 {
8304 /* request was sent -- wait for the response */
8305 lrc = wait_for_completion_interruptible_timeout(
8306 &powerContext.completion,
8307 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008308 if (lrc <= 0)
8309 {
8310 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008311 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008312 }
8313 }
8314 else
8315 {
8316 hddLog(VOS_TRACE_LEVEL_ERROR,
8317 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008318 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 /* continue -- need to clean up as much as possible */
8320 }
8321 }
8322
Jeff Johnson72a40512013-12-19 10:14:15 -08008323 /* either we never sent a request, we sent a request and received a
8324 response or we sent a request and timed out. if we never sent a
8325 request or if we sent a request and got a response, we want to
8326 clear the magic out of paranoia. if we timed out there is a
8327 race condition such that the callback function could be
8328 executing at the same time we are. of primary concern is if the
8329 callback function had already verified the "magic" but had not
8330 yet set the completion variable when a timeout occurred. we
8331 serialize these activities by invalidating the magic while
8332 holding a shared spinlock which will cause us to block if the
8333 callback is currently executing */
8334 spin_lock(&hdd_context_lock);
8335 powerContext.magic = 0;
8336 spin_unlock(&hdd_context_lock);
8337
Yue Ma0d4891e2013-08-06 17:01:45 -07008338 hdd_debugfs_exit(pHddCtx);
8339
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 // Unregister the Net Device Notifier
8341 unregister_netdevice_notifier(&hdd_netdev_notifier);
8342
Jeff Johnson295189b2012-06-20 16:38:30 -07008343 hdd_stop_all_adapters( pHddCtx );
8344
Jeff Johnson295189b2012-06-20 16:38:30 -07008345#ifdef WLAN_BTAMP_FEATURE
8346 vosStatus = WLANBAP_Stop(pVosContext);
8347 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8348 {
8349 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8350 "%s: Failed to stop BAP",__func__);
8351 }
8352#endif //WLAN_BTAMP_FEATURE
8353
8354 //Stop all the modules
8355 vosStatus = vos_stop( pVosContext );
8356 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8357 {
8358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8359 "%s: Failed to stop VOSS",__func__);
8360 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8361 }
8362
Jeff Johnson295189b2012-06-20 16:38:30 -07008363 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008365
8366 //Close the scheduler before calling vos_close to make sure no thread is
8367 // scheduled after the each module close is called i.e after all the data
8368 // structures are freed.
8369 vosStatus = vos_sched_close( pVosContext );
8370 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8371 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8372 "%s: Failed to close VOSS Scheduler",__func__);
8373 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8374 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008375#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008376#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8377 /* Destroy the wake lock */
8378 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8379#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008380 /* Destroy the wake lock */
8381 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008382#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008383
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308384#ifdef CONFIG_ENABLE_LINUX_REG
8385 vosStatus = vos_nv_close();
8386 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8387 {
8388 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8389 "%s: Failed to close NV", __func__);
8390 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8391 }
8392#endif
8393
Jeff Johnson295189b2012-06-20 16:38:30 -07008394 //Close VOSS
8395 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8396 vos_close(pVosContext);
8397
Jeff Johnson295189b2012-06-20 16:38:30 -07008398 //Close Watchdog
8399 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8400 vos_watchdog_close(pVosContext);
8401
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308402 //Clean up HDD Nlink Service
8403 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308404
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308405#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308406 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308407 {
8408 wlan_logging_sock_deactivate_svc();
8409 }
8410#endif
8411
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308412#ifdef WLAN_KD_READY_NOTIFIER
8413 nl_srv_exit(pHddCtx->ptt_pid);
8414#else
8415 nl_srv_exit();
8416#endif /* WLAN_KD_READY_NOTIFIER */
8417
8418
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 hdd_close_all_adapters( pHddCtx );
8420
Jeff Johnson295189b2012-06-20 16:38:30 -07008421 /* free the power on lock from platform driver */
8422 if (free_riva_power_on_lock("wlan"))
8423 {
8424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8425 __func__);
8426 }
8427
Jeff Johnson88ba7742013-02-27 14:36:02 -08008428free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308429
8430 //Free up dynamically allocated members inside HDD Adapter
8431 if (pHddCtx->cfg_ini)
8432 {
8433 kfree(pHddCtx->cfg_ini);
8434 pHddCtx->cfg_ini= NULL;
8435 }
8436
Leo Changf04ddad2013-09-18 13:46:38 -07008437 /* FTM mode, WIPHY did not registered
8438 If un-register here, system crash will happen */
8439 if (VOS_FTM_MODE != hdd_get_conparam())
8440 {
8441 wiphy_unregister(wiphy) ;
8442 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008444 if (hdd_is_ssr_required())
8445 {
8446 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008447 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008448 msleep(5000);
8449 }
8450 hdd_set_ssr_required (VOS_FALSE);
8451}
8452
8453
8454/**---------------------------------------------------------------------------
8455
8456 \brief hdd_update_config_from_nv() - Function to update the contents of
8457 the running configuration with parameters taken from NV storage
8458
8459 \param - pHddCtx - Pointer to the HDD global context
8460
8461 \return - VOS_STATUS_SUCCESS if successful
8462
8463 --------------------------------------------------------------------------*/
8464static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8465{
Jeff Johnson295189b2012-06-20 16:38:30 -07008466 v_BOOL_t itemIsValid = VOS_FALSE;
8467 VOS_STATUS status;
8468 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8469 v_U8_t macLoop;
8470
8471 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8472 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8473 if(status != VOS_STATUS_SUCCESS)
8474 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008475 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008476 return VOS_STATUS_E_FAILURE;
8477 }
8478
8479 if (itemIsValid == VOS_TRUE)
8480 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008481 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008482 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8483 VOS_MAX_CONCURRENCY_PERSONA);
8484 if(status != VOS_STATUS_SUCCESS)
8485 {
8486 /* Get MAC from NV fail, not update CFG info
8487 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008488 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008489 return VOS_STATUS_E_FAILURE;
8490 }
8491
8492 /* If first MAC is not valid, treat all others are not valid
8493 * Then all MACs will be got from ini file */
8494 if(vos_is_macaddr_zero(&macFromNV[0]))
8495 {
8496 /* MAC address in NV file is not configured yet */
8497 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8498 return VOS_STATUS_E_INVAL;
8499 }
8500
8501 /* Get MAC address from NV, update CFG info */
8502 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8503 {
8504 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8505 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308506 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008507 /* This MAC is not valid, skip it
8508 * This MAC will be got from ini file */
8509 }
8510 else
8511 {
8512 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8513 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8514 VOS_MAC_ADDR_SIZE);
8515 }
8516 }
8517 }
8518 else
8519 {
8520 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8521 return VOS_STATUS_E_FAILURE;
8522 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008523
Jeff Johnson295189b2012-06-20 16:38:30 -07008524
8525 return VOS_STATUS_SUCCESS;
8526}
8527
8528/**---------------------------------------------------------------------------
8529
8530 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8531
8532 \param - pAdapter - Pointer to the HDD
8533
8534 \return - None
8535
8536 --------------------------------------------------------------------------*/
8537VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8538{
8539 eHalStatus halStatus;
8540 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308541 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008542
Jeff Johnson295189b2012-06-20 16:38:30 -07008543
8544 // Send ready indication to the HDD. This will kick off the MAC
8545 // into a 'running' state and should kick off an initial scan.
8546 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8547 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8548 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308549 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008550 "code %08d [x%08x]",__func__, halStatus, halStatus );
8551 return VOS_STATUS_E_FAILURE;
8552 }
8553
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308554 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008555 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8556 // And RIVA will crash
8557 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8558 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308559 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8560 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8561
8562
Jeff Johnson295189b2012-06-20 16:38:30 -07008563 return VOS_STATUS_SUCCESS;
8564}
8565
Jeff Johnson295189b2012-06-20 16:38:30 -07008566/* wake lock APIs for HDD */
8567void hdd_prevent_suspend(void)
8568{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008569#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008570 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008571#else
8572 wcnss_prevent_suspend();
8573#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008574}
8575
8576void hdd_allow_suspend(void)
8577{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008578#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008579 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008580#else
8581 wcnss_allow_suspend();
8582#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008583}
8584
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308585void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008586{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008587#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008588 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008589#else
8590 /* Do nothing as there is no API in wcnss for timeout*/
8591#endif
8592}
8593
Jeff Johnson295189b2012-06-20 16:38:30 -07008594/**---------------------------------------------------------------------------
8595
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008596 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8597 information between Host and Riva
8598
8599 This function gets reported version of FW
8600 It also finds the version of Riva headers used to compile the host
8601 It compares the above two and prints a warning if they are different
8602 It gets the SW and HW version string
8603 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8604 indicating the features they support through a bitmap
8605
8606 \param - pHddCtx - Pointer to HDD context
8607
8608 \return - void
8609
8610 --------------------------------------------------------------------------*/
8611
8612void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8613{
8614
8615 tSirVersionType versionCompiled;
8616 tSirVersionType versionReported;
8617 tSirVersionString versionString;
8618 tANI_U8 fwFeatCapsMsgSupported = 0;
8619 VOS_STATUS vstatus;
8620
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008621 memset(&versionCompiled, 0, sizeof(versionCompiled));
8622 memset(&versionReported, 0, sizeof(versionReported));
8623
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008624 /* retrieve and display WCNSS version information */
8625 do {
8626
8627 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8628 &versionCompiled);
8629 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8630 {
8631 hddLog(VOS_TRACE_LEVEL_FATAL,
8632 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008633 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008634 break;
8635 }
8636
8637 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8638 &versionReported);
8639 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8640 {
8641 hddLog(VOS_TRACE_LEVEL_FATAL,
8642 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008643 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008644 break;
8645 }
8646
8647 if ((versionCompiled.major != versionReported.major) ||
8648 (versionCompiled.minor != versionReported.minor) ||
8649 (versionCompiled.version != versionReported.version) ||
8650 (versionCompiled.revision != versionReported.revision))
8651 {
8652 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8653 "Host expected %u.%u.%u.%u\n",
8654 WLAN_MODULE_NAME,
8655 (int)versionReported.major,
8656 (int)versionReported.minor,
8657 (int)versionReported.version,
8658 (int)versionReported.revision,
8659 (int)versionCompiled.major,
8660 (int)versionCompiled.minor,
8661 (int)versionCompiled.version,
8662 (int)versionCompiled.revision);
8663 }
8664 else
8665 {
8666 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8667 WLAN_MODULE_NAME,
8668 (int)versionReported.major,
8669 (int)versionReported.minor,
8670 (int)versionReported.version,
8671 (int)versionReported.revision);
8672 }
8673
8674 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8675 versionString,
8676 sizeof(versionString));
8677 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8678 {
8679 hddLog(VOS_TRACE_LEVEL_FATAL,
8680 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008681 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008682 break;
8683 }
8684
8685 pr_info("%s: WCNSS software version %s\n",
8686 WLAN_MODULE_NAME, versionString);
8687
8688 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8689 versionString,
8690 sizeof(versionString));
8691 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8692 {
8693 hddLog(VOS_TRACE_LEVEL_FATAL,
8694 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008695 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008696 break;
8697 }
8698
8699 pr_info("%s: WCNSS hardware version %s\n",
8700 WLAN_MODULE_NAME, versionString);
8701
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008702 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8703 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008704 send the message only if it the riva is 1.1
8705 minor numbers for different riva branches:
8706 0 -> (1.0)Mainline Build
8707 1 -> (1.1)Mainline Build
8708 2->(1.04) Stability Build
8709 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008710 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008711 ((versionReported.minor>=1) && (versionReported.version>=1)))
8712 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8713 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008714
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008715 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008716 {
8717#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8718 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8719 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8720#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008721 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8722 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8723 {
8724 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8725 }
8726
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008727 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008728 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008729
8730 } while (0);
8731
8732}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308733void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8734{
8735 struct sk_buff *skb;
8736 struct nlmsghdr *nlh;
8737 tAniMsgHdr *ani_hdr;
8738
8739 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8740
8741 if(skb == NULL) {
8742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8743 "%s: alloc_skb failed", __func__);
8744 return;
8745 }
8746
8747 nlh = (struct nlmsghdr *)skb->data;
8748 nlh->nlmsg_pid = 0; /* from kernel */
8749 nlh->nlmsg_flags = 0;
8750 nlh->nlmsg_seq = 0;
8751 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8752
8753 ani_hdr = NLMSG_DATA(nlh);
8754 ani_hdr->type = type;
8755
8756 switch(type) {
8757 case WLAN_SVC_SAP_RESTART_IND:
8758 ani_hdr->length = 0;
8759 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8760 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8761 break;
8762 default:
8763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8764 "Attempt to send unknown nlink message %d", type);
8765 kfree_skb(skb);
8766 return;
8767 }
8768
8769 nl_srv_bcast(skb);
8770
8771 return;
8772}
8773
8774
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008775
8776/**---------------------------------------------------------------------------
8777
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308778 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8779
8780 \param - pHddCtx - Pointer to the hdd context
8781
8782 \return - true if hardware supports 5GHz
8783
8784 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308785boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308786{
8787 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8788 * then hardware support 5Ghz.
8789 */
8790 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8791 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308792 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308793 return true;
8794 }
8795 else
8796 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308798 __func__);
8799 return false;
8800 }
8801}
8802
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308803/**---------------------------------------------------------------------------
8804
8805 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8806 generate function
8807
8808 This is generate the random mac address for WLAN interface
8809
8810 \param - pHddCtx - Pointer to HDD context
8811 idx - Start interface index to get auto
8812 generated mac addr.
8813 mac_addr - Mac address
8814
8815 \return - 0 for success, < 0 for failure
8816
8817 --------------------------------------------------------------------------*/
8818
8819static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8820 int idx, v_MACADDR_t mac_addr)
8821{
8822 int i;
8823 unsigned int serialno;
8824 serialno = wcnss_get_serial_number();
8825
8826 if (0 != serialno)
8827 {
8828 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8829 bytes of the serial number that can be used to generate
8830 the other 3 bytes of the MAC address. Mask off all but
8831 the lower 3 bytes (this will also make sure we don't
8832 overflow in the next step) */
8833 serialno &= 0x00FFFFFF;
8834
8835 /* we need a unique address for each session */
8836 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8837
8838 /* autogen other Mac addresses */
8839 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8840 {
8841 /* start with the entire default address */
8842 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8843 /* then replace the lower 3 bytes */
8844 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8845 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8846 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8847
8848 serialno++;
8849 hddLog(VOS_TRACE_LEVEL_ERROR,
8850 "%s: Derived Mac Addr: "
8851 MAC_ADDRESS_STR, __func__,
8852 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8853 }
8854
8855 }
8856 else
8857 {
8858 hddLog(LOGE, FL("Failed to Get Serial NO"));
8859 return -1;
8860 }
8861 return 0;
8862}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308863
8864/**---------------------------------------------------------------------------
8865
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308866 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8867 completed to flush out the scan results
8868
8869 11d scan is done during driver load and is a passive scan on all
8870 channels supported by the device, 11d scans may find some APs on
8871 frequencies which are forbidden to be used in the regulatory domain
8872 the device is operating in. If these APs are notified to the supplicant
8873 it may try to connect to these APs, thus flush out all the scan results
8874 which are present in SME after 11d scan is done.
8875
8876 \return - eHalStatus
8877
8878 --------------------------------------------------------------------------*/
8879static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8880 tANI_U32 scanId, eCsrScanStatus status)
8881{
8882 ENTER();
8883
8884 sme_ScanFlushResult(halHandle, 0);
8885
8886 EXIT();
8887
8888 return eHAL_STATUS_SUCCESS;
8889}
8890
8891/**---------------------------------------------------------------------------
8892
Jeff Johnson295189b2012-06-20 16:38:30 -07008893 \brief hdd_wlan_startup() - HDD init function
8894
8895 This is the driver startup code executed once a WLAN device has been detected
8896
8897 \param - dev - Pointer to the underlying device
8898
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008899 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008900
8901 --------------------------------------------------------------------------*/
8902
8903int hdd_wlan_startup(struct device *dev )
8904{
8905 VOS_STATUS status;
8906 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008907 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008908 hdd_context_t *pHddCtx = NULL;
8909 v_CONTEXT_t pVosContext= NULL;
8910#ifdef WLAN_BTAMP_FEATURE
8911 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8912 WLANBAP_ConfigType btAmpConfig;
8913 hdd_config_t *pConfig;
8914#endif
8915 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008916 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308917 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008918
8919 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008920 /*
8921 * cfg80211: wiphy allocation
8922 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308923 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008924
8925 if(wiphy == NULL)
8926 {
8927 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008928 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 pHddCtx = wiphy_priv(wiphy);
8931
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 //Initialize the adapter context to zeros.
8933 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8934
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308937 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008938
8939 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8940
8941 /*Get vos context here bcoz vos_open requires it*/
8942 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8943
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008944 if(pVosContext == NULL)
8945 {
8946 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8947 goto err_free_hdd_context;
8948 }
8949
Jeff Johnson295189b2012-06-20 16:38:30 -07008950 //Save the Global VOSS context in adapter context for future.
8951 pHddCtx->pvosContext = pVosContext;
8952
8953 //Save the adapter context in global context for future.
8954 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8955
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 pHddCtx->parent_dev = dev;
8957
8958 init_completion(&pHddCtx->full_pwr_comp_var);
8959 init_completion(&pHddCtx->standby_comp_var);
8960 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008961 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008962 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308963 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308964 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008965
8966#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008967 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008968#else
8969 init_completion(&pHddCtx->driver_crda_req);
8970#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008971
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308972 spin_lock_init(&pHddCtx->schedScan_lock);
8973
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8975
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308976#ifdef FEATURE_WLAN_TDLS
8977 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8978 * invoked by other instances also) to protect the concurrent
8979 * access for the Adapters by TDLS module.
8980 */
8981 mutex_init(&pHddCtx->tdls_lock);
8982#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05308983 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05308984 mutex_init(&pHddCtx->wmmLock);
8985
Agarwal Ashish1f422872014-07-22 00:11:55 +05308986 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308987
Agarwal Ashish1f422872014-07-22 00:11:55 +05308988 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 // Load all config first as TL config is needed during vos_open
8990 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
8991 if(pHddCtx->cfg_ini == NULL)
8992 {
8993 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
8994 goto err_free_hdd_context;
8995 }
8996
8997 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
8998
8999 // Read and parse the qcom_cfg.ini file
9000 status = hdd_parse_config_ini( pHddCtx );
9001 if ( VOS_STATUS_SUCCESS != status )
9002 {
9003 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9004 __func__, WLAN_INI_FILE);
9005 goto err_config;
9006 }
Arif Hussaind5218912013-12-05 01:10:55 -08009007#ifdef MEMORY_DEBUG
9008 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9009 vos_mem_init();
9010
9011 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9012 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9013#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009014
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309015 /* INI has been read, initialise the configuredMcastBcastFilter with
9016 * INI value as this will serve as the default value
9017 */
9018 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9019 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9020 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309021
9022 if (false == hdd_is_5g_supported(pHddCtx))
9023 {
9024 //5Ghz is not supported.
9025 if (1 != pHddCtx->cfg_ini->nBandCapability)
9026 {
9027 hddLog(VOS_TRACE_LEVEL_INFO,
9028 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9029 pHddCtx->cfg_ini->nBandCapability = 1;
9030 }
9031 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309032
9033 /* If SNR Monitoring is enabled, FW has to parse all beacons
9034 * for calcaluting and storing the average SNR, so set Nth beacon
9035 * filter to 1 to enable FW to parse all the beaocons
9036 */
9037 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9038 {
9039 /* The log level is deliberately set to WARN as overriding
9040 * nthBeaconFilter to 1 will increase power cosumption and this
9041 * might just prove helpful to detect the power issue.
9042 */
9043 hddLog(VOS_TRACE_LEVEL_WARN,
9044 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9045 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9046 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309048 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009049 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009050 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009051 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009052 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9053 {
9054 hddLog(VOS_TRACE_LEVEL_FATAL,
9055 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9056 goto err_config;
9057 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009059
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009060 // Update VOS trace levels based upon the cfg.ini
9061 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9062 pHddCtx->cfg_ini->vosTraceEnableBAP);
9063 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9064 pHddCtx->cfg_ini->vosTraceEnableTL);
9065 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9066 pHddCtx->cfg_ini->vosTraceEnableWDI);
9067 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9068 pHddCtx->cfg_ini->vosTraceEnableHDD);
9069 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9070 pHddCtx->cfg_ini->vosTraceEnableSME);
9071 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9072 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309073 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9074 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009075 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9076 pHddCtx->cfg_ini->vosTraceEnableWDA);
9077 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9078 pHddCtx->cfg_ini->vosTraceEnableSYS);
9079 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9080 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009081 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9082 pHddCtx->cfg_ini->vosTraceEnableSAP);
9083 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9084 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009085
Jeff Johnson295189b2012-06-20 16:38:30 -07009086 // Update WDI trace levels based upon the cfg.ini
9087 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9088 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9089 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9090 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9091 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9092 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9093 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9094 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009095
Jeff Johnson88ba7742013-02-27 14:36:02 -08009096 if (VOS_FTM_MODE == hdd_get_conparam())
9097 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009098 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9099 {
9100 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9101 goto err_free_hdd_context;
9102 }
9103 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
c_hpothu2de0ef62014-04-15 16:16:15 +05309104
9105 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009106 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009107 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009108
Jeff Johnson88ba7742013-02-27 14:36:02 -08009109 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009110 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9111 {
9112 status = vos_watchdog_open(pVosContext,
9113 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9114
9115 if(!VOS_IS_STATUS_SUCCESS( status ))
9116 {
9117 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309118 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009119 }
9120 }
9121
9122 pHddCtx->isLogpInProgress = FALSE;
9123 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9124
Amar Singhala49cbc52013-10-08 18:37:44 -07009125#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009126 /* initialize the NV module. This is required so that
9127 we can initialize the channel information in wiphy
9128 from the NV.bin data. The channel information in
9129 wiphy needs to be initialized before wiphy registration */
9130
9131 status = vos_nv_open();
9132 if (!VOS_IS_STATUS_SUCCESS(status))
9133 {
9134 /* NV module cannot be initialized */
9135 hddLog( VOS_TRACE_LEVEL_FATAL,
9136 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309137 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009138 }
9139
9140 status = vos_init_wiphy_from_nv_bin();
9141 if (!VOS_IS_STATUS_SUCCESS(status))
9142 {
9143 /* NV module cannot be initialized */
9144 hddLog( VOS_TRACE_LEVEL_FATAL,
9145 "%s: vos_init_wiphy failed", __func__);
9146 goto err_vos_nv_close;
9147 }
9148
Amar Singhala49cbc52013-10-08 18:37:44 -07009149#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309150 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309151 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009152 if ( !VOS_IS_STATUS_SUCCESS( status ))
9153 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009154 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309155 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 }
9157
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9159
9160 if ( NULL == pHddCtx->hHal )
9161 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009162 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 goto err_vosclose;
9164 }
9165
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009166 status = vos_preStart( pHddCtx->pvosContext );
9167 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9168 {
9169 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309170 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009171 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009172
Arif Hussaineaf68602013-12-30 23:10:44 -08009173 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9174 {
9175 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9176 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9177 __func__, enable_dfs_chan_scan);
9178 }
9179 if (0 == enable_11d || 1 == enable_11d)
9180 {
9181 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9182 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9183 __func__, enable_11d);
9184 }
9185
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009186 /* Note that the vos_preStart() sequence triggers the cfg download.
9187 The cfg download must occur before we update the SME config
9188 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 status = hdd_set_sme_config( pHddCtx );
9190
9191 if ( VOS_STATUS_SUCCESS != status )
9192 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009193 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309194 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009195 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009196
Jeff Johnson295189b2012-06-20 16:38:30 -07009197 /* In the integrated architecture we update the configuration from
9198 the INI file and from NV before vOSS has been started so that
9199 the final contents are available to send down to the cCPU */
9200
9201 // Apply the cfg.ini to cfg.dat
9202 if (FALSE == hdd_update_config_dat(pHddCtx))
9203 {
9204 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309205 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009206 }
9207
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309208 // Get mac addr from platform driver
9209 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9210
9211 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009212 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309213 /* Store the mac addr for first interface */
9214 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9215
9216 hddLog(VOS_TRACE_LEVEL_ERROR,
9217 "%s: WLAN Mac Addr: "
9218 MAC_ADDRESS_STR, __func__,
9219 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9220
9221 /* Here, passing Arg2 as 1 because we do not want to change the
9222 last 3 bytes (means non OUI bytes) of first interface mac
9223 addr.
9224 */
9225 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9226 {
9227 hddLog(VOS_TRACE_LEVEL_ERROR,
9228 "%s: Failed to generate wlan interface mac addr "
9229 "using MAC from ini file ", __func__);
9230 }
9231 }
9232 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9233 {
9234 // Apply the NV to cfg.dat
9235 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009236#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9237 /* There was not a valid set of MAC Addresses in NV. See if the
9238 default addresses were modified by the cfg.ini settings. If so,
9239 we'll use them, but if not, we'll autogenerate a set of MAC
9240 addresses based upon the device serial number */
9241
9242 static const v_MACADDR_t default_address =
9243 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009244
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309245 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9246 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009247 {
9248 /* cfg.ini has the default address, invoke autogen logic */
9249
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309250 /* Here, passing Arg2 as 0 because we want to change the
9251 last 3 bytes (means non OUI bytes) of all the interfaces
9252 mac addr.
9253 */
9254 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9255 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309257 hddLog(VOS_TRACE_LEVEL_ERROR,
9258 "%s: Failed to generate wlan interface mac addr "
9259 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9260 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009262 }
9263 else
9264#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9265 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009266 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009267 "%s: Invalid MAC address in NV, using MAC from ini file "
9268 MAC_ADDRESS_STR, __func__,
9269 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9270 }
9271 }
9272 {
9273 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309274
9275 /* Set the MAC Address Currently this is used by HAL to
9276 * add self sta. Remove this once self sta is added as
9277 * part of session open.
9278 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9280 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9281 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309282
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 if (!HAL_STATUS_SUCCESS( halStatus ))
9284 {
9285 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9286 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309287 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009288 }
9289 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009290
9291 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9292 Note: Firmware image will be read and downloaded inside vos_start API */
9293 status = vos_start( pHddCtx->pvosContext );
9294 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9295 {
9296 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309297 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 }
9299
Leo Chang6cec3e22014-01-21 15:33:49 -08009300#ifdef FEATURE_WLAN_CH_AVOID
9301 /* Plug in avoid channel notification callback
9302 * This should happen before ADD_SELF_STA
9303 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309304
9305 /* check the Channel Avoidance is enabled */
9306 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9307 {
9308 sme_AddChAvoidCallback(pHddCtx->hHal,
9309 hdd_hostapd_ch_avoid_cb);
9310 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009311#endif /* FEATURE_WLAN_CH_AVOID */
9312
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009313 /* Exchange capability info between Host and FW and also get versioning info from FW */
9314 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009315
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309316#ifdef CONFIG_ENABLE_LINUX_REG
9317 status = wlan_hdd_init_channels(pHddCtx);
9318 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9319 {
9320 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9321 __func__);
9322 goto err_vosstop;
9323 }
9324#endif
9325
Jeff Johnson295189b2012-06-20 16:38:30 -07009326 status = hdd_post_voss_start_config( pHddCtx );
9327 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9328 {
9329 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9330 __func__);
9331 goto err_vosstop;
9332 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009333
9334#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309335 wlan_hdd_cfg80211_update_reg_info( wiphy );
9336
9337 /* registration of wiphy dev with cfg80211 */
9338 if (0 > wlan_hdd_cfg80211_register(wiphy))
9339 {
9340 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9341 goto err_vosstop;
9342 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009343#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009344
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309345#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309346 /* registration of wiphy dev with cfg80211 */
9347 if (0 > wlan_hdd_cfg80211_register(wiphy))
9348 {
9349 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9350 goto err_vosstop;
9351 }
9352
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309353 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309354 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9355 {
9356 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9357 __func__);
9358 goto err_unregister_wiphy;
9359 }
9360#endif
9361
c_hpothu4a298be2014-12-22 21:12:51 +05309362 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9363
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9365 {
9366 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9367 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9368 }
9369 else
9370 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009371 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9372 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9373 if (pAdapter != NULL)
9374 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309375 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309377 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9378 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9379 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009380
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309381 /* Generate the P2P Device Address. This consists of the device's
9382 * primary MAC address with the locally administered bit set.
9383 */
9384 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009385 }
9386 else
9387 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309388 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9389 if (p2p_dev_addr != NULL)
9390 {
9391 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9392 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9393 }
9394 else
9395 {
9396 hddLog(VOS_TRACE_LEVEL_FATAL,
9397 "%s: Failed to allocate mac_address for p2p_device",
9398 __func__);
9399 goto err_close_adapter;
9400 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009402
9403 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9404 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9405 if ( NULL == pP2pAdapter )
9406 {
9407 hddLog(VOS_TRACE_LEVEL_FATAL,
9408 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009409 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009410 goto err_close_adapter;
9411 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009412 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009413 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009414
9415 if( pAdapter == NULL )
9416 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009417 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9418 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009420
Arif Hussain66559122013-11-21 10:11:40 -08009421 if (country_code)
9422 {
9423 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009424 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009425 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9426#ifndef CONFIG_ENABLE_LINUX_REG
9427 hdd_checkandupdate_phymode(pAdapter, country_code);
9428#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009429 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9430 (void *)(tSmeChangeCountryCallback)
9431 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009432 country_code,
9433 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309434 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009435 if (eHAL_STATUS_SUCCESS == ret)
9436 {
Arif Hussaincb607082013-12-20 11:57:42 -08009437 ret = wait_for_completion_interruptible_timeout(
9438 &pAdapter->change_country_code,
9439 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9440
9441 if (0 >= ret)
9442 {
9443 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9444 "%s: SME while setting country code timed out", __func__);
9445 }
Arif Hussain66559122013-11-21 10:11:40 -08009446 }
9447 else
9448 {
Arif Hussaincb607082013-12-20 11:57:42 -08009449 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9450 "%s: SME Change Country code from module param fail ret=%d",
9451 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009452 }
9453 }
9454
Jeff Johnson295189b2012-06-20 16:38:30 -07009455#ifdef WLAN_BTAMP_FEATURE
9456 vStatus = WLANBAP_Open(pVosContext);
9457 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9458 {
9459 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9460 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009461 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 }
9463
9464 vStatus = BSL_Init(pVosContext);
9465 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9466 {
9467 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9468 "%s: Failed to Init BSL",__func__);
9469 goto err_bap_close;
9470 }
9471 vStatus = WLANBAP_Start(pVosContext);
9472 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9473 {
9474 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9475 "%s: Failed to start TL",__func__);
9476 goto err_bap_close;
9477 }
9478
9479 pConfig = pHddCtx->cfg_ini;
9480 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9481 status = WLANBAP_SetConfig(&btAmpConfig);
9482
9483#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009484
Mihir Shete9c238772014-10-15 14:35:16 +05309485 /*
9486 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9487 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9488 * which is greater than 0xf. So the below check is safe to make
9489 * sure that there is no entry for UapsdMask in the ini
9490 */
9491 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9492 {
9493 if(IS_DYNAMIC_WMM_PS_ENABLED)
9494 {
9495 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9496 __func__);
9497 pHddCtx->cfg_ini->UapsdMask =
9498 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9499 }
9500 else
9501 {
9502 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9503 __func__);
9504 pHddCtx->cfg_ini->UapsdMask =
9505 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9506 }
9507 }
9508
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009509#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9510 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9511 {
9512 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9513 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9514 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9515 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9516 }
9517#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009518
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309519 wlan_hdd_tdls_init(pHddCtx);
9520
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309521 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9522
Jeff Johnson295189b2012-06-20 16:38:30 -07009523 /* Register with platform driver as client for Suspend/Resume */
9524 status = hddRegisterPmOps(pHddCtx);
9525 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9526 {
9527 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9528#ifdef WLAN_BTAMP_FEATURE
9529 goto err_bap_stop;
9530#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009531 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009532#endif //WLAN_BTAMP_FEATURE
9533 }
9534
Yue Ma0d4891e2013-08-06 17:01:45 -07009535 /* Open debugfs interface */
9536 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9537 {
9538 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9539 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009540 }
9541
Jeff Johnson295189b2012-06-20 16:38:30 -07009542 /* Register TM level change handler function to the platform */
9543 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9544 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9545 {
9546 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9547 goto err_unregister_pmops;
9548 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009549
9550 /* register for riva power on lock to platform driver */
9551 if (req_riva_power_on_lock("wlan"))
9552 {
9553 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9554 __func__);
9555 goto err_unregister_pmops;
9556 }
9557
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 // register net device notifier for device change notification
9559 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9560
9561 if(ret < 0)
9562 {
9563 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9564 goto err_free_power_on_lock;
9565 }
9566
9567 //Initialize the nlink service
9568 if(nl_srv_init() != 0)
9569 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309570 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 goto err_reg_netdev;
9572 }
9573
Leo Chang4ce1cc52013-10-21 18:27:15 -07009574#ifdef WLAN_KD_READY_NOTIFIER
9575 pHddCtx->kd_nl_init = 1;
9576#endif /* WLAN_KD_READY_NOTIFIER */
9577
Jeff Johnson295189b2012-06-20 16:38:30 -07009578 //Initialize the BTC service
9579 if(btc_activate_service(pHddCtx) != 0)
9580 {
9581 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9582 goto err_nl_srv;
9583 }
9584
9585#ifdef PTT_SOCK_SVC_ENABLE
9586 //Initialize the PTT service
9587 if(ptt_sock_activate_svc(pHddCtx) != 0)
9588 {
9589 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9590 goto err_nl_srv;
9591 }
9592#endif
9593
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309594#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9595 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9596 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309597 if(wlan_logging_sock_activate_svc(
9598 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9599 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9600 {
9601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9602 " failed", __func__);
9603 goto err_nl_srv;
9604 }
9605 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9606 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309607 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9608 pHddCtx->cfg_ini->gEnableDebugLog =
9609 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309610 }
9611#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009614 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009615 /* Action frame registered in one adapter which will
9616 * applicable to all interfaces
9617 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309618 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009620
9621 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309622 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009623
Jeff Johnson295189b2012-06-20 16:38:30 -07009624
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009625#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009626#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9627 /* Initialize the wake lcok */
9628 wake_lock_init(&pHddCtx->rx_wake_lock,
9629 WAKE_LOCK_SUSPEND,
9630 "qcom_rx_wakelock");
9631#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009632 /* Initialize the wake lcok */
9633 wake_lock_init(&pHddCtx->sap_wake_lock,
9634 WAKE_LOCK_SUSPEND,
9635 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009636#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009637
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009638 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9639 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009640
Katya Nigam5c306ea2014-06-19 15:39:54 +05309641 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9643 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309644
9645#ifdef FEATURE_WLAN_SCAN_PNO
9646 /*SME must send channel update configuration to RIVA*/
9647 sme_UpdateChannelConfig(pHddCtx->hHal);
9648#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309649 /* Send the update default channel list to the FW*/
9650 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309651#ifndef CONFIG_ENABLE_LINUX_REG
9652 /*updating wiphy so that regulatory user hints can be processed*/
9653 if (wiphy)
9654 {
9655 regulatory_hint(wiphy, "00");
9656 }
9657#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009658 // Initialize the restart logic
9659 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309660
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009661 //Register the traffic monitor timer now
9662 if ( pHddCtx->cfg_ini->dynSplitscan)
9663 {
9664 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9665 VOS_TIMER_TYPE_SW,
9666 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9667 (void *)pHddCtx);
9668 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309669#ifdef WLAN_FEATURE_EXTSCAN
9670 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9671 wlan_hdd_cfg80211_extscan_callback,
9672 pHddCtx);
9673#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309674
9675#ifdef WLAN_NS_OFFLOAD
9676 // Register IPv6 notifier to notify if any change in IP
9677 // So that we can reconfigure the offload parameters
9678 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
9679 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
9680 if (ret)
9681 {
9682 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
9683 }
9684 else
9685 {
9686 hddLog(LOGE, FL("Registered IPv6 notifier"));
9687 }
9688#endif
9689
9690 // Register IPv4 notifier to notify if any change in IP
9691 // So that we can reconfigure the offload parameters
9692 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
9693 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
9694 if (ret)
9695 {
9696 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
9697 }
9698 else
9699 {
9700 hddLog(LOGE, FL("Registered IPv4 notifier"));
9701 }
9702
Jeff Johnson295189b2012-06-20 16:38:30 -07009703 goto success;
9704
9705err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009706#ifdef WLAN_KD_READY_NOTIFIER
9707 nl_srv_exit(pHddCtx->ptt_pid);
9708#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009709 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009710#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009711err_reg_netdev:
9712 unregister_netdevice_notifier(&hdd_netdev_notifier);
9713
9714err_free_power_on_lock:
9715 free_riva_power_on_lock("wlan");
9716
9717err_unregister_pmops:
9718 hddDevTmUnregisterNotifyCallback(pHddCtx);
9719 hddDeregisterPmOps(pHddCtx);
9720
Yue Ma0d4891e2013-08-06 17:01:45 -07009721 hdd_debugfs_exit(pHddCtx);
9722
Jeff Johnson295189b2012-06-20 16:38:30 -07009723#ifdef WLAN_BTAMP_FEATURE
9724err_bap_stop:
9725 WLANBAP_Stop(pVosContext);
9726#endif
9727
9728#ifdef WLAN_BTAMP_FEATURE
9729err_bap_close:
9730 WLANBAP_Close(pVosContext);
9731#endif
9732
Jeff Johnson295189b2012-06-20 16:38:30 -07009733err_close_adapter:
9734 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309735#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309736err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309737#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309738 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009739err_vosstop:
9740 vos_stop(pVosContext);
9741
Amar Singhala49cbc52013-10-08 18:37:44 -07009742err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009743 status = vos_sched_close( pVosContext );
9744 if (!VOS_IS_STATUS_SUCCESS(status)) {
9745 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9746 "%s: Failed to close VOSS Scheduler", __func__);
9747 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9748 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009749 vos_close(pVosContext );
9750
Amar Singhal0a402232013-10-11 20:57:16 -07009751err_vos_nv_close:
9752
c_hpothue6a36282014-03-19 12:27:38 +05309753#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009754 vos_nv_close();
9755
c_hpothu70f8d812014-03-22 22:59:23 +05309756#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009757
9758err_wdclose:
9759 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9760 vos_watchdog_close(pVosContext);
9761
Jeff Johnson295189b2012-06-20 16:38:30 -07009762err_config:
9763 kfree(pHddCtx->cfg_ini);
9764 pHddCtx->cfg_ini= NULL;
9765
9766err_free_hdd_context:
9767 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 wiphy_free(wiphy) ;
9769 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009770 VOS_BUG(1);
9771
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009772 if (hdd_is_ssr_required())
9773 {
9774 /* WDI timeout had happened during load, so SSR is needed here */
9775 subsystem_restart("wcnss");
9776 msleep(5000);
9777 }
9778 hdd_set_ssr_required (VOS_FALSE);
9779
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009780 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009781
9782success:
9783 EXIT();
9784 return 0;
9785}
9786
9787/**---------------------------------------------------------------------------
9788
Jeff Johnson32d95a32012-09-10 13:15:23 -07009789 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009790
Jeff Johnson32d95a32012-09-10 13:15:23 -07009791 This is the driver entry point - called in different timeline depending
9792 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009793
9794 \param - None
9795
9796 \return - 0 for success, non zero for failure
9797
9798 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009799static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009800{
9801 VOS_STATUS status;
9802 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009803 struct device *dev = NULL;
9804 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009805#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9806 int max_retries = 0;
9807#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309808#ifdef HAVE_CBC_DONE
9809 int max_cbc_retries = 0;
9810#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009811
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309812#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9813 wlan_logging_sock_init_svc();
9814#endif
9815
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 ENTER();
9817
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009818#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009820#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009821
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309822 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009823 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9824 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9825
Jeff Johnson295189b2012-06-20 16:38:30 -07009826#ifdef ANI_BUS_TYPE_PCI
9827
9828 dev = wcnss_wlan_get_device();
9829
9830#endif // ANI_BUS_TYPE_PCI
9831
9832#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009833
9834#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9835 /* wait until WCNSS driver downloads NV */
9836 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9837 msleep(1000);
9838 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309839
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009840 if (max_retries >= 5) {
9841 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309842#ifdef WLAN_OPEN_SOURCE
9843 wake_lock_destroy(&wlan_wake_lock);
9844#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309845
9846#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9847 wlan_logging_sock_deinit_svc();
9848#endif
9849
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009850 return -ENODEV;
9851 }
9852#endif
9853
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309854#ifdef HAVE_CBC_DONE
9855 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
9856 msleep(1000);
9857 }
9858 if (max_cbc_retries >= 10) {
9859 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
9860 }
9861#endif
9862
Jeff Johnson295189b2012-06-20 16:38:30 -07009863 dev = wcnss_wlan_get_device();
9864#endif // ANI_BUS_TYPE_PLATFORM
9865
9866
9867 do {
9868 if (NULL == dev) {
9869 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9870 ret_status = -1;
9871 break;
9872 }
9873
Jeff Johnson295189b2012-06-20 16:38:30 -07009874#ifdef TIMER_MANAGER
9875 vos_timer_manager_init();
9876#endif
9877
9878 /* Preopen VOSS so that it is ready to start at least SAL */
9879 status = vos_preOpen(&pVosContext);
9880
9881 if (!VOS_IS_STATUS_SUCCESS(status))
9882 {
9883 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9884 ret_status = -1;
9885 break;
9886 }
9887
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009888#ifndef MODULE
9889 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9890 */
9891 hdd_set_conparam((v_UINT_t)con_mode);
9892#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009893
9894 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009895 if (hdd_wlan_startup(dev))
9896 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009897 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009898 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 vos_preClose( &pVosContext );
9900 ret_status = -1;
9901 break;
9902 }
9903
Jeff Johnson295189b2012-06-20 16:38:30 -07009904 } while (0);
9905
9906 if (0 != ret_status)
9907 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009908#ifdef TIMER_MANAGER
9909 vos_timer_exit();
9910#endif
9911#ifdef MEMORY_DEBUG
9912 vos_mem_exit();
9913#endif
9914
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009915#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009917#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309918
9919#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9920 wlan_logging_sock_deinit_svc();
9921#endif
9922
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9924 }
9925 else
9926 {
9927 //Send WLAN UP indication to Nlink Service
9928 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9929
9930 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 }
9932
9933 EXIT();
9934
9935 return ret_status;
9936}
9937
Jeff Johnson32d95a32012-09-10 13:15:23 -07009938/**---------------------------------------------------------------------------
9939
9940 \brief hdd_module_init() - Init Function
9941
9942 This is the driver entry point (invoked when module is loaded using insmod)
9943
9944 \param - None
9945
9946 \return - 0 for success, non zero for failure
9947
9948 --------------------------------------------------------------------------*/
9949#ifdef MODULE
9950static int __init hdd_module_init ( void)
9951{
9952 return hdd_driver_init();
9953}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009954#else /* #ifdef MODULE */
9955static int __init hdd_module_init ( void)
9956{
9957 /* Driver initialization is delayed to fwpath_changed_handler */
9958 return 0;
9959}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009960#endif /* #ifdef MODULE */
9961
Jeff Johnson295189b2012-06-20 16:38:30 -07009962
9963/**---------------------------------------------------------------------------
9964
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009965 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009966
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009967 This is the driver exit point (invoked when module is unloaded using rmmod
9968 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009969
9970 \param - None
9971
9972 \return - None
9973
9974 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009975static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009976{
9977 hdd_context_t *pHddCtx = NULL;
9978 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309979 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309980 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009981
9982 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9983
9984 //Get the global vos context
9985 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9986
9987 if(!pVosContext)
9988 {
9989 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
9990 goto done;
9991 }
9992
9993 //Get the HDD context.
9994 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
9995
9996 if(!pHddCtx)
9997 {
9998 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
9999 }
10000 else
10001 {
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010002 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10003 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10004 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10005 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010007 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010008 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10009 msecs_to_jiffies(30000));
10010 if(!rc)
10011 {
10012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10013 "%s:SSR timedout, fatal error", __func__);
10014 VOS_BUG(0);
10015 }
10016 }
10017
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010018 rtnl_lock();
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010019 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10020 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010021 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -070010022
c_hpothu8adb97b2014-12-08 19:38:20 +053010023 /* Driver Need to send country code 00 in below condition
10024 * 1) If gCountryCodePriority is set to 1; and last country
10025 * code set is through 11d. This needs to be done in case
10026 * when NV country code is 00.
10027 * This Needs to be done as when kernel store last country
10028 * code and if stored country code is not through 11d,
10029 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10030 * in next load/unload as soon as we get any country through
10031 * 11d. In sme_HandleChangeCountryCodeByUser
10032 * pMsg->countryCode will be last countryCode and
10033 * pMac->scan.countryCode11d will be country through 11d so
10034 * due to mismatch driver will disable 11d.
10035 *
10036 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010037
c_hpothu8adb97b2014-12-08 19:38:20 +053010038 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010039 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010040 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010041 {
10042 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010043 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010044 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10045 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010046
c_hpothu8adb97b2014-12-08 19:38:20 +053010047 //Do all the cleanup before deregistering the driver
10048 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010049 }
10050
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 vos_preClose( &pVosContext );
10052
10053#ifdef TIMER_MANAGER
10054 vos_timer_exit();
10055#endif
10056#ifdef MEMORY_DEBUG
10057 vos_mem_exit();
10058#endif
10059
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010060#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10061 wlan_logging_sock_deinit_svc();
10062#endif
10063
Jeff Johnson295189b2012-06-20 16:38:30 -070010064done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010065#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010067#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010068
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10070}
10071
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010072/**---------------------------------------------------------------------------
10073
10074 \brief hdd_module_exit() - Exit function
10075
10076 This is the driver exit point (invoked when module is unloaded using rmmod)
10077
10078 \param - None
10079
10080 \return - None
10081
10082 --------------------------------------------------------------------------*/
10083static void __exit hdd_module_exit(void)
10084{
10085 hdd_driver_exit();
10086}
10087
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010088#ifdef MODULE
10089static int fwpath_changed_handler(const char *kmessage,
10090 struct kernel_param *kp)
10091{
Jeff Johnson76052702013-04-16 13:55:05 -070010092 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010093}
10094
10095static int con_mode_handler(const char *kmessage,
10096 struct kernel_param *kp)
10097{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010098 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010099}
10100#else /* #ifdef MODULE */
10101/**---------------------------------------------------------------------------
10102
Jeff Johnson76052702013-04-16 13:55:05 -070010103 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010104
Jeff Johnson76052702013-04-16 13:55:05 -070010105 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010106 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010107 - invoked when module parameter fwpath is modified from userspace to signal
10108 initializing the WLAN driver or when con_mode is modified from userspace
10109 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010110
10111 \return - 0 for success, non zero for failure
10112
10113 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010114static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010115{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010116 int ret_status;
10117
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010118 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010119 ret_status = hdd_driver_init();
10120 wlan_hdd_inited = ret_status ? 0 : 1;
10121 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010122 }
10123
10124 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010125
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010126 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010127
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010128 ret_status = hdd_driver_init();
10129 wlan_hdd_inited = ret_status ? 0 : 1;
10130 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010131}
10132
Jeff Johnson295189b2012-06-20 16:38:30 -070010133/**---------------------------------------------------------------------------
10134
Jeff Johnson76052702013-04-16 13:55:05 -070010135 \brief fwpath_changed_handler() - Handler Function
10136
10137 Handle changes to the fwpath parameter
10138
10139 \return - 0 for success, non zero for failure
10140
10141 --------------------------------------------------------------------------*/
10142static int fwpath_changed_handler(const char *kmessage,
10143 struct kernel_param *kp)
10144{
10145 int ret;
10146
10147 ret = param_set_copystring(kmessage, kp);
10148 if (0 == ret)
10149 ret = kickstart_driver();
10150 return ret;
10151}
10152
10153/**---------------------------------------------------------------------------
10154
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010155 \brief con_mode_handler() -
10156
10157 Handler function for module param con_mode when it is changed by userspace
10158 Dynamically linked - do nothing
10159 Statically linked - exit and init driver, as in rmmod and insmod
10160
Jeff Johnson76052702013-04-16 13:55:05 -070010161 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010162
Jeff Johnson76052702013-04-16 13:55:05 -070010163 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010164
10165 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010166static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010167{
Jeff Johnson76052702013-04-16 13:55:05 -070010168 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010169
Jeff Johnson76052702013-04-16 13:55:05 -070010170 ret = param_set_int(kmessage, kp);
10171 if (0 == ret)
10172 ret = kickstart_driver();
10173 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010174}
10175#endif /* #ifdef MODULE */
10176
10177/**---------------------------------------------------------------------------
10178
Jeff Johnson295189b2012-06-20 16:38:30 -070010179 \brief hdd_get_conparam() -
10180
10181 This is the driver exit point (invoked when module is unloaded using rmmod)
10182
10183 \param - None
10184
10185 \return - tVOS_CON_MODE
10186
10187 --------------------------------------------------------------------------*/
10188tVOS_CON_MODE hdd_get_conparam ( void )
10189{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010190#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010191 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010192#else
10193 return (tVOS_CON_MODE)curr_con_mode;
10194#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010195}
10196void hdd_set_conparam ( v_UINT_t newParam )
10197{
10198 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010199#ifndef MODULE
10200 curr_con_mode = con_mode;
10201#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010202}
10203/**---------------------------------------------------------------------------
10204
10205 \brief hdd_softap_sta_deauth() - function
10206
10207 This to take counter measure to handle deauth req from HDD
10208
10209 \param - pAdapter - Pointer to the HDD
10210
10211 \param - enable - boolean value
10212
10213 \return - None
10214
10215 --------------------------------------------------------------------------*/
10216
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010217VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10218 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010219{
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010221 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010222
10223 ENTER();
10224
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010225 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10226 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010227
10228 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010229 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010230 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010231
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010232 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010233
10234 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010235 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010236}
10237
10238/**---------------------------------------------------------------------------
10239
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010240 \brief hdd_del_all_sta() - function
10241
10242 This function removes all the stations associated on stopping AP/P2P GO.
10243
10244 \param - pAdapter - Pointer to the HDD
10245
10246 \return - None
10247
10248 --------------------------------------------------------------------------*/
10249
10250int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10251{
10252 v_U16_t i;
10253 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010254 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10255 ptSapContext pSapCtx = NULL;
10256 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10257 if(pSapCtx == NULL){
10258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10259 FL("psapCtx is NULL"));
10260 return 1;
10261 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010262 ENTER();
10263
10264 hddLog(VOS_TRACE_LEVEL_INFO,
10265 "%s: Delete all STAs associated.",__func__);
10266 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10267 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10268 )
10269 {
10270 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10271 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010272 if ((pSapCtx->aStaInfo[i].isUsed) &&
10273 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010274 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010275 struct tagCsrDelStaParams delStaParams;
10276
10277 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010278 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010279 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10280 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010281 &delStaParams);
10282 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010283 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010284 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010285 }
10286 }
10287 }
10288
10289 EXIT();
10290 return 0;
10291}
10292
10293/**---------------------------------------------------------------------------
10294
Jeff Johnson295189b2012-06-20 16:38:30 -070010295 \brief hdd_softap_sta_disassoc() - function
10296
10297 This to take counter measure to handle deauth req from HDD
10298
10299 \param - pAdapter - Pointer to the HDD
10300
10301 \param - enable - boolean value
10302
10303 \return - None
10304
10305 --------------------------------------------------------------------------*/
10306
10307void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10308{
10309 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10310
10311 ENTER();
10312
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010313 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010314
10315 //Ignore request to disassoc bcmc station
10316 if( pDestMacAddress[0] & 0x1 )
10317 return;
10318
10319 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10320}
10321
10322void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10323{
10324 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10325
10326 ENTER();
10327
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010328 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010329
10330 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10331}
10332
Jeff Johnson295189b2012-06-20 16:38:30 -070010333/**---------------------------------------------------------------------------
10334 *
10335 * \brief hdd_get__concurrency_mode() -
10336 *
10337 *
10338 * \param - None
10339 *
10340 * \return - CONCURRENCY MODE
10341 *
10342 * --------------------------------------------------------------------------*/
10343tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10344{
10345 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10346 hdd_context_t *pHddCtx;
10347
10348 if (NULL != pVosContext)
10349 {
10350 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10351 if (NULL != pHddCtx)
10352 {
10353 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10354 }
10355 }
10356
10357 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010358 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010359 return VOS_STA;
10360}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010361v_BOOL_t
10362wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10363{
10364 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010365
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010366 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10367 if (pAdapter == NULL)
10368 {
10369 hddLog(VOS_TRACE_LEVEL_INFO,
10370 FL("GO doesn't exist"));
10371 return TRUE;
10372 }
10373 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10374 {
10375 hddLog(VOS_TRACE_LEVEL_INFO,
10376 FL("GO started"));
10377 return TRUE;
10378 }
10379 else
10380 /* wait till GO changes its interface to p2p device */
10381 hddLog(VOS_TRACE_LEVEL_INFO,
10382 FL("Del_bss called, avoid apps suspend"));
10383 return FALSE;
10384
10385}
Jeff Johnson295189b2012-06-20 16:38:30 -070010386/* Decide whether to allow/not the apps power collapse.
10387 * Allow apps power collapse if we are in connected state.
10388 * if not, allow only if we are in IMPS */
10389v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10390{
10391 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010392 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010393 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010394 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10395 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10396 hdd_adapter_t *pAdapter = NULL;
10397 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010398 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010399
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10401 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010402
Yathish9f22e662012-12-10 14:21:35 -080010403 concurrent_state = hdd_get_concurrency_mode();
10404
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010405 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10406 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10407 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010408#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010409
Yathish9f22e662012-12-10 14:21:35 -080010410 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010411 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010412 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10413 return TRUE;
10414#endif
10415
Jeff Johnson295189b2012-06-20 16:38:30 -070010416 /*loop through all adapters. TBD fix for Concurrency */
10417 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10418 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10419 {
10420 pAdapter = pAdapterNode->pAdapter;
10421 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10422 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10423 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010424 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010425 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010426 && pmcState != STOPPED && pmcState != STANDBY &&
10427 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010428 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10429 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010430 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010431 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010432 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10433 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010434 return FALSE;
10435 }
10436 }
10437 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10438 pAdapterNode = pNext;
10439 }
10440 return TRUE;
10441}
10442
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010443/* Decides whether to send suspend notification to Riva
10444 * if any adapter is in BMPS; then it is required */
10445v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10446{
10447 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10448 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10449
10450 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10451 {
10452 return TRUE;
10453 }
10454 return FALSE;
10455}
10456
Jeff Johnson295189b2012-06-20 16:38:30 -070010457void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10458{
10459 switch(mode)
10460 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010461 case VOS_STA_MODE:
10462 case VOS_P2P_CLIENT_MODE:
10463 case VOS_P2P_GO_MODE:
10464 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010465 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010466 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 break;
10468 default:
10469 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010470 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010471 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10472 "Number of open sessions for mode %d = %d"),
10473 pHddCtx->concurrency_mode, mode,
10474 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010475}
10476
10477
10478void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10479{
10480 switch(mode)
10481 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010482 case VOS_STA_MODE:
10483 case VOS_P2P_CLIENT_MODE:
10484 case VOS_P2P_GO_MODE:
10485 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010486 pHddCtx->no_of_open_sessions[mode]--;
10487 if (!(pHddCtx->no_of_open_sessions[mode]))
10488 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010489 break;
10490 default:
10491 break;
10492 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010493 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10494 "Number of open sessions for mode %d = %d"),
10495 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10496
10497}
10498/**---------------------------------------------------------------------------
10499 *
10500 * \brief wlan_hdd_incr_active_session()
10501 *
10502 * This function increments the number of active sessions
10503 * maintained per device mode
10504 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10505 * Incase of SAP/P2P GO upon bss start it is incremented
10506 *
10507 * \param pHddCtx - HDD Context
10508 * \param mode - device mode
10509 *
10510 * \return - None
10511 *
10512 * --------------------------------------------------------------------------*/
10513void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10514{
10515 switch (mode) {
10516 case VOS_STA_MODE:
10517 case VOS_P2P_CLIENT_MODE:
10518 case VOS_P2P_GO_MODE:
10519 case VOS_STA_SAP_MODE:
10520 pHddCtx->no_of_active_sessions[mode]++;
10521 break;
10522 default:
10523 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10524 break;
10525 }
10526 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10527 mode,
10528 pHddCtx->no_of_active_sessions[mode]);
10529}
10530
10531/**---------------------------------------------------------------------------
10532 *
10533 * \brief wlan_hdd_decr_active_session()
10534 *
10535 * This function decrements the number of active sessions
10536 * maintained per device mode
10537 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10538 * Incase of SAP/P2P GO upon bss stop it is decremented
10539 *
10540 * \param pHddCtx - HDD Context
10541 * \param mode - device mode
10542 *
10543 * \return - None
10544 *
10545 * --------------------------------------------------------------------------*/
10546void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10547{
10548 switch (mode) {
10549 case VOS_STA_MODE:
10550 case VOS_P2P_CLIENT_MODE:
10551 case VOS_P2P_GO_MODE:
10552 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010553 if (pHddCtx->no_of_active_sessions[mode] > 0)
10554 pHddCtx->no_of_active_sessions[mode]--;
10555 else
10556 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10557 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010558 break;
10559 default:
10560 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10561 break;
10562 }
10563 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10564 mode,
10565 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010566}
10567
Jeff Johnsone7245742012-09-05 17:12:55 -070010568/**---------------------------------------------------------------------------
10569 *
10570 * \brief wlan_hdd_restart_init
10571 *
10572 * This function initalizes restart timer/flag. An internal function.
10573 *
10574 * \param - pHddCtx
10575 *
10576 * \return - None
10577 *
10578 * --------------------------------------------------------------------------*/
10579
10580static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10581{
10582 /* Initialize */
10583 pHddCtx->hdd_restart_retries = 0;
10584 atomic_set(&pHddCtx->isRestartInProgress, 0);
10585 vos_timer_init(&pHddCtx->hdd_restart_timer,
10586 VOS_TIMER_TYPE_SW,
10587 wlan_hdd_restart_timer_cb,
10588 pHddCtx);
10589}
10590/**---------------------------------------------------------------------------
10591 *
10592 * \brief wlan_hdd_restart_deinit
10593 *
10594 * This function cleans up the resources used. An internal function.
10595 *
10596 * \param - pHddCtx
10597 *
10598 * \return - None
10599 *
10600 * --------------------------------------------------------------------------*/
10601
10602static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10603{
10604
10605 VOS_STATUS vos_status;
10606 /* Block any further calls */
10607 atomic_set(&pHddCtx->isRestartInProgress, 1);
10608 /* Cleanup */
10609 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10610 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010611 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010612 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10613 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010614 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010615
10616}
10617
10618/**---------------------------------------------------------------------------
10619 *
10620 * \brief wlan_hdd_framework_restart
10621 *
10622 * This function uses a cfg80211 API to start a framework initiated WLAN
10623 * driver module unload/load.
10624 *
10625 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10626 *
10627 *
10628 * \param - pHddCtx
10629 *
10630 * \return - VOS_STATUS_SUCCESS: Success
10631 * VOS_STATUS_E_EMPTY: Adapter is Empty
10632 * VOS_STATUS_E_NOMEM: No memory
10633
10634 * --------------------------------------------------------------------------*/
10635
10636static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10637{
10638 VOS_STATUS status = VOS_STATUS_SUCCESS;
10639 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010640 int len = (sizeof (struct ieee80211_mgmt));
10641 struct ieee80211_mgmt *mgmt = NULL;
10642
10643 /* Prepare the DEAUTH managment frame with reason code */
10644 mgmt = kzalloc(len, GFP_KERNEL);
10645 if(mgmt == NULL)
10646 {
10647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10648 "%s: memory allocation failed (%d bytes)", __func__, len);
10649 return VOS_STATUS_E_NOMEM;
10650 }
10651 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010652
10653 /* Iterate over all adapters/devices */
10654 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10655 do
10656 {
10657 if( (status == VOS_STATUS_SUCCESS) &&
10658 pAdapterNode &&
10659 pAdapterNode->pAdapter)
10660 {
10661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10662 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10663 pAdapterNode->pAdapter->dev->name,
10664 pAdapterNode->pAdapter->device_mode,
10665 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010666 /*
10667 * CFG80211 event to restart the driver
10668 *
10669 * 'cfg80211_send_unprot_deauth' sends a
10670 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10671 * of SME(Linux Kernel) state machine.
10672 *
10673 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10674 * the driver.
10675 *
10676 */
10677
10678 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010679 }
10680 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10681 pAdapterNode = pNext;
10682 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10683
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010684
10685 /* Free the allocated management frame */
10686 kfree(mgmt);
10687
Jeff Johnsone7245742012-09-05 17:12:55 -070010688 /* Retry until we unload or reach max count */
10689 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10690 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10691
10692 return status;
10693
10694}
10695/**---------------------------------------------------------------------------
10696 *
10697 * \brief wlan_hdd_restart_timer_cb
10698 *
10699 * Restart timer callback. An internal function.
10700 *
10701 * \param - User data:
10702 *
10703 * \return - None
10704 *
10705 * --------------------------------------------------------------------------*/
10706
10707void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10708{
10709 hdd_context_t *pHddCtx = usrDataForCallback;
10710 wlan_hdd_framework_restart(pHddCtx);
10711 return;
10712
10713}
10714
10715
10716/**---------------------------------------------------------------------------
10717 *
10718 * \brief wlan_hdd_restart_driver
10719 *
10720 * This function sends an event to supplicant to restart the WLAN driver.
10721 *
10722 * This function is called from vos_wlanRestart.
10723 *
10724 * \param - pHddCtx
10725 *
10726 * \return - VOS_STATUS_SUCCESS: Success
10727 * VOS_STATUS_E_EMPTY: Adapter is Empty
10728 * VOS_STATUS_E_ALREADY: Request already in progress
10729
10730 * --------------------------------------------------------------------------*/
10731VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10732{
10733 VOS_STATUS status = VOS_STATUS_SUCCESS;
10734
10735 /* A tight check to make sure reentrancy */
10736 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10737 {
Mihir Shetefd528652014-06-23 19:07:50 +053010738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010739 "%s: WLAN restart is already in progress", __func__);
10740
10741 return VOS_STATUS_E_ALREADY;
10742 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010743 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010744#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010745 wcnss_reset_intr();
10746#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010747
Jeff Johnsone7245742012-09-05 17:12:55 -070010748 return status;
10749}
10750
Mihir Shetee1093ba2014-01-21 20:13:32 +053010751/**---------------------------------------------------------------------------
10752 *
10753 * \brief wlan_hdd_init_channels
10754 *
10755 * This function is used to initialize the channel list in CSR
10756 *
10757 * This function is called from hdd_wlan_startup
10758 *
10759 * \param - pHddCtx: HDD context
10760 *
10761 * \return - VOS_STATUS_SUCCESS: Success
10762 * VOS_STATUS_E_FAULT: Failure reported by SME
10763
10764 * --------------------------------------------------------------------------*/
10765static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10766{
10767 eHalStatus status;
10768
10769 status = sme_InitChannels(pHddCtx->hHal);
10770 if (HAL_STATUS_SUCCESS(status))
10771 {
10772 return VOS_STATUS_SUCCESS;
10773 }
10774 else
10775 {
10776 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10777 __func__, status);
10778 return VOS_STATUS_E_FAULT;
10779 }
10780}
10781
Mihir Shete04206452014-11-20 17:50:58 +053010782#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010783VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010784{
10785 eHalStatus status;
10786
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010787 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010788 if (HAL_STATUS_SUCCESS(status))
10789 {
10790 return VOS_STATUS_SUCCESS;
10791 }
10792 else
10793 {
10794 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10795 __func__, status);
10796 return VOS_STATUS_E_FAULT;
10797 }
10798}
Mihir Shete04206452014-11-20 17:50:58 +053010799#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010800/*
10801 * API to find if there is any STA or P2P-Client is connected
10802 */
10803VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10804{
10805 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10806}
Jeff Johnsone7245742012-09-05 17:12:55 -070010807
Agarwal Ashish57e84372014-12-05 18:26:53 +053010808/*
10809 * API to find if there is any session connected
10810 */
10811VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
10812{
10813 return sme_is_any_session_connected(pHddCtx->hHal);
10814}
10815
10816
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010817int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10818{
10819 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10820 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010821 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053010822 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010823
10824 pScanInfo = &pHddCtx->scan_info;
10825 if (pScanInfo->mScanPending)
10826 {
c_hpothua3d45d52015-01-05 14:11:17 +053010827 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
10828 eCSR_SCAN_ABORT_DEFAULT);
10829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10830 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010831
c_hpothua3d45d52015-01-05 14:11:17 +053010832 /* If there is active scan command lets wait for the completion else
10833 * there is no need to wait as scan command might be in the SME pending
10834 * command list.
10835 */
10836 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
10837 {
10838 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10839 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010840 &pScanInfo->abortscan_event_var,
10841 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053010842 if (0 >= status)
10843 {
10844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010845 "%s: Timeout or Interrupt occurred while waiting for abort"
10846 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053010847 return -ETIMEDOUT;
10848 }
10849 }
10850 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
10851 {
10852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10853 FL("hdd_abort_mac_scan failed"));
10854 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010855 }
10856 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010857 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010858}
10859
c_hpothu225aa7c2014-10-22 17:45:13 +053010860VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10861{
10862 hdd_adapter_t *pAdapter;
10863 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10864 VOS_STATUS vosStatus;
10865
10866 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10867 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10868 {
10869 pAdapter = pAdapterNode->pAdapter;
10870 if (NULL != pAdapter)
10871 {
10872 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10873 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10874 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10875 {
10876 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10877 pAdapter->device_mode);
10878 if (VOS_STATUS_SUCCESS !=
10879 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10880 {
10881 hddLog(LOGE, FL("failed to abort ROC"));
10882 return VOS_STATUS_E_FAILURE;
10883 }
10884 }
10885 }
10886 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10887 pAdapterNode = pNext;
10888 }
10889 return VOS_STATUS_SUCCESS;
10890}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053010891
Mihir Shete0be28772015-02-17 18:42:14 +053010892hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
10893{
10894 hdd_adapter_t *pAdapter;
10895 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10896 hdd_cfg80211_state_t *cfgState;
10897 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
10898 VOS_STATUS vosStatus;
10899
10900 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
10901 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10902 {
10903 pAdapter = pAdapterNode->pAdapter;
10904 if (NULL != pAdapter)
10905 {
10906 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
10907 pRemainChanCtx = cfgState->remain_on_chan_ctx;
10908 if (pRemainChanCtx)
10909 break;
10910 }
10911 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
10912 pAdapterNode = pNext;
10913 }
10914 return pRemainChanCtx;
10915}
10916
Jeff Johnson295189b2012-06-20 16:38:30 -070010917//Register the module init/exit functions
10918module_init(hdd_module_init);
10919module_exit(hdd_module_exit);
10920
10921MODULE_LICENSE("Dual BSD/GPL");
10922MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10923MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10924
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010925module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10926 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010927
Jeff Johnson76052702013-04-16 13:55:05 -070010928module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010929 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010930
10931module_param(enable_dfs_chan_scan, int,
10932 S_IRUSR | S_IRGRP | S_IROTH);
10933
10934module_param(enable_11d, int,
10935 S_IRUSR | S_IRGRP | S_IROTH);
10936
10937module_param(country_code, charp,
10938 S_IRUSR | S_IRGRP | S_IROTH);