blob: 414557bef915bfdc34aae73efff6f182f354e8d3 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080026 */
Kiet Lam842dad02014-02-18 18:44:02 -080027
28
Kiet Lama7f454d2014-07-24 12:04:06 -070029
30
Jeff Johnson295189b2012-06-20 16:38:30 -070031/*========================================================================
32
33 \file wlan_hdd_main.c
34
35 \brief WLAN Host Device Driver implementation
36
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38 ========================================================================*/
39
40/**=========================================================================
41
42 EDIT HISTORY FOR FILE
43
44
45 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
47
48
49 $Header:$ $DateTime: $ $Author: $
50
51
52 when who what, where, why
53 -------- --- --------------------------------------------------------
54 04/5/09 Shailender Created module.
55 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module
56 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure
57 ==========================================================================*/
58
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62//#include <wlan_qct_driver.h>
63#include <wlan_hdd_includes.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070064#include <vos_api.h>
65#include <vos_sched.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070066#include <linux/etherdevice.h>
67#include <linux/firmware.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070068#ifdef ANI_BUS_TYPE_PLATFORM
69#include <linux/wcnss_wlan.h>
70#endif //ANI_BUS_TYPE_PLATFORM
71#ifdef ANI_BUS_TYPE_PCI
72#include "wcnss_wlan.h"
73#endif /* ANI_BUS_TYPE_PCI */
74#include <wlan_hdd_tx_rx.h>
75#include <palTimer.h>
76#include <wniApi.h>
77#include <wlan_nlink_srv.h>
78#include <wlan_btc_svc.h>
79#include <wlan_hdd_cfg.h>
80#include <wlan_ptt_sock_svc.h>
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053081#include <wlan_logging_sock_svc.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070082#include <wlan_hdd_wowl.h>
83#include <wlan_hdd_misc.h>
84#include <wlan_hdd_wext.h>
85#ifdef WLAN_BTAMP_FEATURE
86#include <bap_hdd_main.h>
87#include <bapInternal.h>
88#endif // WLAN_BTAMP_FEATURE
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053089#include "wlan_hdd_trace.h"
90#include "vos_types.h"
91#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070092#include <linux/wireless.h>
93#include <net/cfg80211.h>
Vinay Krishna Erannad9cbdb32014-01-16 12:59:10 +053094#include <linux/inetdevice.h>
95#include <net/addrconf.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070096#include "wlan_hdd_cfg80211.h"
97#include "wlan_hdd_p2p.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098#include <linux/rtnetlink.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070099int wlan_hdd_ftm_start(hdd_context_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700100#include "sapApi.h"
101#include <linux/semaphore.h>
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -0700102#include <linux/ctype.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530103#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
104#include <soc/qcom/subsystem_restart.h>
105#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700106#include <mach/subsystem_restart.h>
Arun Kumar Khandavalli74fe3032014-03-17 20:35:34 +0530107#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#include <wlan_hdd_hostapd.h>
109#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#include "cfgApi.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700111#include "wlan_hdd_dev_pwr.h"
112#ifdef WLAN_BTAMP_FEATURE
113#include "bap_hdd_misc.h"
114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700115#include "wlan_qct_pal_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700116#include "qwlan_version.h"
Yathish9f22e662012-12-10 14:21:35 -0800117#include "wlan_qct_wda.h"
Chilam NG571c65a2013-01-19 12:27:36 +0530118#ifdef FEATURE_WLAN_TDLS
119#include "wlan_hdd_tdls.h"
120#endif
Yue Ma0d4891e2013-08-06 17:01:45 -0700121#include "wlan_hdd_debugfs.h"
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +0530122#include "sapInternal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700123
124#ifdef MODULE
125#define WLAN_MODULE_NAME module_name(THIS_MODULE)
126#else
127#define WLAN_MODULE_NAME "wlan"
128#endif
129
130#ifdef TIMER_MANAGER
131#define TIMER_MANAGER_STR " +TIMER_MANAGER"
132#else
133#define TIMER_MANAGER_STR ""
134#endif
135
136#ifdef MEMORY_DEBUG
137#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
138#else
139#define MEMORY_DEBUG_STR ""
140#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530141#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700142/* the Android framework expects this param even though we don't use it */
143#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700144static char fwpath_buffer[BUF_LEN];
145static struct kparam_string fwpath = {
146 .string = fwpath_buffer,
147 .maxlen = BUF_LEN,
148};
Arif Hussain66559122013-11-21 10:11:40 -0800149
150static char *country_code;
151static int enable_11d = -1;
152static int enable_dfs_chan_scan = -1;
c_hpothu92367912014-05-01 15:18:17 +0530153static int gbcnMissRate = -1;
Arif Hussain66559122013-11-21 10:11:40 -0800154
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700155#ifndef MODULE
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700156static int wlan_hdd_inited;
Madan Mohan Koyyalamudi05f313c2012-09-18 19:19:15 -0700157#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700158
Jeff Johnsone7245742012-09-05 17:12:55 -0700159/*
Jeff Johnson72a40512013-12-19 10:14:15 -0800160 * spinlock for synchronizing asynchronous request/response
161 * (full description of use in wlan_hdd_main.h)
162 */
163DEFINE_SPINLOCK(hdd_context_lock);
164
165/*
Jeff Johnsone7245742012-09-05 17:12:55 -0700166 * The rate at which the driver sends RESTART event to supplicant
167 * once the function 'vos_wlanRestart()' is called
168 *
169 */
170#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */
171#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -0700172
173/*
174 * Size of Driver command strings from upper layer
175 */
176#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */
177#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */
178
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800179#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700180#define TID_MIN_VALUE 0
181#define TID_MAX_VALUE 15
182static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
183 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800184static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
185 tCsrEseBeaconReq *pEseBcnReq);
186#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700187
Atul Mittal1d722422014-03-19 11:15:07 +0530188/*
189 * Maximum buffer size used for returning the data back to user space
190 */
191#define WLAN_MAX_BUF_SIZE 1024
192#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700193
c_hpothu92367912014-05-01 15:18:17 +0530194//wait time for beacon miss rate.
195#define BCN_MISS_RATE_TIME 500
196
Sameer Thalappil50dc0092013-02-19 17:23:33 -0800197#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198static struct wake_lock wlan_wake_lock;
Jeff Johnsone7245742012-09-05 17:12:55 -0700199#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700200/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700201static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700202
203//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700204static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
205static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
206static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
207void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800208void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700209
Jeff Johnson295189b2012-06-20 16:38:30 -0700210v_U16_t hdd_select_queue(struct net_device *dev,
211 struct sk_buff *skb);
212
213#ifdef WLAN_FEATURE_PACKET_FILTERING
214static void hdd_set_multicast_list(struct net_device *dev);
215#endif
216
217void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
218
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800219#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800220void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
221static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700222static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
223 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
224 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -0700225static VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
226 tANI_U8 *pTargetApBssid,
227 tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800228#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800229#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700230VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800231#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700232
Mihir Shetee1093ba2014-01-21 20:13:32 +0530233static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530234const char * hdd_device_modetoString(v_U8_t device_mode)
235{
236 switch(device_mode)
237 {
238 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
239 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
240 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
241 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
242 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
243 CASE_RETURN_STRING( WLAN_HDD_FTM );
244 CASE_RETURN_STRING( WLAN_HDD_IBSS );
245 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
246 default:
247 return "device_mode Unknown";
248 }
249}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530250
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530251static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700252 unsigned long state,
253 void *ndev)
254{
255 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700256 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700257 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700258#ifdef WLAN_BTAMP_FEATURE
259 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700260#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530261 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700262
263 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700264 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700265 (strncmp(dev->name, "p2p", 3)))
266 return NOTIFY_DONE;
267
Jeff Johnson295189b2012-06-20 16:38:30 -0700268 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700269 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700270
Jeff Johnson27cee452013-03-27 11:10:24 -0700271 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700272 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800273 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700274 VOS_ASSERT(0);
275 return NOTIFY_DONE;
276 }
277
Jeff Johnson27cee452013-03-27 11:10:24 -0700278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
279 if (NULL == pHddCtx)
280 {
281 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
282 VOS_ASSERT(0);
283 return NOTIFY_DONE;
284 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800285 if (pHddCtx->isLogpInProgress)
286 return NOTIFY_DONE;
287
Jeff Johnson27cee452013-03-27 11:10:24 -0700288
289 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
290 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700291
292 switch (state) {
293 case NETDEV_REGISTER:
294 break;
295
296 case NETDEV_UNREGISTER:
297 break;
298
299 case NETDEV_UP:
300 break;
301
302 case NETDEV_DOWN:
303 break;
304
305 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700306 if(TRUE == pAdapter->isLinkUpSvcNeeded)
307 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700308 break;
309
310 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530311 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530312 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530313 {
314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
315 "%s: Timeout occurred while waiting for abortscan %ld",
316 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700317 }
318 else
319 {
320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530321 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 }
323#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 status = WLANBAP_StopAmp();
326 if(VOS_STATUS_SUCCESS != status )
327 {
328 pHddCtx->isAmpAllowed = VOS_TRUE;
329 hddLog(VOS_TRACE_LEVEL_FATAL,
330 "%s: Failed to stop AMP", __func__);
331 }
332 else
333 {
334 //a state m/c implementation in PAL is TBD to avoid this delay
335 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700336 if ( pHddCtx->isAmpAllowed )
337 {
338 WLANBAP_DeregisterFromHCI();
339 pHddCtx->isAmpAllowed = VOS_FALSE;
340 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700341 }
342#endif //WLAN_BTAMP_FEATURE
343 break;
344
345 default:
346 break;
347 }
348
349 return NOTIFY_DONE;
350}
351
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530352static int hdd_netdev_notifier_call(struct notifier_block * nb,
353 unsigned long state,
354 void *ndev)
355{
356 int ret;
357 vos_ssr_protect(__func__);
358 ret = __hdd_netdev_notifier_call( nb, state, ndev);
359 vos_ssr_unprotect(__func__);
360 return ret;
361}
362
Jeff Johnson295189b2012-06-20 16:38:30 -0700363struct notifier_block hdd_netdev_notifier = {
364 .notifier_call = hdd_netdev_notifier_call,
365};
366
367/*---------------------------------------------------------------------------
368 * Function definitions
369 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700370void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
371void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700372//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700373static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700374#ifndef MODULE
375/* current con_mode - used only for statically linked driver
376 * con_mode is changed by userspace to indicate a mode change which will
377 * result in calling the module exit and init functions. The module
378 * exit function will clean up based on the value of con_mode prior to it
379 * being changed by userspace. So curr_con_mode records the current con_mode
380 * for exit when con_mode becomes the next mode for init
381 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700382static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700383#endif
384
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800385/**---------------------------------------------------------------------------
386
387 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
388
389 Called immediately after the cfg.ini is read in order to configure
390 the desired trace levels.
391
392 \param - moduleId - module whose trace level is being configured
393 \param - bitmask - bitmask of log levels to be enabled
394
395 \return - void
396
397 --------------------------------------------------------------------------*/
398static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
399{
400 wpt_tracelevel level;
401
402 /* if the bitmask is the default value, then a bitmask was not
403 specified in cfg.ini, so leave the logging level alone (it
404 will remain at the "compiled in" default value) */
405 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
406 {
407 return;
408 }
409
410 /* a mask was specified. start by disabling all logging */
411 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
412
413 /* now cycle through the bitmask until all "set" bits are serviced */
414 level = VOS_TRACE_LEVEL_FATAL;
415 while (0 != bitmask)
416 {
417 if (bitmask & 1)
418 {
419 vos_trace_setValue(moduleId, level, 1);
420 }
421 level++;
422 bitmask >>= 1;
423 }
424}
425
426
Jeff Johnson295189b2012-06-20 16:38:30 -0700427/**---------------------------------------------------------------------------
428
429 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
430
431 Called immediately after the cfg.ini is read in order to configure
432 the desired trace levels in the WDI.
433
434 \param - moduleId - module whose trace level is being configured
435 \param - bitmask - bitmask of log levels to be enabled
436
437 \return - void
438
439 --------------------------------------------------------------------------*/
440static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
441{
442 wpt_tracelevel level;
443
444 /* if the bitmask is the default value, then a bitmask was not
445 specified in cfg.ini, so leave the logging level alone (it
446 will remain at the "compiled in" default value) */
447 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
448 {
449 return;
450 }
451
452 /* a mask was specified. start by disabling all logging */
453 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
454
455 /* now cycle through the bitmask until all "set" bits are serviced */
456 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
457 while (0 != bitmask)
458 {
459 if (bitmask & 1)
460 {
461 wpalTraceSetLevel(moduleId, level, 1);
462 }
463 level++;
464 bitmask >>= 1;
465 }
466}
Jeff Johnson295189b2012-06-20 16:38:30 -0700467
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530468/*
469 * FUNCTION: wlan_hdd_validate_context
470 * This function is used to check the HDD context
471 */
472int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
473{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530474
475 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
476 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530478 "%s: HDD context is Null", __func__);
479 return -ENODEV;
480 }
481
482 if (pHddCtx->isLogpInProgress)
483 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530485 "%s: LOGP %s. Ignore!!", __func__,
486 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
487 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530488 return -EAGAIN;
489 }
490
Mihir Shete18156292014-03-11 15:38:30 +0530491 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530492 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530494 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
495 return -EAGAIN;
496 }
497 return 0;
498}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700499#ifdef CONFIG_ENABLE_LINUX_REG
500void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
501{
502 hdd_adapter_t *pAdapter = NULL;
503 hdd_station_ctx_t *pHddStaCtx = NULL;
504 eCsrPhyMode phyMode;
505 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530506
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700507 if (NULL == pHddCtx)
508 {
509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
510 "HDD Context is null !!");
511 return ;
512 }
513
514 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
515 if (NULL == pAdapter)
516 {
517 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
518 "pAdapter is null !!");
519 return ;
520 }
521
522 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
523 if (NULL == pHddStaCtx)
524 {
525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
526 "pHddStaCtx is null !!");
527 return ;
528 }
529
530 cfg_param = pHddCtx->cfg_ini;
531 if (NULL == cfg_param)
532 {
533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
534 "cfg_params not available !!");
535 return ;
536 }
537
538 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
539
540 if (!pHddCtx->isVHT80Allowed)
541 {
542 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
543 (eCSR_DOT11_MODE_11ac == phyMode) ||
544 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
545 {
546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
547 "Setting phymode to 11n!!");
548 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
549 }
550 }
551 else
552 {
553 /*New country Supports 11ac as well resetting value back from .ini*/
554 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
555 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
556 return ;
557 }
558
559 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
560 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
561 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
562 {
563 VOS_STATUS vosStatus;
564
565 // need to issue a disconnect to CSR.
566 INIT_COMPLETION(pAdapter->disconnect_comp_var);
567 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
568 pAdapter->sessionId,
569 eCSR_DISCONNECT_REASON_UNSPECIFIED );
570
571 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530572 {
573 long ret;
574
575 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700576 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530577 if (0 >= ret)
578 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
579 ret);
580 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700581
582 }
583}
584#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530585void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
586{
587 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
588 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
589 hdd_config_t *cfg_param;
590 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530591 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530592
593 if (NULL == pHddCtx)
594 {
595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
596 "HDD Context is null !!");
597 return ;
598 }
599
600 cfg_param = pHddCtx->cfg_ini;
601
602 if (NULL == cfg_param)
603 {
604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
605 "cfg_params not available !!");
606 return ;
607 }
608
609 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
610
611 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
612 {
613 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
614 (eCSR_DOT11_MODE_11ac == phyMode) ||
615 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
616 {
617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
618 "Setting phymode to 11n!!");
619 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
620 }
621 }
622 else
623 {
624 /*New country Supports 11ac as well resetting value back from .ini*/
625 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
626 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
627 return ;
628 }
629
630 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
631 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
632 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
633 {
634 VOS_STATUS vosStatus;
635
636 // need to issue a disconnect to CSR.
637 INIT_COMPLETION(pAdapter->disconnect_comp_var);
638 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
639 pAdapter->sessionId,
640 eCSR_DISCONNECT_REASON_UNSPECIFIED );
641
642 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530643 {
644 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530645 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530646 if (ret <= 0)
647 {
648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
649 "wait on disconnect_comp_var is failed %ld", ret);
650 }
651 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530652
653 }
654}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700655#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530656
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700657void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
658{
659 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
660 hdd_config_t *cfg_param;
661
662 if (NULL == pHddCtx)
663 {
664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
665 "HDD Context is null !!");
666 return ;
667 }
668
669 cfg_param = pHddCtx->cfg_ini;
670
671 if (NULL == cfg_param)
672 {
673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
674 "cfg_params not available !!");
675 return ;
676 }
677
Agarwal Ashish738843c2014-09-25 12:27:56 +0530678 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
679 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700680 {
681 /*New country doesn't support DFS */
682 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
683 }
684 else
685 {
686 /*New country Supports DFS as well resetting value back from .ini*/
687 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
688 }
689
690}
691
Rajeev79dbe4c2013-10-05 11:03:42 +0530692#ifdef FEATURE_WLAN_BATCH_SCAN
693
694/**---------------------------------------------------------------------------
695
696 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
697 input string
698
699 This function extracts assigned integer from string in below format:
700 "STRING=10" : extracts integer 10 from this string
701
702 \param - pInPtr Pointer to input string
703 \param - base Base for string to int conversion(10 for decimal 16 for hex)
704 \param - pOutPtr Pointer to variable in which extracted integer needs to be
705 assigned
706 \param - pLastArg to tell whether it is last arguement in input string or
707 not
708
709 \return - NULL for failure cases
710 pointer to next arguement in input string for success cases
711 --------------------------------------------------------------------------*/
712static tANI_U8 *
713hdd_extract_assigned_int_from_str
714(
715 tANI_U8 *pInPtr,
716 tANI_U8 base,
717 tANI_U32 *pOutPtr,
718 tANI_U8 *pLastArg
719)
720{
721 int tempInt;
722 int v = 0;
723 char buf[32];
724 int val = 0;
725 *pLastArg = FALSE;
726
727 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
728 if (NULL == pInPtr)
729 {
730 return NULL;
731 }
732
733 pInPtr++;
734
735 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
736
737 val = sscanf(pInPtr, "%32s ", buf);
738 if (val < 0 && val > strlen(pInPtr))
739 {
740 return NULL;
741 }
742 pInPtr += val;
743 v = kstrtos32(buf, base, &tempInt);
744 if (v < 0)
745 {
746 return NULL;
747 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -0800748 if (tempInt < 0)
749 {
750 tempInt = 0;
751 }
Rajeev79dbe4c2013-10-05 11:03:42 +0530752 *pOutPtr = tempInt;
753
754 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
755 if (NULL == pInPtr)
756 {
757 *pLastArg = TRUE;
758 return NULL;
759 }
760 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
761
762 return pInPtr;
763}
764
765/**---------------------------------------------------------------------------
766
767 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
768 input string
769
770 This function extracts assigned character from string in below format:
771 "STRING=A" : extracts char 'A' from this string
772
773 \param - pInPtr Pointer to input string
774 \param - pOutPtr Pointer to variable in which extracted char needs to be
775 assigned
776 \param - pLastArg to tell whether it is last arguement in input string or
777 not
778
779 \return - NULL for failure cases
780 pointer to next arguement in input string for success cases
781 --------------------------------------------------------------------------*/
782static tANI_U8 *
783hdd_extract_assigned_char_from_str
784(
785 tANI_U8 *pInPtr,
786 tANI_U8 *pOutPtr,
787 tANI_U8 *pLastArg
788)
789{
790 *pLastArg = FALSE;
791
792 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
793 if (NULL == pInPtr)
794 {
795 return NULL;
796 }
797
798 pInPtr++;
799
800 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
801
802 *pOutPtr = *pInPtr;
803
804 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
805 if (NULL == pInPtr)
806 {
807 *pLastArg = TRUE;
808 return NULL;
809 }
810 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
811
812 return pInPtr;
813}
814
815
816/**---------------------------------------------------------------------------
817
818 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
819
820 This function parses set batch scan command in below format:
821 WLS_BATCHING_SET <space> followed by below arguements
822 "SCANFREQ=XX" : Optional defaults to 30 sec
823 "MSCAN=XX" : Required number of scans to attempt to batch
824 "BESTN=XX" : Best Network (RSSI) defaults to 16
825 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
826 A. implies only 5 GHz , B. implies only 2.4GHz
827 "RTT=X" : optional defaults to 0
828 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
829 error
830
831 For example input commands:
832 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
833 translated into set batch scan with following parameters:
834 a) Frequence 60 seconds
835 b) Batch 10 scans together
836 c) Best RSSI to be 20
837 d) 5GHz band only
838 e) RTT is equal to 0
839
840 \param - pValue Pointer to input channel list
841 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
842
843 \return - 0 for success non-zero for failure
844
845 --------------------------------------------------------------------------*/
846static int
847hdd_parse_set_batchscan_command
848(
849 tANI_U8 *pValue,
850 tSirSetBatchScanReq *pHddSetBatchScanReq
851)
852{
853 tANI_U8 *inPtr = pValue;
854 tANI_U8 val = 0;
855 tANI_U8 lastArg = 0;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800856 tANI_U32 nScanFreq;
857 tANI_U32 nMscan;
858 tANI_U32 nBestN;
859 tANI_U8 ucRfBand;
860 tANI_U32 nRtt;
Rajeev Kumarc933d982013-11-18 20:04:20 -0800861 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +0530862
863 /*initialize default values*/
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800864 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
865 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
866 nRtt = 0;
867 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
Rajeev79dbe4c2013-10-05 11:03:42 +0530868
869 /*go to space after WLS_BATCHING_SET command*/
870 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
871 /*no argument after the command*/
872 if (NULL == inPtr)
873 {
874 return -EINVAL;
875 }
876
877 /*no space after the command*/
878 else if (SPACE_ASCII_VALUE != *inPtr)
879 {
880 return -EINVAL;
881 }
882
883 /*removing empty spaces*/
884 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
885
886 /*no argument followed by spaces*/
887 if ('\0' == *inPtr)
888 {
889 return -EINVAL;
890 }
891
892 /*check and parse SCANFREQ*/
893 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
894 {
895 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800896 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800897
Rajeev Kumarc933d982013-11-18 20:04:20 -0800898 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800899 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800900 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800901 }
902
Rajeev79dbe4c2013-10-05 11:03:42 +0530903 if ( (NULL == inPtr) || (TRUE == lastArg))
904 {
905 return -EINVAL;
906 }
907 }
908
909 /*check and parse MSCAN*/
910 if ((strncmp(inPtr, "MSCAN", 5) == 0))
911 {
912 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800913 &nMscan, &lastArg);
914
915 if (0 == nMscan)
916 {
917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
918 "invalid MSCAN=%d", nMscan);
919 return -EINVAL;
920 }
921
Rajeev79dbe4c2013-10-05 11:03:42 +0530922 if (TRUE == lastArg)
923 {
924 goto done;
925 }
926 else if (NULL == inPtr)
927 {
928 return -EINVAL;
929 }
930 }
931 else
932 {
933 return -EINVAL;
934 }
935
936 /*check and parse BESTN*/
937 if ((strncmp(inPtr, "BESTN", 5) == 0))
938 {
939 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -0800940 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800941
Rajeev Kumarc933d982013-11-18 20:04:20 -0800942 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800943 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800944 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800945 }
946
Rajeev79dbe4c2013-10-05 11:03:42 +0530947 if (TRUE == lastArg)
948 {
949 goto done;
950 }
951 else if (NULL == inPtr)
952 {
953 return -EINVAL;
954 }
955 }
956
957 /*check and parse CHANNEL*/
958 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
959 {
960 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -0800961
Rajeev79dbe4c2013-10-05 11:03:42 +0530962 if (('A' == val) || ('a' == val))
963 {
c_hpothuebf89732014-02-25 13:00:24 +0530964 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530965 }
966 else if (('B' == val) || ('b' == val))
967 {
c_hpothuebf89732014-02-25 13:00:24 +0530968 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +0530969 }
970 else
971 {
Rajeev Kumarc933d982013-11-18 20:04:20 -0800972 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
973 }
974
975 if (TRUE == lastArg)
976 {
977 goto done;
978 }
979 else if (NULL == inPtr)
980 {
Rajeev79dbe4c2013-10-05 11:03:42 +0530981 return -EINVAL;
982 }
983 }
984
985 /*check and parse RTT*/
986 if ((strncmp(inPtr, "RTT", 3) == 0))
987 {
988 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -0800989 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +0530990 if (TRUE == lastArg)
991 {
992 goto done;
993 }
994 if (NULL == inPtr)
995 {
996 return -EINVAL;
997 }
998 }
999
1000
1001done:
1002
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001003 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1004 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1005 pHddSetBatchScanReq->bestNetwork = nBestN;
1006 pHddSetBatchScanReq->rfBand = ucRfBand;
1007 pHddSetBatchScanReq->rtt = nRtt;
1008
Rajeev79dbe4c2013-10-05 11:03:42 +05301009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1010 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1011 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1012 pHddSetBatchScanReq->scanFrequency,
1013 pHddSetBatchScanReq->numberOfScansToBatch,
1014 pHddSetBatchScanReq->bestNetwork,
1015 pHddSetBatchScanReq->rfBand,
1016 pHddSetBatchScanReq->rtt);
1017
1018 return 0;
1019}/*End of hdd_parse_set_batchscan_command*/
1020
1021/**---------------------------------------------------------------------------
1022
1023 \brief hdd_set_batch_scan_req_callback () - This function is called after
1024 receiving set batch scan response from FW and it saves set batch scan
1025 response data FW to HDD context and sets the completion event on
1026 which hdd_ioctl is waiting
1027
1028 \param - callbackContext Pointer to HDD adapter
1029 \param - pRsp Pointer to set batch scan response data received from FW
1030
1031 \return - nothing
1032
1033 --------------------------------------------------------------------------*/
1034static void hdd_set_batch_scan_req_callback
1035(
1036 void *callbackContext,
1037 tSirSetBatchScanRsp *pRsp
1038)
1039{
1040 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1041 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1042
1043 /*sanity check*/
1044 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1045 {
1046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1047 "%s: Invalid pAdapter magic", __func__);
1048 VOS_ASSERT(0);
1049 return;
1050 }
1051 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1052
1053 /*save set batch scan response*/
1054 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1055
1056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1057 "Received set batch scan rsp from FW with nScansToBatch=%d",
1058 pHddSetBatchScanRsp->nScansToBatch);
1059
1060 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1061 complete(&pAdapter->hdd_set_batch_scan_req_var);
1062
1063 return;
1064}/*End of hdd_set_batch_scan_req_callback*/
1065
1066
1067/**---------------------------------------------------------------------------
1068
1069 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1070 info in hdd batch scan response queue
1071
1072 \param - pAdapter Pointer to hdd adapter
1073 \param - pAPMetaInfo Pointer to access point meta info
1074 \param - scanId scan ID of batch scan response
1075 \param - isLastAp tells whether AP is last AP in batch scan response or not
1076
1077 \return - nothing
1078
1079 --------------------------------------------------------------------------*/
1080static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1081 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1082{
1083 tHddBatchScanRsp *pHead;
1084 tHddBatchScanRsp *pNode;
1085 tHddBatchScanRsp *pPrev;
1086 tHddBatchScanRsp *pTemp;
1087 tANI_U8 ssidLen;
1088
1089 /*head of hdd batch scan response queue*/
1090 pHead = pAdapter->pBatchScanRsp;
1091
1092 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1093 if (NULL == pNode)
1094 {
1095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1096 "%s: Could not allocate memory", __func__);
1097 VOS_ASSERT(0);
1098 return;
1099 }
1100
1101 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1102 sizeof(pNode->ApInfo.bssid));
1103 ssidLen = strlen(pApMetaInfo->ssid);
1104 if (SIR_MAX_SSID_SIZE < ssidLen)
1105 {
1106 /*invalid scan result*/
1107 vos_mem_free(pNode);
1108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1109 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1110 return;
1111 }
1112 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1113 /*null terminate ssid*/
1114 pNode->ApInfo.ssid[ssidLen] = '\0';
1115 pNode->ApInfo.ch = pApMetaInfo->ch;
1116 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1117 pNode->ApInfo.age = pApMetaInfo->timestamp;
1118 pNode->ApInfo.batchId = scanId;
1119 pNode->ApInfo.isLastAp = isLastAp;
1120
1121 pNode->pNext = NULL;
1122 if (NULL == pHead)
1123 {
1124 pAdapter->pBatchScanRsp = pNode;
1125 }
1126 else
1127 {
1128 pTemp = pHead;
1129 while (NULL != pTemp)
1130 {
1131 pPrev = pTemp;
1132 pTemp = pTemp->pNext;
1133 }
1134 pPrev->pNext = pNode;
1135 }
1136
1137 return;
1138}/*End of hdd_populate_batch_scan_rsp_queue*/
1139
1140/**---------------------------------------------------------------------------
1141
1142 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1143 receiving batch scan response indication from FW. It saves get batch scan
1144 response data in HDD batch scan response queue. This callback sets the
1145 completion event on which hdd_ioctl is waiting only after getting complete
1146 batch scan response data from FW
1147
1148 \param - callbackContext Pointer to HDD adapter
1149 \param - pRsp Pointer to get batch scan response data received from FW
1150
1151 \return - nothing
1152
1153 --------------------------------------------------------------------------*/
1154static void hdd_batch_scan_result_ind_callback
1155(
1156 void *callbackContext,
1157 void *pRsp
1158)
1159{
1160 v_BOOL_t isLastAp;
1161 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001162 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301163 tANI_U32 numberScanList;
1164 tANI_U32 nextScanListOffset;
1165 tANI_U32 nextApMetaInfoOffset;
1166 hdd_adapter_t* pAdapter;
1167 tpSirBatchScanList pScanList;
1168 tpSirBatchScanNetworkInfo pApMetaInfo;
1169 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1170 tSirSetBatchScanReq *pReq;
1171
1172 pAdapter = (hdd_adapter_t *)callbackContext;
1173 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001174 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301175 {
1176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1177 "%s: Invalid pAdapter magic", __func__);
1178 VOS_ASSERT(0);
1179 return;
1180 }
1181
1182 /*initialize locals*/
1183 pReq = &pAdapter->hddSetBatchScanReq;
1184 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1185 isLastAp = FALSE;
1186 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001187 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301188 numberScanList = 0;
1189 nextScanListOffset = 0;
1190 nextApMetaInfoOffset = 0;
1191 pScanList = NULL;
1192 pApMetaInfo = NULL;
1193
1194 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1195 {
1196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1197 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1198 isLastAp = TRUE;
1199 goto done;
1200 }
1201
1202 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1204 "Batch scan rsp: numberScalList %d", numberScanList);
1205
1206 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1207 {
1208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1209 "%s: numberScanList %d", __func__, numberScanList);
1210 isLastAp = TRUE;
1211 goto done;
1212 }
1213
1214 while (numberScanList)
1215 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001216 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301217 nextScanListOffset);
1218 if (NULL == pScanList)
1219 {
1220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1221 "%s: pScanList is %p", __func__, pScanList);
1222 isLastAp = TRUE;
1223 goto done;
1224 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001225 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001227 "Batch scan rsp: numApMetaInfo %d scanId %d",
1228 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301229
1230 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1231 {
1232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1233 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1234 isLastAp = TRUE;
1235 goto done;
1236 }
1237
Rajeev Kumarce651e42013-10-21 18:57:15 -07001238 /*Initialize next AP meta info offset for next scan list*/
1239 nextApMetaInfoOffset = 0;
1240
Rajeev79dbe4c2013-10-05 11:03:42 +05301241 while (numApMetaInfo)
1242 {
1243 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1244 nextApMetaInfoOffset);
1245 if (NULL == pApMetaInfo)
1246 {
1247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1248 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1249 isLastAp = TRUE;
1250 goto done;
1251 }
1252 /*calculate AP age*/
1253 pApMetaInfo->timestamp =
1254 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1255
1256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001257 "%s: bssId "MAC_ADDRESS_STR
1258 " ch %d rssi %d timestamp %d", __func__,
1259 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1260 pApMetaInfo->ch, pApMetaInfo->rssi,
1261 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301262
1263 /*mark last AP in batch scan response*/
1264 if ((TRUE == pBatchScanRsp->isLastResult) &&
1265 (1 == numberScanList) && (1 == numApMetaInfo))
1266 {
1267 isLastAp = TRUE;
1268 }
1269
1270 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1271 /*store batch scan repsonse in hdd queue*/
1272 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1273 pScanList->scanId, isLastAp);
1274 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1275
1276 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1277 numApMetaInfo--;
1278 }
1279
Rajeev Kumarce651e42013-10-21 18:57:15 -07001280 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1281 + (sizeof(tSirBatchScanNetworkInfo)
1282 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301283 numberScanList--;
1284 }
1285
1286done:
1287
1288 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1289 requested from hdd_ioctl*/
1290 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1291 (TRUE == isLastAp))
1292 {
1293 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1294 complete(&pAdapter->hdd_get_batch_scan_req_var);
1295 }
1296
1297 return;
1298}/*End of hdd_batch_scan_result_ind_callback*/
1299
1300/**---------------------------------------------------------------------------
1301
1302 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1303 response as per batch scan FR request format by putting proper markers
1304
1305 \param - pDest pointer to destination buffer
1306 \param - cur_len current length
1307 \param - tot_len total remaining size which can be written to user space
1308 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1309 \param - pAdapter Pointer to HDD adapter
1310
1311 \return - ret no of characters written
1312
1313 --------------------------------------------------------------------------*/
1314static tANI_U32
1315hdd_format_batch_scan_rsp
1316(
1317 tANI_U8 *pDest,
1318 tANI_U32 cur_len,
1319 tANI_U32 tot_len,
1320 tHddBatchScanRsp *pApMetaInfo,
1321 hdd_adapter_t* pAdapter
1322)
1323{
1324 tANI_U32 ret = 0;
1325 tANI_U32 rem_len = 0;
1326 tANI_U8 temp_len = 0;
1327 tANI_U8 temp_total_len = 0;
1328 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1329 tANI_U8 *pTemp = temp;
1330
1331 /*Batch scan reponse needs to be returned to user space in
1332 following format:
1333 "scancount=X\n" where X is the number of scans in current batch
1334 batch
1335 "trunc\n" optional present if current scan truncated
1336 "bssid=XX:XX:XX:XX:XX:XX\n"
1337 "ssid=XXXX\n"
1338 "freq=X\n" frequency in Mhz
1339 "level=XX\n"
1340 "age=X\n" ms
1341 "dist=X\n" cm (-1 if not available)
1342 "errror=X\n" (-1if not available)
1343 "====\n" (end of ap marker)
1344 "####\n" (end of scan marker)
1345 "----\n" (end of results)*/
1346 /*send scan result in above format to user space based on
1347 available length*/
1348 /*The GET response may have more data than the driver can return in its
1349 buffer. In that case the buffer should be filled to the nearest complete
1350 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1351 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1352 The final buffer should end with "----\n"*/
1353
1354 /*sanity*/
1355 if (cur_len > tot_len)
1356 {
1357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1358 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1359 return 0;
1360 }
1361 else
1362 {
1363 rem_len = (tot_len - cur_len);
1364 }
1365
1366 /*end scan marker*/
1367 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1368 {
1369 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1370 pTemp += temp_len;
1371 temp_total_len += temp_len;
1372 }
1373
1374 /*bssid*/
1375 temp_len = snprintf(pTemp, sizeof(temp),
1376 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1377 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1378 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1379 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1380 pTemp += temp_len;
1381 temp_total_len += temp_len;
1382
1383 /*ssid*/
1384 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1385 pApMetaInfo->ApInfo.ssid);
1386 pTemp += temp_len;
1387 temp_total_len += temp_len;
1388
1389 /*freq*/
1390 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001391 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301392 pTemp += temp_len;
1393 temp_total_len += temp_len;
1394
1395 /*level*/
1396 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1397 pApMetaInfo->ApInfo.rssi);
1398 pTemp += temp_len;
1399 temp_total_len += temp_len;
1400
1401 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001402 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301403 pApMetaInfo->ApInfo.age);
1404 pTemp += temp_len;
1405 temp_total_len += temp_len;
1406
1407 /*dist*/
1408 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1409 pTemp += temp_len;
1410 temp_total_len += temp_len;
1411
1412 /*error*/
1413 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1414 pTemp += temp_len;
1415 temp_total_len += temp_len;
1416
1417 /*end AP marker*/
1418 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1419 pTemp += temp_len;
1420 temp_total_len += temp_len;
1421
1422 /*last AP in batch scan response*/
1423 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1424 {
1425 /*end scan marker*/
1426 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1427 pTemp += temp_len;
1428 temp_total_len += temp_len;
1429
1430 /*end batch scan result marker*/
1431 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1432 pTemp += temp_len;
1433 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001434
Rajeev79dbe4c2013-10-05 11:03:42 +05301435 }
1436
1437 if (temp_total_len < rem_len)
1438 {
1439 ret = temp_total_len + 1;
1440 strlcpy(pDest, temp, ret);
1441 pAdapter->isTruncated = FALSE;
1442 }
1443 else
1444 {
1445 pAdapter->isTruncated = TRUE;
1446 if (rem_len >= strlen("%%%%"))
1447 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001448 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05301449 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08001450 else
Rajeev79dbe4c2013-10-05 11:03:42 +05301451 {
1452 ret = 0;
1453 }
1454 }
1455
1456 return ret;
1457
1458}/*End of hdd_format_batch_scan_rsp*/
1459
1460/**---------------------------------------------------------------------------
1461
1462 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
1463 buffer starting with head of hdd batch scan response queue
1464
1465 \param - pAdapter Pointer to HDD adapter
1466 \param - pDest Pointer to user data buffer
1467 \param - cur_len current offset in user buffer
1468 \param - rem_len remaining no of bytes in user buffer
1469
1470 \return - number of bytes written in user buffer
1471
1472 --------------------------------------------------------------------------*/
1473
1474tANI_U32 hdd_populate_user_batch_scan_rsp
1475(
1476 hdd_adapter_t* pAdapter,
1477 tANI_U8 *pDest,
1478 tANI_U32 cur_len,
1479 tANI_U32 rem_len
1480)
1481{
1482 tHddBatchScanRsp *pHead;
1483 tHddBatchScanRsp *pPrev;
1484 tANI_U32 len;
1485
Rajeev79dbe4c2013-10-05 11:03:42 +05301486 pAdapter->isTruncated = FALSE;
1487
1488 /*head of hdd batch scan response queue*/
1489 pHead = pAdapter->pBatchScanRsp;
1490 while (pHead)
1491 {
1492 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
1493 pAdapter);
1494 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07001495 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05301496 cur_len += len;
1497 if(TRUE == pAdapter->isTruncated)
1498 {
1499 /*result is truncated return rest of scan rsp in next req*/
1500 cur_len = rem_len;
1501 break;
1502 }
1503 pPrev = pHead;
1504 pHead = pHead->pNext;
1505 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08001506 if (TRUE == pPrev->ApInfo.isLastAp)
1507 {
1508 pAdapter->prev_batch_id = 0;
1509 }
1510 else
1511 {
1512 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
1513 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301514 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08001515 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05301516 }
1517
1518 return cur_len;
1519}/*End of hdd_populate_user_batch_scan_rsp*/
1520
1521/**---------------------------------------------------------------------------
1522
1523 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
1524 scan response data from HDD queue to user space
1525 It does following in detail:
1526 a) if HDD has enough data in its queue then it 1st copies data to user
1527 space and then send get batch scan indication message to FW. In this
1528 case it does not wait on any event and batch scan response data will
1529 be populated in HDD response queue in MC thread context after receiving
1530 indication from FW
1531 b) else send get batch scan indication message to FW and wait on an event
1532 which will be set once HDD receives complete batch scan response from
1533 FW and then this function returns batch scan response to user space
1534
1535 \param - pAdapter Pointer to HDD adapter
1536 \param - pPrivData Pointer to priv_data
1537
1538 \return - 0 for success -EFAULT for failure
1539
1540 --------------------------------------------------------------------------*/
1541
1542int hdd_return_batch_scan_rsp_to_user
1543(
1544 hdd_adapter_t* pAdapter,
1545 hdd_priv_data_t *pPrivData,
1546 tANI_U8 *command
1547)
1548{
1549 tANI_U8 *pDest;
1550 tANI_U32 count = 0;
1551 tANI_U32 len = 0;
1552 tANI_U32 cur_len = 0;
1553 tANI_U32 rem_len = 0;
1554 eHalStatus halStatus;
1555 unsigned long rc;
1556 tSirTriggerBatchScanResultInd *pReq;
1557
1558 pReq = &pAdapter->hddTriggerBatchScanResultInd;
1559 pReq->param = 0;/*batch scan client*/
1560 pDest = (tANI_U8 *)(command + pPrivData->used_len);
1561 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1562
1563 cur_len = pPrivData->used_len;
1564 if (pPrivData->total_len > pPrivData->used_len)
1565 {
1566 rem_len = pPrivData->total_len - pPrivData->used_len;
1567 }
1568 else
1569 {
1570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1571 "%s: Invalid user data buffer total_len %d used_len %d",
1572 __func__, pPrivData->total_len, pPrivData->used_len);
1573 return -EFAULT;
1574 }
1575
1576 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1577 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1578 cur_len, rem_len);
1579 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1580
1581 /*enough scan result available in cache to return to user space or
1582 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08001583 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05301584 {
1585 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
1586 halStatus = sme_TriggerBatchScanResultInd(
1587 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1588 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
1589 pAdapter);
1590 if ( eHAL_STATUS_SUCCESS == halStatus )
1591 {
1592 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
1593 {
1594 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
1595 rc = wait_for_completion_timeout(
1596 &pAdapter->hdd_get_batch_scan_req_var,
1597 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
1598 if (0 == rc)
1599 {
1600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1601 "%s: Timeout waiting to fetch batch scan rsp from fw",
1602 __func__);
1603 return -EFAULT;
1604 }
1605 }
1606
1607 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07001608 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301609 pDest += len;
1610 cur_len += len;
1611
1612 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1613 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
1614 cur_len, rem_len);
1615 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1616
1617 count = 0;
1618 len = (len - pPrivData->used_len);
1619 pDest = (command + pPrivData->used_len);
1620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001621 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301622 while(count < len)
1623 {
1624 printk("%c", *(pDest + count));
1625 count++;
1626 }
1627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1628 "%s: copy %d data to user buffer", __func__, len);
1629 if (copy_to_user(pPrivData->buf, pDest, len))
1630 {
1631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1632 "%s: failed to copy data to user buffer", __func__);
1633 return -EFAULT;
1634 }
1635 }
1636 else
1637 {
1638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1639 "sme_GetBatchScanScan returned failure halStatus %d",
1640 halStatus);
1641 return -EINVAL;
1642 }
1643 }
1644 else
1645 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301646 count = 0;
1647 len = (len - pPrivData->used_len);
1648 pDest = (command + pPrivData->used_len);
1649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08001650 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05301651 while(count < len)
1652 {
1653 printk("%c", *(pDest + count));
1654 count++;
1655 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08001656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1657 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05301658 if (copy_to_user(pPrivData->buf, pDest, len))
1659 {
1660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1661 "%s: failed to copy data to user buffer", __func__);
1662 return -EFAULT;
1663 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301664 }
1665
1666 return 0;
1667} /*End of hdd_return_batch_scan_rsp_to_user*/
1668
Rajeev Kumar8b373292014-01-08 20:36:55 -08001669
1670/**---------------------------------------------------------------------------
1671
1672 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
1673 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
1674 WLS_BATCHING VERSION
1675 WLS_BATCHING SET
1676 WLS_BATCHING GET
1677 WLS_BATCHING STOP
1678
1679 \param - pAdapter Pointer to HDD adapter
1680 \param - pPrivdata Pointer to priv_data
1681 \param - command Pointer to command
1682
1683 \return - 0 for success -EFAULT for failure
1684
1685 --------------------------------------------------------------------------*/
1686
1687int hdd_handle_batch_scan_ioctl
1688(
1689 hdd_adapter_t *pAdapter,
1690 hdd_priv_data_t *pPrivdata,
1691 tANI_U8 *command
1692)
1693{
1694 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08001695 hdd_context_t *pHddCtx;
1696
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301697 ENTER();
1698
Yue Mae36e3552014-03-05 17:06:20 -08001699 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1700 ret = wlan_hdd_validate_context(pHddCtx);
1701 if (ret)
1702 {
Yue Mae36e3552014-03-05 17:06:20 -08001703 goto exit;
1704 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001705
1706 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
1707 {
1708 char extra[32];
1709 tANI_U8 len = 0;
1710 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
1711
1712 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1713 {
1714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1715 "%s: Batch scan feature is not supported by FW", __func__);
1716 ret = -EINVAL;
1717 goto exit;
1718 }
1719
1720 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
1721 version);
1722 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1723 {
1724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1725 "%s: failed to copy data to user buffer", __func__);
1726 ret = -EFAULT;
1727 goto exit;
1728 }
1729 ret = HDD_BATCH_SCAN_VERSION;
1730 }
1731 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
1732 {
1733 int status;
1734 tANI_U8 *value = (command + 16);
1735 eHalStatus halStatus;
1736 unsigned long rc;
1737 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
1738 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
1739
1740 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1741 {
1742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1743 "%s: Batch scan feature is not supported by FW", __func__);
1744 ret = -EINVAL;
1745 goto exit;
1746 }
1747
1748 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
1749 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
1750 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
1751 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
1752 {
1753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301754 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08001755 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301756 hdd_device_modetoString(pAdapter->device_mode),
1757 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001758 ret = -EINVAL;
1759 goto exit;
1760 }
1761
1762 status = hdd_parse_set_batchscan_command(value, pReq);
1763 if (status)
1764 {
1765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1766 "Invalid WLS_BATCHING SET command");
1767 ret = -EINVAL;
1768 goto exit;
1769 }
1770
1771
1772 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
1773 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
1774 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
1775 pAdapter);
1776
1777 if ( eHAL_STATUS_SUCCESS == halStatus )
1778 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301779 char extra[32];
1780 tANI_U8 len = 0;
1781 tANI_U8 mScan = 0;
1782
Rajeev Kumar8b373292014-01-08 20:36:55 -08001783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1784 "sme_SetBatchScanReq returned success halStatus %d",
1785 halStatus);
1786 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
1787 {
1788 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
1789 rc = wait_for_completion_timeout(
1790 &pAdapter->hdd_set_batch_scan_req_var,
1791 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
1792 if (0 == rc)
1793 {
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1795 "%s: Timeout waiting for set batch scan to complete",
1796 __func__);
1797 ret = -EINVAL;
1798 goto exit;
1799 }
1800 }
1801 if ( !pRsp->nScansToBatch )
1802 {
1803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1804 "%s: Received set batch scan failure response from FW",
1805 __func__);
1806 ret = -EINVAL;
1807 goto exit;
1808 }
1809 /*As per the Batch Scan Framework API we should return the MIN of
1810 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301811 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08001812
1813 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
1814
1815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1816 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05301817 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
1818 len = scnprintf(extra, sizeof(extra), "%d", mScan);
1819 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
1820 {
1821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1822 "%s: failed to copy MSCAN value to user buffer", __func__);
1823 ret = -EFAULT;
1824 goto exit;
1825 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08001826 }
1827 else
1828 {
1829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1830 "sme_SetBatchScanReq returned failure halStatus %d",
1831 halStatus);
1832 ret = -EINVAL;
1833 goto exit;
1834 }
1835 }
1836 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
1837 {
1838 eHalStatus halStatus;
1839 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
1840 pInd->param = 0;
1841
1842 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1843 {
1844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1845 "%s: Batch scan feature is not supported by FW", __func__);
1846 ret = -EINVAL;
1847 goto exit;
1848 }
1849
1850 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1851 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001853 "Batch scan is not yet enabled batch scan state %d",
1854 pAdapter->batchScanState);
1855 ret = -EINVAL;
1856 goto exit;
1857 }
1858
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001859 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1860 hdd_deinit_batch_scan(pAdapter);
1861 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1862
Rajeev Kumar8b373292014-01-08 20:36:55 -08001863 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
1864
1865 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
1866 pAdapter->sessionId);
1867 if ( eHAL_STATUS_SUCCESS == halStatus )
1868 {
1869 ret = 0;
1870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1871 "sme_StopBatchScanInd returned success halStatus %d",
1872 halStatus);
1873 }
1874 else
1875 {
1876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1877 "sme_StopBatchScanInd returned failure halStatus %d",
1878 halStatus);
1879 ret = -EINVAL;
1880 goto exit;
1881 }
1882 }
1883 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
1884 {
1885 tANI_U32 remain_len;
1886
1887 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
1888 {
1889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1890 "%s: Batch scan feature is not supported by FW", __func__);
1891 ret = -EINVAL;
1892 goto exit;
1893 }
1894
1895 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
1896 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05301897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08001898 "Batch scan is not yet enabled could not return results"
1899 "Batch Scan state %d",
1900 pAdapter->batchScanState);
1901 ret = -EINVAL;
1902 goto exit;
1903 }
1904
1905 pPrivdata->used_len = 16;
1906 remain_len = pPrivdata->total_len - pPrivdata->used_len;
1907 if (remain_len < pPrivdata->total_len)
1908 {
1909 /*Clear previous batch scan response data if any*/
1910 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
1911 }
1912 else
1913 {
1914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1915 "Invalid total length from user space can't fetch batch"
1916 " scan response total_len %d used_len %d remain len %d",
1917 pPrivdata->total_len, pPrivdata->used_len, remain_len);
1918 ret = -EINVAL;
1919 goto exit;
1920 }
1921 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
1922 }
1923
1924exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301925 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08001926 return ret;
1927}
1928
1929
Rajeev79dbe4c2013-10-05 11:03:42 +05301930#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
1931
c_hpothu92367912014-05-01 15:18:17 +05301932static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
1933{
c_hpothu39eb1e32014-06-26 16:31:50 +05301934 bcnMissRateContext_t *pCBCtx;
1935
1936 if (NULL == data)
1937 {
1938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1939 return;
1940 }
c_hpothu92367912014-05-01 15:18:17 +05301941
1942 /* there is a race condition that exists between this callback
1943 function and the caller since the caller could time out either
1944 before or while this code is executing. we use a spinlock to
1945 serialize these actions */
1946 spin_lock(&hdd_context_lock);
1947
c_hpothu39eb1e32014-06-26 16:31:50 +05301948 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05301949 gbcnMissRate = -1;
1950
c_hpothu39eb1e32014-06-26 16:31:50 +05301951 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05301952 {
1953 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05301954 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05301955 spin_unlock(&hdd_context_lock);
1956 return ;
1957 }
1958
1959 if (VOS_STATUS_SUCCESS == status)
1960 {
c_hpothu39eb1e32014-06-26 16:31:50 +05301961 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05301962 }
c_hpothu39eb1e32014-06-26 16:31:50 +05301963 else
1964 {
1965 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
1966 }
1967
c_hpothu92367912014-05-01 15:18:17 +05301968 complete(&(pCBCtx->completion));
1969 spin_unlock(&hdd_context_lock);
1970
1971 return;
1972}
1973
Abhishek Singh08aa7762014-12-16 13:59:03 +05301974void hdd_FWStatisCB( VOS_STATUS status,
1975 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05301976{
1977 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301978 hdd_adapter_t *pAdapter;
1979
1980 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
1981
Abhishek Singh08aa7762014-12-16 13:59:03 +05301982 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05301983 {
1984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
1985 return;
1986 }
1987 /* there is a race condition that exists between this callback
1988 function and the caller since the caller could time out either
1989 before or while this code is executing. we use a spinlock to
1990 serialize these actions */
1991 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05301992 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05301993 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR,
1996 FL("invalid context magic: %08x"), fwStatsCtx->magic);
1997 spin_unlock(&hdd_context_lock);
1998 return;
1999 }
2000 pAdapter = fwStatsCtx->pAdapter;
2001 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2002 {
2003 hddLog(VOS_TRACE_LEVEL_ERROR,
2004 FL("pAdapter returned is NULL or invalid"));
2005 spin_unlock(&hdd_context_lock);
2006 return;
2007 }
2008 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302009 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302010 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302011 switch( fwStatsResult->type )
2012 {
2013 case FW_UBSP_STATS:
2014 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302015 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302016 hddLog(VOS_TRACE_LEVEL_INFO,
2017 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302018 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2019 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302020 }
2021 break;
2022 default:
2023 {
2024 hddLog(VOS_TRACE_LEVEL_ERROR,
2025 FL(" No handling for stats type %d"),fwStatsResult->type);
2026 }
2027 }
2028 }
2029 complete(&(fwStatsCtx->completion));
2030 spin_unlock(&hdd_context_lock);
2031 return;
2032}
2033
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302034static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2035{
2036 int ret = 0;
2037
2038 if (!pCfg || !command || !extra || !len)
2039 {
2040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2041 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2042 ret = -EINVAL;
2043 return ret;
2044 }
2045
2046 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2047 {
2048 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2049 (int)pCfg->nActiveMaxChnTime);
2050 return ret;
2051 }
2052 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2053 {
2054 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2055 (int)pCfg->nActiveMinChnTime);
2056 return ret;
2057 }
2058 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2059 {
2060 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2061 (int)pCfg->nPassiveMaxChnTime);
2062 return ret;
2063 }
2064 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2065 {
2066 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2067 (int)pCfg->nPassiveMinChnTime);
2068 return ret;
2069 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302070 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2071 {
2072 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2073 (int)pCfg->nActiveMaxChnTime);
2074 return ret;
2075 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302076 else
2077 {
2078 ret = -EINVAL;
2079 }
2080
2081 return ret;
2082}
2083
2084static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2085{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302086 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302087 hdd_config_t *pCfg;
2088 tANI_U8 *value = command;
2089 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302090 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302091
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302092 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2093 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302094 {
2095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2096 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2097 ret = -EINVAL;
2098 return ret;
2099 }
2100
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302101 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2102 sme_GetConfigParam(hHal, &smeConfig);
2103
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302104 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2105 {
2106 value = value + 24;
2107 temp = kstrtou32(value, 10, &val);
2108 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2109 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2110 {
2111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2112 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2113 ret = -EFAULT;
2114 return ret;
2115 }
2116 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302117 smeConfig.csrConfig.nActiveMaxChnTime = val;
2118 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302119 }
2120 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2121 {
2122 value = value + 24;
2123 temp = kstrtou32(value, 10, &val);
2124 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2125 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2126 {
2127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2128 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2129 ret = -EFAULT;
2130 return ret;
2131 }
2132 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302133 smeConfig.csrConfig.nActiveMinChnTime = val;
2134 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302135 }
2136 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2137 {
2138 value = value + 25;
2139 temp = kstrtou32(value, 10, &val);
2140 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2141 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2142 {
2143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2144 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2145 ret = -EFAULT;
2146 return ret;
2147 }
2148 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302149 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2150 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302151 }
2152 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2153 {
2154 value = value + 25;
2155 temp = kstrtou32(value, 10, &val);
2156 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2157 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2158 {
2159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2160 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2161 ret = -EFAULT;
2162 return ret;
2163 }
2164 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302165 smeConfig.csrConfig.nPassiveMinChnTime = val;
2166 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302167 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302168 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2169 {
2170 value = value + 13;
2171 temp = kstrtou32(value, 10, &val);
2172 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2173 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2174 {
2175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2176 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2177 ret = -EFAULT;
2178 return ret;
2179 }
2180 pCfg->nActiveMaxChnTime = val;
2181 smeConfig.csrConfig.nActiveMaxChnTime = val;
2182 sme_UpdateConfig(hHal, &smeConfig);
2183 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302184 else
2185 {
2186 ret = -EINVAL;
2187 }
2188
2189 return ret;
2190}
2191
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002192static int hdd_driver_command(hdd_adapter_t *pAdapter,
2193 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07002194{
Jeff Johnson295189b2012-06-20 16:38:30 -07002195 hdd_priv_data_t priv_data;
2196 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302197 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2198 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002199 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302200 int status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302201
2202 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002203 /*
2204 * Note that valid pointers are provided by caller
2205 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002206
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002207 /* copy to local struct to avoid numerous changes to legacy code */
2208 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07002209
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002210 if (priv_data.total_len <= 0 ||
2211 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07002212 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002213 hddLog(VOS_TRACE_LEVEL_WARN,
2214 "%s:invalid priv_data.total_len(%d)!!!", __func__,
2215 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002216 ret = -EINVAL;
2217 goto exit;
2218 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05302219 status = wlan_hdd_validate_context(pHddCtx);
2220 if (0 != status)
2221 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302222 ret = -EINVAL;
2223 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05302224 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002225 /* Allocate +1 for '\0' */
2226 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07002227 if (!command)
2228 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002229 hddLog(VOS_TRACE_LEVEL_ERROR,
2230 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 ret = -ENOMEM;
2232 goto exit;
2233 }
2234
2235 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
2236 {
2237 ret = -EFAULT;
2238 goto exit;
2239 }
2240
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002241 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07002242 command[priv_data.total_len] = '\0';
2243
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002244 /* at one time the following block of code was conditional. braces
2245 * have been retained to avoid re-indenting the legacy code
2246 */
Jeff Johnson295189b2012-06-20 16:38:30 -07002247 {
2248 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2249
2250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07002251 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07002252
2253 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
2254 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302255 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2256 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
2257 pAdapter->sessionId, (unsigned)
2258 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
2259 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
2260 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
2261 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07002262 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
2263 sizeof(tSirMacAddr)))
2264 {
2265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002266 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002267 ret = -EFAULT;
2268 }
2269 }
Amar Singhal0974e402013-02-12 14:27:46 -08002270 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07002271 {
Amar Singhal0974e402013-02-12 14:27:46 -08002272 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002273
Jeff Johnson295189b2012-06-20 16:38:30 -07002274 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002275
2276 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07002277 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08002279 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07002280 /* Change band request received */
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002281 ret = hdd_setBand_helper(pAdapter->dev, ptr);
Abhishek Singh2ec36ab2014-08-07 16:14:25 +05302282 if(ret < 0)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302283 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002284 "%s: failed to set band ret=%d", __func__, ret);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002285 }
Kiet Lamf040f472013-11-20 21:15:23 +05302286 else if(strncmp(command, "SETWMMPS", 8) == 0)
2287 {
2288 tANI_U8 *ptr = command;
2289 ret = hdd_wmmps_helper(pAdapter, ptr);
2290 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302291
2292 else if(strncmp(command, "TDLSSCAN", 8) == 0)
2293 {
2294 tANI_U8 *ptr = command;
2295 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
2296 }
2297
Jeff Johnson32d95a32012-09-10 13:15:23 -07002298 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
2299 {
2300 char *country_code;
2301
2302 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002303
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002304 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07002305 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002306#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05302307 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07002308#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002309 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2310 (void *)(tSmeChangeCountryCallback)
2311 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05302312 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002313 if (eHAL_STATUS_SUCCESS == ret)
2314 {
2315 ret = wait_for_completion_interruptible_timeout(
2316 &pAdapter->change_country_code,
2317 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
2318 if (0 >= ret)
2319 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302321 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002322 }
2323 }
2324 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07002325 {
2326 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07002327 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002328 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002329 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07002330
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002331 }
2332 /*
2333 command should be a string having format
2334 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
2335 */
Amar Singhal0974e402013-02-12 14:27:46 -08002336 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002337 {
Amar Singhal0974e402013-02-12 14:27:46 -08002338 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002339
2340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002341 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07002342
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08002343 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07002344 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002345 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
2346 {
2347 int suspend = 0;
2348 tANI_U8 *ptr = (tANI_U8*)command + 15;
2349
2350 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302351 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2352 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
2353 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08002354 hdd_set_wlan_suspend_mode(suspend);
2355 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002356#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
2357 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
2358 {
2359 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002360 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002361 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
2362 eHalStatus status = eHAL_STATUS_SUCCESS;
2363
2364 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
2365 value = value + 15;
2366
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002367 /* Convert the value from ascii to integer */
2368 ret = kstrtos8(value, 10, &rssi);
2369 if (ret < 0)
2370 {
2371 /* If the input value is greater than max value of datatype, then also
2372 kstrtou8 fails */
2373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2374 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07002375 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002376 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2377 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2378 ret = -EINVAL;
2379 goto exit;
2380 }
2381
Srinivas Girigowdade697412013-02-14 16:31:48 -08002382 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002383
Srinivas Girigowdade697412013-02-14 16:31:48 -08002384 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
2385 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
2386 {
2387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2388 "Neighbor lookup threshold value %d is out of range"
2389 " (Min: %d Max: %d)", lookUpThreshold,
2390 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
2391 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
2392 ret = -EINVAL;
2393 goto exit;
2394 }
2395
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302396 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2397 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
2398 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2400 "%s: Received Command to Set Roam trigger"
2401 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
2402
2403 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
2404 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
2405 if (eHAL_STATUS_SUCCESS != status)
2406 {
2407 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2408 "%s: Failed to set roam trigger, try again", __func__);
2409 ret = -EPERM;
2410 goto exit;
2411 }
2412
2413 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05302414 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002415 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
2416 }
2417 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
2418 {
2419 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
2420 int rssi = (-1) * lookUpThreshold;
2421 char extra[32];
2422 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302423 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2424 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
2425 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002426 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002427 if (copy_to_user(priv_data.buf, &extra, len + 1))
2428 {
2429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2430 "%s: failed to copy data to user buffer", __func__);
2431 ret = -EFAULT;
2432 goto exit;
2433 }
2434 }
2435 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
2436 {
2437 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002438 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002439 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002440
Srinivas Girigowdade697412013-02-14 16:31:48 -08002441 /* input refresh period is in terms of seconds */
2442 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
2443 value = value + 18;
2444 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002445 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002446 if (ret < 0)
2447 {
2448 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002449 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08002450 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002451 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08002452 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002453 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2454 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002455 ret = -EINVAL;
2456 goto exit;
2457 }
2458
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002459 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
2460 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08002461 {
2462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002463 "Roam scan period value %d is out of range"
2464 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07002465 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
2466 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002467 ret = -EINVAL;
2468 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302469 }
2470 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2471 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
2472 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002473 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002474
2475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2476 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002477 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002478
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002479 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
2480 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002481 }
2482 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
2483 {
2484 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2485 char extra[32];
2486 tANI_U8 len = 0;
2487
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302488 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2489 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
2490 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002491 len = scnprintf(extra, sizeof(extra), "%s %d",
2492 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002493 /* Returned value is in units of seconds */
2494 if (copy_to_user(priv_data.buf, &extra, len + 1))
2495 {
2496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2497 "%s: failed to copy data to user buffer", __func__);
2498 ret = -EFAULT;
2499 goto exit;
2500 }
2501 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002502 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
2503 {
2504 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002505 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002506 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002507
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002508 /* input refresh period is in terms of seconds */
2509 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
2510 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002511
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002512 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002513 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002514 if (ret < 0)
2515 {
2516 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002517 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002519 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002520 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002521 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2522 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2523 ret = -EINVAL;
2524 goto exit;
2525 }
2526
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002527 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
2528 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
2529 {
2530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2531 "Neighbor scan results refresh period value %d is out of range"
2532 " (Min: %d Max: %d)", roamScanRefreshPeriod,
2533 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
2534 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
2535 ret = -EINVAL;
2536 goto exit;
2537 }
2538 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
2539
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2541 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002542 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002543
2544 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
2545 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
2546 }
2547 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
2548 {
2549 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
2550 char extra[32];
2551 tANI_U8 len = 0;
2552
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002553 len = scnprintf(extra, sizeof(extra), "%s %d",
2554 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002555 /* Returned value is in units of seconds */
2556 if (copy_to_user(priv_data.buf, &extra, len + 1))
2557 {
2558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2559 "%s: failed to copy data to user buffer", __func__);
2560 ret = -EFAULT;
2561 goto exit;
2562 }
2563 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002564#ifdef FEATURE_WLAN_LFR
2565 /* SETROAMMODE */
2566 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
2567 {
2568 tANI_U8 *value = command;
2569 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
2570
2571 /* Move pointer to ahead of SETROAMMODE<delimiter> */
2572 value = value + SIZE_OF_SETROAMMODE + 1;
2573
2574 /* Convert the value from ascii to integer */
2575 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
2576 if (ret < 0)
2577 {
2578 /* If the input value is greater than max value of datatype, then also
2579 kstrtou8 fails */
2580 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2581 "%s: kstrtou8 failed range [%d - %d]", __func__,
2582 CFG_LFR_FEATURE_ENABLED_MIN,
2583 CFG_LFR_FEATURE_ENABLED_MAX);
2584 ret = -EINVAL;
2585 goto exit;
2586 }
2587 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
2588 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
2589 {
2590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2591 "Roam Mode value %d is out of range"
2592 " (Min: %d Max: %d)", roamMode,
2593 CFG_LFR_FEATURE_ENABLED_MIN,
2594 CFG_LFR_FEATURE_ENABLED_MAX);
2595 ret = -EINVAL;
2596 goto exit;
2597 }
2598
2599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2600 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
2601 /*
2602 * Note that
2603 * SETROAMMODE 0 is to enable LFR while
2604 * SETROAMMODE 1 is to disable LFR, but
2605 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
2606 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
2607 */
2608 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2609 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
2610 else
2611 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
2612
2613 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
2614 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
2615 }
2616 /* GETROAMMODE */
2617 else if (strncmp(priv_data.buf, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
2618 {
2619 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2620 char extra[32];
2621 tANI_U8 len = 0;
2622
2623 /*
2624 * roamMode value shall be inverted because the sementics is different.
2625 */
2626 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
2627 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
2628 else
2629 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
2630
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002631 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07002632 if (copy_to_user(priv_data.buf, &extra, len + 1))
2633 {
2634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2635 "%s: failed to copy data to user buffer", __func__);
2636 ret = -EFAULT;
2637 goto exit;
2638 }
2639 }
2640#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08002641#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002642#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002643 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
2644 {
2645 tANI_U8 *value = command;
2646 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
2647
2648 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
2649 value = value + 13;
2650 /* Convert the value from ascii to integer */
2651 ret = kstrtou8(value, 10, &roamRssiDiff);
2652 if (ret < 0)
2653 {
2654 /* If the input value is greater than max value of datatype, then also
2655 kstrtou8 fails */
2656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2657 "%s: kstrtou8 failed range [%d - %d]", __func__,
2658 CFG_ROAM_RSSI_DIFF_MIN,
2659 CFG_ROAM_RSSI_DIFF_MAX);
2660 ret = -EINVAL;
2661 goto exit;
2662 }
2663
2664 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
2665 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
2666 {
2667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2668 "Roam rssi diff value %d is out of range"
2669 " (Min: %d Max: %d)", roamRssiDiff,
2670 CFG_ROAM_RSSI_DIFF_MIN,
2671 CFG_ROAM_RSSI_DIFF_MAX);
2672 ret = -EINVAL;
2673 goto exit;
2674 }
2675
2676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2677 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
2678
2679 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
2680 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
2681 }
2682 else if (strncmp(priv_data.buf, "GETROAMDELTA", 12) == 0)
2683 {
2684 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
2685 char extra[32];
2686 tANI_U8 len = 0;
2687
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302688 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2689 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
2690 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002691 len = scnprintf(extra, sizeof(extra), "%s %d",
2692 command, roamRssiDiff);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002693 if (copy_to_user(priv_data.buf, &extra, len + 1))
2694 {
2695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2696 "%s: failed to copy data to user buffer", __func__);
2697 ret = -EFAULT;
2698 goto exit;
2699 }
2700 }
2701#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002702#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08002703 else if (strncmp(command, "GETBAND", 7) == 0)
2704 {
2705 int band = -1;
2706 char extra[32];
2707 tANI_U8 len = 0;
2708 hdd_getBand_helper(pHddCtx, &band);
2709
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302710 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2711 TRACE_CODE_HDD_GETBAND_IOCTL,
2712 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002713 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002714 if (copy_to_user(priv_data.buf, &extra, len + 1))
2715 {
2716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2717 "%s: failed to copy data to user buffer", __func__);
2718 ret = -EFAULT;
2719 goto exit;
2720 }
2721 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08002722 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
2723 {
2724 tANI_U8 *value = command;
2725 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2726 tANI_U8 numChannels = 0;
2727 eHalStatus status = eHAL_STATUS_SUCCESS;
2728
2729 status = hdd_parse_channellist(value, ChannelList, &numChannels);
2730 if (eHAL_STATUS_SUCCESS != status)
2731 {
2732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2733 "%s: Failed to parse channel list information", __func__);
2734 ret = -EINVAL;
2735 goto exit;
2736 }
2737
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302738 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2739 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
2740 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002741 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
2742 {
2743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2744 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
2745 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
2746 ret = -EINVAL;
2747 goto exit;
2748 }
2749 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
2750 numChannels);
2751 if (eHAL_STATUS_SUCCESS != status)
2752 {
2753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 "%s: Failed to update channel list information", __func__);
2755 ret = -EINVAL;
2756 goto exit;
2757 }
2758 }
2759 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
2760 {
2761 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
2762 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07002763 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002764 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07002765 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08002766
2767 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
2768 ChannelList, &numChannels ))
2769 {
2770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2771 "%s: failed to get roam scan channel list", __func__);
2772 ret = -EFAULT;
2773 goto exit;
2774 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302775 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2776 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
2777 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08002778 /* output channel list is of the format
2779 [Number of roam scan channels][Channel1][Channel2]... */
2780 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002781 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002782 for (j = 0; (j < numChannels); j++)
2783 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002784 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
2785 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08002786 }
2787
2788 if (copy_to_user(priv_data.buf, &extra, len + 1))
2789 {
2790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s: failed to copy data to user buffer", __func__);
2792 ret = -EFAULT;
2793 goto exit;
2794 }
2795 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002796 else if (strncmp(command, "GETCCXMODE", 10) == 0)
2797 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002798 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002799 char extra[32];
2800 tANI_U8 len = 0;
2801
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002802 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002803 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002804 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002805 hdd_is_okc_mode_enabled(pHddCtx) &&
2806 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2807 {
2808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002809 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002810 " hence this operation is not permitted!", __func__);
2811 ret = -EPERM;
2812 goto exit;
2813 }
2814
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002815 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002816 "GETCCXMODE", eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002817 if (copy_to_user(priv_data.buf, &extra, len + 1))
2818 {
2819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2820 "%s: failed to copy data to user buffer", __func__);
2821 ret = -EFAULT;
2822 goto exit;
2823 }
2824 }
2825 else if (strncmp(command, "GETOKCMODE", 10) == 0)
2826 {
2827 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
2828 char extra[32];
2829 tANI_U8 len = 0;
2830
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002831 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002832 then this operation is not permitted (return FAILURE) */
2833 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002834 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002835 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
2836 {
2837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08002838 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07002839 " hence this operation is not permitted!", __func__);
2840 ret = -EPERM;
2841 goto exit;
2842 }
2843
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002844 len = scnprintf(extra, sizeof(extra), "%s %d",
2845 "GETOKCMODE", okcMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002846 if (copy_to_user(priv_data.buf, &extra, len + 1))
2847 {
2848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2849 "%s: failed to copy data to user buffer", __func__);
2850 ret = -EFAULT;
2851 goto exit;
2852 }
2853 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07002854 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002855 {
2856 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2857 char extra[32];
2858 tANI_U8 len = 0;
2859
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002860 len = scnprintf(extra, sizeof(extra), "%s %d",
2861 "GETFASTROAM", lfrMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002862 if (copy_to_user(priv_data.buf, &extra, len + 1))
2863 {
2864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2865 "%s: failed to copy data to user buffer", __func__);
2866 ret = -EFAULT;
2867 goto exit;
2868 }
2869 }
2870 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
2871 {
2872 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
2873 char extra[32];
2874 tANI_U8 len = 0;
2875
Sameer Thalappilb0a30232013-09-27 15:37:48 -07002876 len = scnprintf(extra, sizeof(extra), "%s %d",
2877 "GETFASTTRANSITION", ft);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002878 if (copy_to_user(priv_data.buf, &extra, len + 1))
2879 {
2880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2881 "%s: failed to copy data to user buffer", __func__);
2882 ret = -EFAULT;
2883 goto exit;
2884 }
2885 }
2886 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
2887 {
2888 tANI_U8 *value = command;
2889 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
2890
2891 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
2892 value = value + 26;
2893 /* Convert the value from ascii to integer */
2894 ret = kstrtou8(value, 10, &minTime);
2895 if (ret < 0)
2896 {
2897 /* If the input value is greater than max value of datatype, then also
2898 kstrtou8 fails */
2899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2900 "%s: kstrtou8 failed range [%d - %d]", __func__,
2901 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2902 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2903 ret = -EINVAL;
2904 goto exit;
2905 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002906 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
2907 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
2908 {
2909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2910 "scan min channel time value %d is out of range"
2911 " (Min: %d Max: %d)", minTime,
2912 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
2913 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
2914 ret = -EINVAL;
2915 goto exit;
2916 }
2917
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302918 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2919 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
2920 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07002921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2922 "%s: Received Command to change channel min time = %d", __func__, minTime);
2923
2924 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
2925 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
2926 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002927 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
2928 {
2929 tANI_U8 *value = command;
2930 tANI_U8 channel = 0;
2931 tANI_U8 dwellTime = 0;
2932 tANI_U8 bufLen = 0;
2933 tANI_U8 *buf = NULL;
2934 tSirMacAddr targetApBssid;
2935 eHalStatus status = eHAL_STATUS_SUCCESS;
2936 struct ieee80211_channel chan;
2937 tANI_U8 finalLen = 0;
2938 tANI_U8 *finalBuf = NULL;
2939 tANI_U8 temp = 0;
2940 u64 cookie;
2941 hdd_station_ctx_t *pHddStaCtx = NULL;
2942 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2943
2944 /* if not associated, no need to send action frame */
2945 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2946 {
2947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
2948 ret = -EINVAL;
2949 goto exit;
2950 }
2951
2952 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
2953 &dwellTime, &buf, &bufLen);
2954 if (eHAL_STATUS_SUCCESS != status)
2955 {
2956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2957 "%s: Failed to parse send action frame data", __func__);
2958 ret = -EINVAL;
2959 goto exit;
2960 }
2961
2962 /* if the target bssid is different from currently associated AP,
2963 then no need to send action frame */
2964 if (VOS_TRUE != vos_mem_compare(targetApBssid,
2965 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
2966 {
2967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
2968 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002969 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002970 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002971 goto exit;
2972 }
2973
2974 /* if the channel number is different from operating channel then
2975 no need to send action frame */
2976 if (channel != pHddStaCtx->conn_info.operationChannel)
2977 {
2978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2979 "%s: channel(%d) is different from operating channel(%d)",
2980 __func__, channel, pHddStaCtx->conn_info.operationChannel);
2981 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07002982 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002983 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002984 goto exit;
2985 }
2986 chan.center_freq = sme_ChnToFreq(channel);
2987
2988 finalLen = bufLen + 24;
2989 finalBuf = vos_mem_malloc(finalLen);
2990 if (NULL == finalBuf)
2991 {
2992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
2993 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07002994 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002995 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07002996 goto exit;
2997 }
2998 vos_mem_zero(finalBuf, finalLen);
2999
3000 /* Fill subtype */
3001 temp = SIR_MAC_MGMT_ACTION << 4;
3002 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3003
3004 /* Fill type */
3005 temp = SIR_MAC_MGMT_FRAME;
3006 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3007
3008 /* Fill destination address (bssid of the AP) */
3009 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3010
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003011 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003012 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3013
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003014 /* Fill BSSID (AP mac address) */
3015 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003016
3017 /* Fill received buffer from 24th address */
3018 vos_mem_copy(finalBuf + 24, buf, bufLen);
3019
Jeff Johnson11c33152013-04-16 17:52:40 -07003020 /* done with the parsed buffer */
3021 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003022 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003023
DARAM SUDHA39eede62014-02-12 11:16:40 +05303024 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3026 &(pAdapter->wdev),
3027#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003028 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003029#endif
3030 &chan, 0,
3031#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3032 NL80211_CHAN_HT20, 1,
3033#endif
3034 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003035 1, &cookie );
3036 vos_mem_free(finalBuf);
3037 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003038 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3039 {
3040 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3041 char extra[32];
3042 tANI_U8 len = 0;
3043
3044 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003045 len = scnprintf(extra, sizeof(extra), "%s %d",
3046 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303047 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3048 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3049 pAdapter->sessionId, val));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003050 if (copy_to_user(priv_data.buf, &extra, len + 1))
3051 {
3052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3053 "%s: failed to copy data to user buffer", __func__);
3054 ret = -EFAULT;
3055 goto exit;
3056 }
3057 }
3058 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
3059 {
3060 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003061 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003062
3063 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
3064 value = value + 19;
3065 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003066 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003067 if (ret < 0)
3068 {
3069 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003070 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07003072 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003073 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3074 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3075 ret = -EINVAL;
3076 goto exit;
3077 }
3078
3079 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
3080 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
3081 {
3082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3083 "lfr mode value %d is out of range"
3084 " (Min: %d Max: %d)", maxTime,
3085 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
3086 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
3087 ret = -EINVAL;
3088 goto exit;
3089 }
3090
3091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3092 "%s: Received Command to change channel max time = %d", __func__, maxTime);
3093
3094 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
3095 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
3096 }
3097 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
3098 {
3099 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
3100 char extra[32];
3101 tANI_U8 len = 0;
3102
3103 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003104 len = scnprintf(extra, sizeof(extra), "%s %d",
3105 "GETSCANCHANNELTIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003106 if (copy_to_user(priv_data.buf, &extra, len + 1))
3107 {
3108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3109 "%s: failed to copy data to user buffer", __func__);
3110 ret = -EFAULT;
3111 goto exit;
3112 }
3113 }
3114 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
3115 {
3116 tANI_U8 *value = command;
3117 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
3118
3119 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
3120 value = value + 16;
3121 /* Convert the value from ascii to integer */
3122 ret = kstrtou16(value, 10, &val);
3123 if (ret < 0)
3124 {
3125 /* If the input value is greater than max value of datatype, then also
3126 kstrtou16 fails */
3127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3128 "%s: kstrtou16 failed range [%d - %d]", __func__,
3129 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3130 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3131 ret = -EINVAL;
3132 goto exit;
3133 }
3134
3135 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
3136 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
3137 {
3138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3139 "scan home time value %d is out of range"
3140 " (Min: %d Max: %d)", val,
3141 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
3142 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
3143 ret = -EINVAL;
3144 goto exit;
3145 }
3146
3147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3148 "%s: Received Command to change scan home time = %d", __func__, val);
3149
3150 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
3151 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
3152 }
3153 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
3154 {
3155 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
3156 char extra[32];
3157 tANI_U8 len = 0;
3158
3159 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003160 len = scnprintf(extra, sizeof(extra), "%s %d",
3161 "GETSCANHOMETIME", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003162 if (copy_to_user(priv_data.buf, &extra, len + 1))
3163 {
3164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3165 "%s: failed to copy data to user buffer", __func__);
3166 ret = -EFAULT;
3167 goto exit;
3168 }
3169 }
3170 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
3171 {
3172 tANI_U8 *value = command;
3173 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
3174
3175 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
3176 value = value + 17;
3177 /* Convert the value from ascii to integer */
3178 ret = kstrtou8(value, 10, &val);
3179 if (ret < 0)
3180 {
3181 /* If the input value is greater than max value of datatype, then also
3182 kstrtou8 fails */
3183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3184 "%s: kstrtou8 failed range [%d - %d]", __func__,
3185 CFG_ROAM_INTRA_BAND_MIN,
3186 CFG_ROAM_INTRA_BAND_MAX);
3187 ret = -EINVAL;
3188 goto exit;
3189 }
3190
3191 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
3192 (val > CFG_ROAM_INTRA_BAND_MAX))
3193 {
3194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3195 "intra band mode value %d is out of range"
3196 " (Min: %d Max: %d)", val,
3197 CFG_ROAM_INTRA_BAND_MIN,
3198 CFG_ROAM_INTRA_BAND_MAX);
3199 ret = -EINVAL;
3200 goto exit;
3201 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003202 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3203 "%s: Received Command to change intra band = %d", __func__, val);
3204
3205 pHddCtx->cfg_ini->nRoamIntraBand = val;
3206 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
3207 }
3208 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
3209 {
3210 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
3211 char extra[32];
3212 tANI_U8 len = 0;
3213
3214 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003215 len = scnprintf(extra, sizeof(extra), "%s %d",
3216 "GETROAMINTRABAND", val);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003217 if (copy_to_user(priv_data.buf, &extra, len + 1))
3218 {
3219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3220 "%s: failed to copy data to user buffer", __func__);
3221 ret = -EFAULT;
3222 goto exit;
3223 }
3224 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003225 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
3226 {
3227 tANI_U8 *value = command;
3228 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
3229
3230 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
3231 value = value + 15;
3232 /* Convert the value from ascii to integer */
3233 ret = kstrtou8(value, 10, &nProbes);
3234 if (ret < 0)
3235 {
3236 /* If the input value is greater than max value of datatype, then also
3237 kstrtou8 fails */
3238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3239 "%s: kstrtou8 failed range [%d - %d]", __func__,
3240 CFG_ROAM_SCAN_N_PROBES_MIN,
3241 CFG_ROAM_SCAN_N_PROBES_MAX);
3242 ret = -EINVAL;
3243 goto exit;
3244 }
3245
3246 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
3247 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
3248 {
3249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3250 "NProbes value %d is out of range"
3251 " (Min: %d Max: %d)", nProbes,
3252 CFG_ROAM_SCAN_N_PROBES_MIN,
3253 CFG_ROAM_SCAN_N_PROBES_MAX);
3254 ret = -EINVAL;
3255 goto exit;
3256 }
3257
3258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3259 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
3260
3261 pHddCtx->cfg_ini->nProbes = nProbes;
3262 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
3263 }
3264 else if (strncmp(priv_data.buf, "GETSCANNPROBES", 14) == 0)
3265 {
3266 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
3267 char extra[32];
3268 tANI_U8 len = 0;
3269
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003270 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003271 if (copy_to_user(priv_data.buf, &extra, len + 1))
3272 {
3273 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3274 "%s: failed to copy data to user buffer", __func__);
3275 ret = -EFAULT;
3276 goto exit;
3277 }
3278 }
3279 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
3280 {
3281 tANI_U8 *value = command;
3282 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
3283
3284 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
3285 /* input value is in units of msec */
3286 value = value + 20;
3287 /* Convert the value from ascii to integer */
3288 ret = kstrtou16(value, 10, &homeAwayTime);
3289 if (ret < 0)
3290 {
3291 /* If the input value is greater than max value of datatype, then also
3292 kstrtou8 fails */
3293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3294 "%s: kstrtou8 failed range [%d - %d]", __func__,
3295 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3296 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3297 ret = -EINVAL;
3298 goto exit;
3299 }
3300
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003301 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
3302 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
3303 {
3304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3305 "homeAwayTime value %d is out of range"
3306 " (Min: %d Max: %d)", homeAwayTime,
3307 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
3308 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
3309 ret = -EINVAL;
3310 goto exit;
3311 }
3312
3313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3314 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07003315 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
3316 {
3317 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
3318 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
3319 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003320 }
3321 else if (strncmp(priv_data.buf, "GETSCANHOMEAWAYTIME", 19) == 0)
3322 {
3323 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
3324 char extra[32];
3325 tANI_U8 len = 0;
3326
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003327 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003328 if (copy_to_user(priv_data.buf, &extra, len + 1))
3329 {
3330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3331 "%s: failed to copy data to user buffer", __func__);
3332 ret = -EFAULT;
3333 goto exit;
3334 }
3335 }
3336 else if (strncmp(command, "REASSOC", 7) == 0)
3337 {
3338 tANI_U8 *value = command;
3339 tANI_U8 channel = 0;
3340 tSirMacAddr targetApBssid;
3341 eHalStatus status = eHAL_STATUS_SUCCESS;
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003342#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3343 tCsrHandoffRequest handoffInfo;
3344#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003345 hdd_station_ctx_t *pHddStaCtx = NULL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003346 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3347
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003348 /* if not associated, no need to proceed with reassoc */
3349 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3350 {
3351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3352 ret = -EINVAL;
3353 goto exit;
3354 }
3355
3356 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
3357 if (eHAL_STATUS_SUCCESS != status)
3358 {
3359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3360 "%s: Failed to parse reassoc command data", __func__);
3361 ret = -EINVAL;
3362 goto exit;
3363 }
3364
3365 /* if the target bssid is same as currently associated AP,
3366 then no need to proceed with reassoc */
3367 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3368 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3369 {
3370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Reassoc BSSID is same as currently associated AP bssid",__func__);
3371 ret = -EINVAL;
3372 goto exit;
3373 }
3374
3375 /* Check channel number is a valid channel number */
3376 if(VOS_STATUS_SUCCESS !=
3377 wlan_hdd_validate_operation_channel(pAdapter, channel))
3378 {
3379 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003380 "%s: Invalid Channel [%d]", __func__, channel);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003381 return -EINVAL;
3382 }
3383
3384 /* Proceed with reassoc */
Varun Reddy Yeturucc661d22013-05-20 11:47:10 -07003385#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
3386 handoffInfo.channel = channel;
3387 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3388 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3389#endif
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07003390 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003391 else if (strncmp(command, "SETWESMODE", 10) == 0)
3392 {
3393 tANI_U8 *value = command;
3394 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
3395
3396 /* Move pointer to ahead of SETWESMODE<delimiter> */
3397 value = value + 11;
3398 /* Convert the value from ascii to integer */
3399 ret = kstrtou8(value, 10, &wesMode);
3400 if (ret < 0)
3401 {
3402 /* If the input value is greater than max value of datatype, then also
3403 kstrtou8 fails */
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3405 "%s: kstrtou8 failed range [%d - %d]", __func__,
3406 CFG_ENABLE_WES_MODE_NAME_MIN,
3407 CFG_ENABLE_WES_MODE_NAME_MAX);
3408 ret = -EINVAL;
3409 goto exit;
3410 }
3411
3412 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
3413 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
3414 {
3415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3416 "WES Mode value %d is out of range"
3417 " (Min: %d Max: %d)", wesMode,
3418 CFG_ENABLE_WES_MODE_NAME_MIN,
3419 CFG_ENABLE_WES_MODE_NAME_MAX);
3420 ret = -EINVAL;
3421 goto exit;
3422 }
3423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3424 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
3425
3426 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
3427 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
3428 }
3429 else if (strncmp(priv_data.buf, "GETWESMODE", 10) == 0)
3430 {
3431 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
3432 char extra[32];
3433 tANI_U8 len = 0;
3434
Arif Hussain826d9412013-11-12 16:44:54 -08003435 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003436 if (copy_to_user(priv_data.buf, &extra, len + 1))
3437 {
3438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3439 "%s: failed to copy data to user buffer", __func__);
3440 ret = -EFAULT;
3441 goto exit;
3442 }
3443 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003444#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003445#ifdef FEATURE_WLAN_LFR
3446 else if (strncmp(command, "SETFASTROAM", 11) == 0)
3447 {
3448 tANI_U8 *value = command;
3449 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3450
3451 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3452 value = value + 12;
3453 /* Convert the value from ascii to integer */
3454 ret = kstrtou8(value, 10, &lfrMode);
3455 if (ret < 0)
3456 {
3457 /* If the input value is greater than max value of datatype, then also
3458 kstrtou8 fails */
3459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3460 "%s: kstrtou8 failed range [%d - %d]", __func__,
3461 CFG_LFR_FEATURE_ENABLED_MIN,
3462 CFG_LFR_FEATURE_ENABLED_MAX);
3463 ret = -EINVAL;
3464 goto exit;
3465 }
3466
3467 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3468 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
3469 {
3470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3471 "lfr mode value %d is out of range"
3472 " (Min: %d Max: %d)", lfrMode,
3473 CFG_LFR_FEATURE_ENABLED_MIN,
3474 CFG_LFR_FEATURE_ENABLED_MAX);
3475 ret = -EINVAL;
3476 goto exit;
3477 }
3478
3479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3480 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
3481
3482 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
3483 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
3484 }
3485#endif
3486#ifdef WLAN_FEATURE_VOWIFI_11R
3487 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
3488 {
3489 tANI_U8 *value = command;
3490 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
3491
3492 /* Move pointer to ahead of SETFASTROAM<delimiter> */
3493 value = value + 18;
3494 /* Convert the value from ascii to integer */
3495 ret = kstrtou8(value, 10, &ft);
3496 if (ret < 0)
3497 {
3498 /* If the input value is greater than max value of datatype, then also
3499 kstrtou8 fails */
3500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3501 "%s: kstrtou8 failed range [%d - %d]", __func__,
3502 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3503 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3504 ret = -EINVAL;
3505 goto exit;
3506 }
3507
3508 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
3509 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
3510 {
3511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3512 "ft mode value %d is out of range"
3513 " (Min: %d Max: %d)", ft,
3514 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
3515 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
3516 ret = -EINVAL;
3517 goto exit;
3518 }
3519
3520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3521 "%s: Received Command to change ft mode = %d", __func__, ft);
3522
3523 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
3524 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
3525 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303526
3527 else if (strncmp(command, "FASTREASSOC", 11) == 0)
3528 {
3529 tANI_U8 *value = command;
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303530 tANI_U8 channel = 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303531 tSirMacAddr targetApBssid;
3532 tANI_U8 trigger = 0;
3533 eHalStatus status = eHAL_STATUS_SUCCESS;
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303534 tHalHandle hHal;
3535 v_U32_t roamId = 0;
3536 tCsrRoamModifyProfileFields modProfileFields;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303537 hdd_station_ctx_t *pHddStaCtx = NULL;
3538 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303539 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303540
3541 /* if not associated, no need to proceed with reassoc */
3542 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3543 {
3544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3545 ret = -EINVAL;
3546 goto exit;
3547 }
3548
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303549 status = hdd_parse_reassoc_command_data(value, targetApBssid, &channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303550 if (eHAL_STATUS_SUCCESS != status)
3551 {
3552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3553 "%s: Failed to parse reassoc command data", __func__);
3554 ret = -EINVAL;
3555 goto exit;
3556 }
3557
3558 /* if the target bssid is same as currently associated AP,
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303559 issue reassoc to same AP */
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303560 if (VOS_TRUE == vos_mem_compare(targetApBssid,
3561 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3562 {
3563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3564 "%s:11r Reassoc BSSID is same as currently associated AP bssid",
3565 __func__);
Padma, Santhosh Kumarb980a6f2014-11-06 19:07:24 +05303566 sme_GetModifyProfileFields(hHal, pAdapter->sessionId,
3567 &modProfileFields);
3568 sme_RoamReassoc(hHal, pAdapter->sessionId,
3569 NULL, modProfileFields, &roamId, 1);
3570 return 0;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303571 }
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05303572
3573 /* Check channel number is a valid channel number */
3574 if(VOS_STATUS_SUCCESS !=
3575 wlan_hdd_validate_operation_channel(pAdapter, channel))
3576 {
3577 hddLog(VOS_TRACE_LEVEL_ERROR,
3578 "%s: Invalid Channel [%d]", __func__, channel);
3579 return -EINVAL;
3580 }
3581
Padma, Santhosh Kumarf4582d32014-11-06 19:24:51 +05303582 trigger = eSME_ROAM_TRIGGER_SCAN;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303583
3584 /* Proceed with scan/roam */
3585 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3586 &targetApBssid[0],
Mukul Sharma9e4e0f92015-02-13 18:45:20 +05303587 (tSmeFastRoamTrigger)(trigger),
3588 channel);
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05303589 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003590#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003591#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003592 else if (strncmp(command, "SETCCXMODE", 10) == 0)
3593 {
3594 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003595 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003596
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003597 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003598 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003599 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003600 hdd_is_okc_mode_enabled(pHddCtx) &&
3601 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3602 {
3603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003604 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003605 " hence this operation is not permitted!", __func__);
3606 ret = -EPERM;
3607 goto exit;
3608 }
3609
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003610 /* Move pointer to ahead of SETCCXMODE<delimiter> */
3611 value = value + 11;
3612 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003613 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003614 if (ret < 0)
3615 {
3616 /* If the input value is greater than max value of datatype, then also
3617 kstrtou8 fails */
3618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3619 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003620 CFG_ESE_FEATURE_ENABLED_MIN,
3621 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003622 ret = -EINVAL;
3623 goto exit;
3624 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003625 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
3626 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003627 {
3628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003629 "Ese mode value %d is out of range"
3630 " (Min: %d Max: %d)", eseMode,
3631 CFG_ESE_FEATURE_ENABLED_MIN,
3632 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003633 ret = -EINVAL;
3634 goto exit;
3635 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003637 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003638
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003639 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
3640 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003641 }
3642#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003643 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
3644 {
3645 tANI_U8 *value = command;
3646 tANI_BOOLEAN roamScanControl = 0;
3647
3648 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
3649 value = value + 19;
3650 /* Convert the value from ascii to integer */
3651 ret = kstrtou8(value, 10, &roamScanControl);
3652 if (ret < 0)
3653 {
3654 /* If the input value is greater than max value of datatype, then also
3655 kstrtou8 fails */
3656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3657 "%s: kstrtou8 failed ", __func__);
3658 ret = -EINVAL;
3659 goto exit;
3660 }
3661
3662 if (0 != roamScanControl)
3663 {
3664 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3665 "roam scan control invalid value = %d",
3666 roamScanControl);
3667 ret = -EINVAL;
3668 goto exit;
3669 }
3670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3671 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
3672
3673 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
3674 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003675#ifdef FEATURE_WLAN_OKC
3676 else if (strncmp(command, "SETOKCMODE", 10) == 0)
3677 {
3678 tANI_U8 *value = command;
3679 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
3680
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003681 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003682 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003683 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003684 hdd_is_okc_mode_enabled(pHddCtx) &&
3685 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3686 {
3687 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003688 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003689 " hence this operation is not permitted!", __func__);
3690 ret = -EPERM;
3691 goto exit;
3692 }
3693
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003694 /* Move pointer to ahead of SETOKCMODE<delimiter> */
3695 value = value + 11;
3696 /* Convert the value from ascii to integer */
3697 ret = kstrtou8(value, 10, &okcMode);
3698 if (ret < 0)
3699 {
3700 /* If the input value is greater than max value of datatype, then also
3701 kstrtou8 fails */
3702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3703 "%s: kstrtou8 failed range [%d - %d]", __func__,
3704 CFG_OKC_FEATURE_ENABLED_MIN,
3705 CFG_OKC_FEATURE_ENABLED_MAX);
3706 ret = -EINVAL;
3707 goto exit;
3708 }
3709
3710 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
3711 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
3712 {
3713 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3714 "Okc mode value %d is out of range"
3715 " (Min: %d Max: %d)", okcMode,
3716 CFG_OKC_FEATURE_ENABLED_MIN,
3717 CFG_OKC_FEATURE_ENABLED_MAX);
3718 ret = -EINVAL;
3719 goto exit;
3720 }
3721
3722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3723 "%s: Received Command to change okc mode = %d", __func__, okcMode);
3724
3725 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
3726 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07003727#endif /* FEATURE_WLAN_OKC */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003728 else if (strncmp(priv_data.buf, "GETROAMSCANCONTROL", 18) == 0)
3729 {
3730 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
3731 char extra[32];
3732 tANI_U8 len = 0;
3733
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003734 len = scnprintf(extra, sizeof(extra), "%s %d",
3735 command, roamScanControl);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003736 if (copy_to_user(priv_data.buf, &extra, len + 1))
3737 {
3738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3739 "%s: failed to copy data to user buffer", __func__);
3740 ret = -EFAULT;
3741 goto exit;
3742 }
3743 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05303744#ifdef WLAN_FEATURE_PACKET_FILTERING
3745 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
3746 {
3747 tANI_U8 filterType = 0;
3748 tANI_U8 *value = command;
3749
3750 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
3751 value = value + 22;
3752
3753 /* Convert the value from ascii to integer */
3754 ret = kstrtou8(value, 10, &filterType);
3755 if (ret < 0)
3756 {
3757 /* If the input value is greater than max value of datatype,
3758 * then also kstrtou8 fails
3759 */
3760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3761 "%s: kstrtou8 failed range ", __func__);
3762 ret = -EINVAL;
3763 goto exit;
3764 }
3765
3766 if (filterType != 0 && filterType != 1)
3767 {
3768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3769 "%s: Accepted Values are 0 and 1 ", __func__);
3770 ret = -EINVAL;
3771 goto exit;
3772 }
3773 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
3774 pAdapter->sessionId);
3775 }
3776#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303777 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
3778 {
Kiet Lamad161252014-07-22 11:23:32 -07003779 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303780 int ret;
3781
Kiet Lamad161252014-07-22 11:23:32 -07003782 dhcpPhase = command + 11;
3783 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303784 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003786 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303787
3788 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07003789
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05303790 ret = wlan_hdd_scan_abort(pAdapter);
3791 if (ret < 0)
3792 {
3793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3794 FL("failed to abort existing scan %d"), ret);
3795 }
3796
Kiet Lamad161252014-07-22 11:23:32 -07003797 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
3798 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303799 }
Kiet Lamad161252014-07-22 11:23:32 -07003800 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303801 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05303802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07003803 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05303804
3805 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07003806
3807 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
3808 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05303809 }
3810 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003811 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
3812 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3814 FL("making default scan to ACTIVE"));
3815 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003816 }
3817 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
3818 {
c_hpothudbefd3e2014-04-28 15:59:47 +05303819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3820 FL("making default scan to PASSIVE"));
3821 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07003822 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303823 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
3824 {
3825 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
3826 char extra[32];
3827 tANI_U8 len = 0;
3828
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303829 memset(extra, 0, sizeof(extra));
3830 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
3831 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len + 1))
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303832 {
3833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3834 "%s: failed to copy data to user buffer", __func__);
3835 ret = -EFAULT;
3836 goto exit;
3837 }
3838 ret = len;
3839 }
3840 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3841 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303842 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05303843 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003844 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
3845 {
3846 tANI_U8 filterType = 0;
3847 tANI_U8 *value;
3848 value = command + 9;
3849
3850 /* Convert the value from ascii to integer */
3851 ret = kstrtou8(value, 10, &filterType);
3852 if (ret < 0)
3853 {
3854 /* If the input value is greater than max value of datatype,
3855 * then also kstrtou8 fails
3856 */
3857 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3858 "%s: kstrtou8 failed range ", __func__);
3859 ret = -EINVAL;
3860 goto exit;
3861 }
3862 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
3863 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
3864 {
3865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3866 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
3867 " 2-Sink ", __func__);
3868 ret = -EINVAL;
3869 goto exit;
3870 }
3871 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
3872 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303873 pScanInfo = &pHddCtx->scan_info;
3874 if (filterType && pScanInfo != NULL &&
3875 pHddCtx->scan_info.mScanPending)
3876 {
3877 /*Miracast Session started. Abort Scan */
3878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3879 "%s, Aborting Scan For Miracast",__func__);
3880 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
3881 eCSR_SCAN_ABORT_DEFAULT);
3882 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003883 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05303884 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07003885 }
Leo Chang614d2072013-08-22 14:59:44 -07003886 else if (strncmp(command, "SETMCRATE", 9) == 0)
3887 {
Leo Chang614d2072013-08-22 14:59:44 -07003888 tANI_U8 *value = command;
3889 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07003890 tSirRateUpdateInd *rateUpdate;
3891 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07003892
3893 /* Only valid for SAP mode */
3894 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
3895 {
3896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3897 "%s: SAP mode is not running", __func__);
3898 ret = -EFAULT;
3899 goto exit;
3900 }
3901
3902 /* Move pointer to ahead of SETMCRATE<delimiter> */
3903 /* input value is in units of hundred kbps */
3904 value = value + 10;
3905 /* Convert the value from ascii to integer, decimal base */
3906 ret = kstrtouint(value, 10, &targetRate);
3907
Leo Chang1f98cbd2013-10-17 15:03:52 -07003908 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
3909 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07003910 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07003911 hddLog(VOS_TRACE_LEVEL_ERROR,
3912 "%s: SETMCRATE indication alloc fail", __func__);
3913 ret = -EFAULT;
3914 goto exit;
3915 }
3916 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
3917
3918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3919 "MC Target rate %d", targetRate);
3920 /* Ignore unicast */
3921 rateUpdate->ucastDataRate = -1;
3922 rateUpdate->mcastDataRate24GHz = targetRate;
3923 rateUpdate->mcastDataRate5GHz = targetRate;
3924 rateUpdate->mcastDataRate24GHzTxFlag = 0;
3925 rateUpdate->mcastDataRate5GHzTxFlag = 0;
3926 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
3927 if (eHAL_STATUS_SUCCESS != status)
3928 {
3929 hddLog(VOS_TRACE_LEVEL_ERROR,
3930 "%s: SET_MC_RATE failed", __func__);
3931 vos_mem_free(rateUpdate);
3932 ret = -EFAULT;
3933 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07003934 }
3935 }
Rajeev79dbe4c2013-10-05 11:03:42 +05303936#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08003937 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05303938 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08003939 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05303940 }
3941#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003942#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003943 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
3944 {
3945 tANI_U8 *value = command;
3946 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3947 tANI_U8 numChannels = 0;
3948 eHalStatus status = eHAL_STATUS_SUCCESS;
3949
3950 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3951 if (eHAL_STATUS_SUCCESS != status)
3952 {
3953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3954 "%s: Failed to parse channel list information", __func__);
3955 ret = -EINVAL;
3956 goto exit;
3957 }
3958
3959 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3960 {
3961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3962 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3963 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3964 ret = -EINVAL;
3965 goto exit;
3966 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003967 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07003968 ChannelList,
3969 numChannels);
3970 if (eHAL_STATUS_SUCCESS != status)
3971 {
3972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3973 "%s: Failed to update channel list information", __func__);
3974 ret = -EINVAL;
3975 goto exit;
3976 }
3977 }
3978 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
3979 {
3980 tANI_U8 *value = command;
3981 char extra[128] = {0};
3982 int len = 0;
3983 tANI_U8 tid = 0;
3984 hdd_station_ctx_t *pHddStaCtx = NULL;
3985 tAniTrafStrmMetrics tsmMetrics;
3986 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3987
3988 /* if not associated, return error */
3989 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3990 {
3991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
3992 ret = -EINVAL;
3993 goto exit;
3994 }
3995
3996 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
3997 value = value + 12;
3998 /* Convert the value from ascii to integer */
3999 ret = kstrtou8(value, 10, &tid);
4000 if (ret < 0)
4001 {
4002 /* If the input value is greater than max value of datatype, then also
4003 kstrtou8 fails */
4004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4005 "%s: kstrtou8 failed range [%d - %d]", __func__,
4006 TID_MIN_VALUE,
4007 TID_MAX_VALUE);
4008 ret = -EINVAL;
4009 goto exit;
4010 }
4011
4012 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
4013 {
4014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4015 "tid value %d is out of range"
4016 " (Min: %d Max: %d)", tid,
4017 TID_MIN_VALUE,
4018 TID_MAX_VALUE);
4019 ret = -EINVAL;
4020 goto exit;
4021 }
4022
4023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4024 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
4025
4026 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
4027 {
4028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4029 "%s: failed to get tsm stats", __func__);
4030 ret = -EFAULT;
4031 goto exit;
4032 }
4033
4034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4035 "UplinkPktQueueDly(%d)\n"
4036 "UplinkPktQueueDlyHist[0](%d)\n"
4037 "UplinkPktQueueDlyHist[1](%d)\n"
4038 "UplinkPktQueueDlyHist[2](%d)\n"
4039 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304040 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004041 "UplinkPktLoss(%d)\n"
4042 "UplinkPktCount(%d)\n"
4043 "RoamingCount(%d)\n"
4044 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
4045 tsmMetrics.UplinkPktQueueDlyHist[0],
4046 tsmMetrics.UplinkPktQueueDlyHist[1],
4047 tsmMetrics.UplinkPktQueueDlyHist[2],
4048 tsmMetrics.UplinkPktQueueDlyHist[3],
4049 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
4050 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
4051
4052 /* Output TSM stats is of the format
4053 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
4054 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004055 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004056 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
4057 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
4058 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
4059 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
4060 tsmMetrics.RoamingDly);
4061
4062 if (copy_to_user(priv_data.buf, &extra, len + 1))
4063 {
4064 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4065 "%s: failed to copy data to user buffer", __func__);
4066 ret = -EFAULT;
4067 goto exit;
4068 }
4069 }
4070 else if (strncmp(command, "SETCCKMIE", 9) == 0)
4071 {
4072 tANI_U8 *value = command;
4073 tANI_U8 *cckmIe = NULL;
4074 tANI_U8 cckmIeLen = 0;
4075 eHalStatus status = eHAL_STATUS_SUCCESS;
4076
4077 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
4078 if (eHAL_STATUS_SUCCESS != status)
4079 {
4080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4081 "%s: Failed to parse cckm ie data", __func__);
4082 ret = -EINVAL;
4083 goto exit;
4084 }
4085
4086 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
4087 {
4088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4089 "%s: CCKM Ie input length is more than max[%d]", __func__,
4090 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004091 vos_mem_free(cckmIe);
4092 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004093 ret = -EINVAL;
4094 goto exit;
4095 }
4096 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004097 vos_mem_free(cckmIe);
4098 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004099 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004100 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
4101 {
4102 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004103 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004104 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004105
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004106 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004107 if (eHAL_STATUS_SUCCESS != status)
4108 {
4109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004110 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004111 ret = -EINVAL;
4112 goto exit;
4113 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07004114 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
4115 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
4116 hdd_indicateEseBcnReportNoResults (pAdapter,
4117 eseBcnReq.bcnReq[0].measurementToken,
4118 0x02, //BIT(1) set for measurement done
4119 0); // no BSS
4120 goto exit;
4121 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004122
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004123 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
4124 if (eHAL_STATUS_SUCCESS != status)
4125 {
4126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4127 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
4128 ret = -EINVAL;
4129 goto exit;
4130 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004131 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004132#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05304133 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
4134 {
4135 eHalStatus status;
4136 char buf[32], len;
4137 long waitRet;
4138 bcnMissRateContext_t getBcnMissRateCtx;
4139
4140 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4141
4142 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4143 {
4144 hddLog(VOS_TRACE_LEVEL_WARN,
4145 FL("GETBCNMISSRATE: STA is not in connected state"));
4146 ret = -1;
4147 goto exit;
4148 }
4149
4150 init_completion(&(getBcnMissRateCtx.completion));
4151 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
4152
4153 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
4154 pAdapter->sessionId,
4155 (void *)getBcnMissRateCB,
4156 (void *)(&getBcnMissRateCtx));
4157 if( eHAL_STATUS_SUCCESS != status)
4158 {
4159 hddLog(VOS_TRACE_LEVEL_INFO,
4160 FL("GETBCNMISSRATE: fail to post WDA cmd"));
4161 ret = -EINVAL;
4162 goto exit;
4163 }
4164
4165 waitRet = wait_for_completion_interruptible_timeout
4166 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
4167 if(waitRet <= 0)
4168 {
4169 hddLog(VOS_TRACE_LEVEL_ERROR,
4170 FL("failed to wait on bcnMissRateComp %d"), ret);
4171
4172 //Make magic number to zero so that callback is not called.
4173 spin_lock(&hdd_context_lock);
4174 getBcnMissRateCtx.magic = 0x0;
4175 spin_unlock(&hdd_context_lock);
4176 ret = -EINVAL;
4177 goto exit;
4178 }
4179
4180 hddLog(VOS_TRACE_LEVEL_INFO,
4181 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
4182
4183 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
4184 if (copy_to_user(priv_data.buf, &buf, len + 1))
4185 {
4186 hddLog(VOS_TRACE_LEVEL_ERROR,
4187 "%s: failed to copy data to user buffer", __func__);
4188 ret = -EFAULT;
4189 goto exit;
4190 }
4191 ret = len;
4192 }
Atul Mittal87ec2422014-09-24 13:12:50 +05304193#ifdef FEATURE_WLAN_TDLS
4194 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
4195 tANI_U8 *value = command;
4196 int set_value;
4197 /* Move pointer to ahead of TDLSOFFCH*/
4198 value += 26;
4199 sscanf(value, "%d", &set_value);
4200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4201 "%s: Tdls offchannel offset:%d",
4202 __func__, set_value);
4203 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
4204 if (ret < 0)
4205 {
4206 ret = -EINVAL;
4207 goto exit;
4208 }
4209
4210 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
4211 tANI_U8 *value = command;
4212 int set_value;
4213 /* Move pointer to ahead of tdlsoffchnmode*/
4214 value += 18;
4215 sscanf(value, "%d", &set_value);
4216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4217 "%s: Tdls offchannel mode:%d",
4218 __func__, set_value);
4219 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
4220 if (ret < 0)
4221 {
4222 ret = -EINVAL;
4223 goto exit;
4224 }
4225 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
4226 tANI_U8 *value = command;
4227 int set_value;
4228 /* Move pointer to ahead of TDLSOFFCH*/
4229 value += 14;
4230 sscanf(value, "%d", &set_value);
4231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4232 "%s: Tdls offchannel num: %d",
4233 __func__, set_value);
4234 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
4235 if (ret < 0)
4236 {
4237 ret = -EINVAL;
4238 goto exit;
4239 }
4240 }
4241#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05304242 else if (strncmp(command, "GETFWSTATS", 10) == 0)
4243 {
4244 eHalStatus status;
4245 char *buf = NULL;
4246 char len;
4247 long waitRet;
4248 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05304249 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304250 tANI_U8 *ptr = command;
4251 int stats = *(ptr + 11) - '0';
4252
4253 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
4254 if (!IS_FEATURE_FW_STATS_ENABLE)
4255 {
4256 hddLog(VOS_TRACE_LEVEL_INFO,
4257 FL("Get Firmware stats feature not supported"));
4258 ret = -EINVAL;
4259 goto exit;
4260 }
4261
4262 if (FW_STATS_MAX <= stats || 0 >= stats)
4263 {
4264 hddLog(VOS_TRACE_LEVEL_INFO,
4265 FL(" stats %d not supported"),stats);
4266 ret = -EINVAL;
4267 goto exit;
4268 }
4269
4270 init_completion(&(fwStatsCtx.completion));
4271 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
4272 fwStatsCtx.pAdapter = pAdapter;
4273 fwStatsRsp->type = 0;
4274 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05304275 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304276 if (eHAL_STATUS_SUCCESS != status)
4277 {
4278 hddLog(VOS_TRACE_LEVEL_ERROR,
4279 FL(" fail to post WDA cmd status = %d"), status);
4280 ret = -EINVAL;
4281 goto exit;
4282 }
4283 waitRet = wait_for_completion_timeout
4284 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
4285 if (waitRet <= 0)
4286 {
4287 hddLog(VOS_TRACE_LEVEL_ERROR,
4288 FL("failed to wait on GwtFwstats"));
4289 //Make magic number to zero so that callback is not executed.
4290 spin_lock(&hdd_context_lock);
4291 fwStatsCtx.magic = 0x0;
4292 spin_unlock(&hdd_context_lock);
4293 ret = -EINVAL;
4294 goto exit;
4295 }
4296 if (fwStatsRsp->type)
4297 {
4298 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
4299 if (!buf)
4300 {
4301 hddLog(VOS_TRACE_LEVEL_ERROR,
4302 FL(" failed to allocate memory"));
4303 ret = -ENOMEM;
4304 goto exit;
4305 }
4306 switch( fwStatsRsp->type )
4307 {
4308 case FW_UBSP_STATS:
4309 {
4310 len = snprintf(buf, FW_STATE_RSP_LEN,
4311 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05304312 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
4313 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05304314 }
4315 break;
4316 default:
4317 {
4318 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
4319 ret = -EFAULT;
4320 kfree(buf);
4321 goto exit;
4322 }
4323 }
4324 if (copy_to_user(priv_data.buf, buf, len + 1))
4325 {
4326 hddLog(VOS_TRACE_LEVEL_ERROR,
4327 FL(" failed to copy data to user buffer"));
4328 ret = -EFAULT;
4329 kfree(buf);
4330 goto exit;
4331 }
4332 ret = len;
4333 kfree(buf);
4334 }
4335 else
4336 {
4337 hddLog(VOS_TRACE_LEVEL_ERROR,
4338 FL("failed to fetch the stats"));
4339 ret = -EFAULT;
4340 goto exit;
4341 }
4342
4343 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004344 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304345 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4346 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
4347 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05304348 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
4349 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07004350 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004351 }
4352exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304353 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004354 if (command)
4355 {
4356 kfree(command);
4357 }
4358 return ret;
4359}
4360
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004361#ifdef CONFIG_COMPAT
4362static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4363{
4364 struct {
4365 compat_uptr_t buf;
4366 int used_len;
4367 int total_len;
4368 } compat_priv_data;
4369 hdd_priv_data_t priv_data;
4370 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004371
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004372 /*
4373 * Note that pAdapter and ifr have already been verified by caller,
4374 * and HDD context has also been validated
4375 */
4376 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
4377 sizeof(compat_priv_data))) {
4378 ret = -EFAULT;
4379 goto exit;
4380 }
4381 priv_data.buf = compat_ptr(compat_priv_data.buf);
4382 priv_data.used_len = compat_priv_data.used_len;
4383 priv_data.total_len = compat_priv_data.total_len;
4384 ret = hdd_driver_command(pAdapter, &priv_data);
4385 exit:
4386 return ret;
4387}
4388#else /* CONFIG_COMPAT */
4389static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4390{
4391 /* will never be invoked */
4392 return 0;
4393}
4394#endif /* CONFIG_COMPAT */
4395
4396static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
4397{
4398 hdd_priv_data_t priv_data;
4399 int ret = 0;
4400
4401 /*
4402 * Note that pAdapter and ifr have already been verified by caller,
4403 * and HDD context has also been validated
4404 */
4405 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
4406 ret = -EFAULT;
4407 } else {
4408 ret = hdd_driver_command(pAdapter, &priv_data);
4409 }
4410 return ret;
4411}
4412
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304413int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004414{
4415 hdd_adapter_t *pAdapter;
4416 hdd_context_t *pHddCtx;
4417 int ret;
4418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304419 ENTER();
4420
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004421 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4422 if (NULL == pAdapter) {
4423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4424 "%s: HDD adapter context is Null", __func__);
4425 ret = -ENODEV;
4426 goto exit;
4427 }
4428 if (dev != pAdapter->dev) {
4429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4430 "%s: HDD adapter/dev inconsistency", __func__);
4431 ret = -ENODEV;
4432 goto exit;
4433 }
4434
4435 if ((!ifr) || (!ifr->ifr_data)) {
4436 ret = -EINVAL;
4437 goto exit;
4438 }
4439
4440 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4441 ret = wlan_hdd_validate_context(pHddCtx);
4442 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004443 ret = -EBUSY;
4444 goto exit;
4445 }
4446
4447 switch (cmd) {
4448 case (SIOCDEVPRIVATE + 1):
4449 if (is_compat_task())
4450 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
4451 else
4452 ret = hdd_driver_ioctl(pAdapter, ifr);
4453 break;
4454 default:
4455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
4456 __func__, cmd);
4457 ret = -EINVAL;
4458 break;
4459 }
4460 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304461 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004462 return ret;
4463}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004464
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05304465int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4466{
4467 int ret;
4468
4469 vos_ssr_protect(__func__);
4470 ret = __hdd_ioctl(dev, ifr, cmd);
4471 vos_ssr_unprotect(__func__);
4472
4473 return ret;
4474}
4475
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004476#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004477/**---------------------------------------------------------------------------
4478
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004479 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004480
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004481 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004482 CCXBEACONREQ<space><Number of fields><space><Measurement token>
4483 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
4484 <space>Scan Mode N<space>Meas Duration N
4485 if the Number of bcn req fields (N) does not match with the actual number of fields passed
4486 then take N.
4487 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
4488 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
4489 This function does not take care of removing duplicate channels from the list
4490
4491 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004492 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004493
4494 \return - 0 for success non-zero for failure
4495
4496 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004497static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
4498 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004499{
4500 tANI_U8 *inPtr = pValue;
4501 int tempInt = 0;
4502 int j = 0, i = 0, v = 0;
4503 char buf[32];
4504
4505 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4506 /*no argument after the command*/
4507 if (NULL == inPtr)
4508 {
4509 return -EINVAL;
4510 }
4511 /*no space after the command*/
4512 else if (SPACE_ASCII_VALUE != *inPtr)
4513 {
4514 return -EINVAL;
4515 }
4516
4517 /*removing empty spaces*/
4518 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4519
4520 /*no argument followed by spaces*/
4521 if ('\0' == *inPtr) return -EINVAL;
4522
4523 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004524 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004525 if (1 != v) return -EINVAL;
4526
4527 v = kstrtos32(buf, 10, &tempInt);
4528 if ( v < 0) return -EINVAL;
4529
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004530 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004531
4532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004533 "Number of Bcn Req Ie fields(%d)", pEseBcnReq->numBcnReqIe);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004534
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004535 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004536 {
4537 for (i = 0; i < 4; i++)
4538 {
4539 /*inPtr pointing to the beginning of first space after number of ie fields*/
4540 inPtr = strpbrk( inPtr, " " );
4541 /*no ie data after the number of ie fields argument*/
4542 if (NULL == inPtr) return -EINVAL;
4543
4544 /*removing empty space*/
4545 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
4546
4547 /*no ie data after the number of ie fields argument and spaces*/
4548 if ( '\0' == *inPtr ) return -EINVAL;
4549
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004550 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004551 if (1 != v) return -EINVAL;
4552
4553 v = kstrtos32(buf, 10, &tempInt);
4554 if (v < 0) return -EINVAL;
4555
4556 switch (i)
4557 {
4558 case 0: /* Measurement token */
4559 if (tempInt <= 0)
4560 {
4561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4562 "Invalid Measurement Token(%d)", tempInt);
4563 return -EINVAL;
4564 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004565 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004566 break;
4567
4568 case 1: /* Channel number */
4569 if ((tempInt <= 0) ||
4570 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
4571 {
4572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4573 "Invalid Channel Number(%d)", tempInt);
4574 return -EINVAL;
4575 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004576 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004577 break;
4578
4579 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08004580 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004581 {
4582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4583 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
4584 return -EINVAL;
4585 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004586 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004587 break;
4588
4589 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004590 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
4591 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004592 {
4593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4594 "Invalid Measurement Duration(%d)", tempInt);
4595 return -EINVAL;
4596 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004597 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004598 break;
4599 }
4600 }
4601 }
4602
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004603 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004604 {
4605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05304606 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004607 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004608 pEseBcnReq->bcnReq[j].measurementToken,
4609 pEseBcnReq->bcnReq[j].channel,
4610 pEseBcnReq->bcnReq[j].scanMode,
4611 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08004612 }
4613
4614 return VOS_STATUS_SUCCESS;
4615}
4616
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004617static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
4618{
4619 struct statsContext *pStatsContext = NULL;
4620 hdd_adapter_t *pAdapter = NULL;
4621
4622 if (NULL == pContext)
4623 {
4624 hddLog(VOS_TRACE_LEVEL_ERROR,
4625 "%s: Bad param, pContext [%p]",
4626 __func__, pContext);
4627 return;
4628 }
4629
Jeff Johnson72a40512013-12-19 10:14:15 -08004630 /* there is a race condition that exists between this callback
4631 function and the caller since the caller could time out either
4632 before or while this code is executing. we use a spinlock to
4633 serialize these actions */
4634 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004635
4636 pStatsContext = pContext;
4637 pAdapter = pStatsContext->pAdapter;
4638 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
4639 {
4640 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08004641 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004642 hddLog(VOS_TRACE_LEVEL_WARN,
4643 "%s: Invalid context, pAdapter [%p] magic [%08x]",
4644 __func__, pAdapter, pStatsContext->magic);
4645 return;
4646 }
4647
Jeff Johnson72a40512013-12-19 10:14:15 -08004648 /* context is valid so caller is still waiting */
4649
4650 /* paranoia: invalidate the magic */
4651 pStatsContext->magic = 0;
4652
4653 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004654 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
4655 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
4656 tsmMetrics.UplinkPktQueueDlyHist,
4657 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4658 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4659 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
4660 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
4661 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
4662 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
4663 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
4664
Jeff Johnson72a40512013-12-19 10:14:15 -08004665 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004666 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08004667
4668 /* serialization is complete */
4669 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004670}
4671
4672
4673
4674static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
4675 tAniTrafStrmMetrics* pTsmMetrics)
4676{
4677 hdd_station_ctx_t *pHddStaCtx = NULL;
4678 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08004679 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004680 long lrc;
4681 struct statsContext context;
4682 hdd_context_t *pHddCtx = NULL;
4683
4684 if (NULL == pAdapter)
4685 {
4686 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
4687 return VOS_STATUS_E_FAULT;
4688 }
4689
4690 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4691 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4692
4693 /* we are connected prepare our callback context */
4694 init_completion(&context.completion);
4695 context.pAdapter = pAdapter;
4696 context.magic = STATS_CONTEXT_MAGIC;
4697
4698 /* query tsm stats */
4699 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
4700 pHddStaCtx->conn_info.staId[ 0 ],
4701 pHddStaCtx->conn_info.bssId,
4702 &context, pHddCtx->pvosContext, tid);
4703
4704 if (eHAL_STATUS_SUCCESS != hstatus)
4705 {
Jeff Johnson72a40512013-12-19 10:14:15 -08004706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
4707 __func__);
4708 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004709 }
4710 else
4711 {
4712 /* request was sent -- wait for the response */
4713 lrc = wait_for_completion_interruptible_timeout(&context.completion,
4714 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004715 if (lrc <= 0)
4716 {
4717 hddLog(VOS_TRACE_LEVEL_ERROR,
4718 "%s: SME %s while retrieving statistics",
4719 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08004720 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004721 }
4722 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004723
Jeff Johnson72a40512013-12-19 10:14:15 -08004724 /* either we never sent a request, we sent a request and received a
4725 response or we sent a request and timed out. if we never sent a
4726 request or if we sent a request and got a response, we want to
4727 clear the magic out of paranoia. if we timed out there is a
4728 race condition such that the callback function could be
4729 executing at the same time we are. of primary concern is if the
4730 callback function had already verified the "magic" but had not
4731 yet set the completion variable when a timeout occurred. we
4732 serialize these activities by invalidating the magic while
4733 holding a shared spinlock which will cause us to block if the
4734 callback is currently executing */
4735 spin_lock(&hdd_context_lock);
4736 context.magic = 0;
4737 spin_unlock(&hdd_context_lock);
4738
4739 if (VOS_STATUS_SUCCESS == vstatus)
4740 {
4741 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
4742 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
4743 pAdapter->tsmStats.UplinkPktQueueDlyHist,
4744 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
4745 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
4746 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
4747 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
4748 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
4749 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
4750 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
4751 }
4752 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004753}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004754#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07004755
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004756#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004757void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
4758{
4759 eCsrBand band = -1;
4760 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
4761 switch (band)
4762 {
4763 case eCSR_BAND_ALL:
4764 *pBand = WLAN_HDD_UI_BAND_AUTO;
4765 break;
4766
4767 case eCSR_BAND_24:
4768 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
4769 break;
4770
4771 case eCSR_BAND_5G:
4772 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
4773 break;
4774
4775 default:
4776 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
4777 *pBand = -1;
4778 break;
4779 }
4780}
4781
4782/**---------------------------------------------------------------------------
4783
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004784 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
4785
4786 This function parses the send action frame data passed in the format
4787 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
4788
Srinivas Girigowda56076852013-08-20 14:00:50 -07004789 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004790 \param - pTargetApBssid Pointer to target Ap bssid
4791 \param - pChannel Pointer to the Target AP channel
4792 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
4793 \param - pBuf Pointer to data
4794 \param - pBufLen Pointer to data length
4795
4796 \return - 0 for success non-zero for failure
4797
4798 --------------------------------------------------------------------------*/
4799VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
4800 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
4801{
4802 tANI_U8 *inPtr = pValue;
4803 tANI_U8 *dataEnd;
4804 int tempInt;
4805 int j = 0;
4806 int i = 0;
4807 int v = 0;
4808 tANI_U8 tempBuf[32];
4809 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004810 /* 12 hexa decimal digits, 5 ':' and '\0' */
4811 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004812
4813 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4814 /*no argument after the command*/
4815 if (NULL == inPtr)
4816 {
4817 return -EINVAL;
4818 }
4819
4820 /*no space after the command*/
4821 else if (SPACE_ASCII_VALUE != *inPtr)
4822 {
4823 return -EINVAL;
4824 }
4825
4826 /*removing empty spaces*/
4827 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4828
4829 /*no argument followed by spaces*/
4830 if ('\0' == *inPtr)
4831 {
4832 return -EINVAL;
4833 }
4834
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004835 v = sscanf(inPtr, "%17s", macAddress);
4836 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004837 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4839 "Invalid MAC address or All hex inputs are not read (%d)", v);
4840 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004841 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004842
4843 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
4844 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
4845 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
4846 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
4847 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
4848 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004849
4850 /* point to the next argument */
4851 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4852 /*no argument after the command*/
4853 if (NULL == inPtr) return -EINVAL;
4854
4855 /*removing empty spaces*/
4856 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4857
4858 /*no argument followed by spaces*/
4859 if ('\0' == *inPtr)
4860 {
4861 return -EINVAL;
4862 }
4863
4864 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004865 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004866 if (1 != v) return -EINVAL;
4867
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004868 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05304869 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05304870 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004871
4872 *pChannel = tempInt;
4873
4874 /* point to the next argument */
4875 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4876 /*no argument after the command*/
4877 if (NULL == inPtr) return -EINVAL;
4878 /*removing empty spaces*/
4879 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4880
4881 /*no argument followed by spaces*/
4882 if ('\0' == *inPtr)
4883 {
4884 return -EINVAL;
4885 }
4886
4887 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08004888 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07004889 if (1 != v) return -EINVAL;
4890
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004891 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08004892 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004893
4894 *pDwellTime = tempInt;
4895
4896 /* point to the next argument */
4897 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
4898 /*no argument after the command*/
4899 if (NULL == inPtr) return -EINVAL;
4900 /*removing empty spaces*/
4901 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
4902
4903 /*no argument followed by spaces*/
4904 if ('\0' == *inPtr)
4905 {
4906 return -EINVAL;
4907 }
4908
4909 /* find the length of data */
4910 dataEnd = inPtr;
4911 while(('\0' != *dataEnd) )
4912 {
4913 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004914 }
Kiet Lambe150c22013-11-21 16:30:32 +05304915 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004916 if ( *pBufLen <= 0) return -EINVAL;
4917
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07004918 /* Allocate the number of bytes based on the number of input characters
4919 whether it is even or odd.
4920 if the number of input characters are even, then we need N/2 byte.
4921 if the number of input characters are odd, then we need do (N+1)/2 to
4922 compensate rounding off.
4923 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
4924 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
4925 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004926 if (NULL == *pBuf)
4927 {
4928 hddLog(VOS_TRACE_LEVEL_FATAL,
4929 "%s: vos_mem_alloc failed ", __func__);
4930 return -EINVAL;
4931 }
4932
4933 /* the buffer received from the upper layer is character buffer,
4934 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
4935 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
4936 and f0 in 3rd location */
4937 for (i = 0, j = 0; j < *pBufLen; j += 2)
4938 {
Kiet Lambe150c22013-11-21 16:30:32 +05304939 if( j+1 == *pBufLen)
4940 {
4941 tempByte = hdd_parse_hex(inPtr[j]);
4942 }
4943 else
4944 {
4945 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
4946 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004947 (*pBuf)[i++] = tempByte;
4948 }
4949 *pBufLen = i;
4950 return VOS_STATUS_SUCCESS;
4951}
4952
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004953/**---------------------------------------------------------------------------
4954
Srinivas Girigowdade697412013-02-14 16:31:48 -08004955 \brief hdd_parse_channellist() - HDD Parse channel list
4956
4957 This function parses the channel list passed in the format
4958 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07004959 if the Number of channels (N) does not match with the actual number of channels passed
4960 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
4961 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
4962 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
4963 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08004964
4965 \param - pValue Pointer to input channel list
4966 \param - ChannelList Pointer to local output array to record channel list
4967 \param - pNumChannels Pointer to number of roam scan channels
4968
4969 \return - 0 for success non-zero for failure
4970
4971 --------------------------------------------------------------------------*/
4972VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
4973{
4974 tANI_U8 *inPtr = pValue;
4975 int tempInt;
4976 int j = 0;
4977 int v = 0;
4978 char buf[32];
4979
4980 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
4981 /*no argument after the command*/
4982 if (NULL == inPtr)
4983 {
4984 return -EINVAL;
4985 }
4986
4987 /*no space after the command*/
4988 else if (SPACE_ASCII_VALUE != *inPtr)
4989 {
4990 return -EINVAL;
4991 }
4992
4993 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07004994 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004995
4996 /*no argument followed by spaces*/
4997 if ('\0' == *inPtr)
4998 {
4999 return -EINVAL;
5000 }
5001
5002 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005003 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005004 if (1 != v) return -EINVAL;
5005
Srinivas Girigowdade697412013-02-14 16:31:48 -08005006 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005007 if ((v < 0) ||
5008 (tempInt <= 0) ||
5009 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
5010 {
5011 return -EINVAL;
5012 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005013
5014 *pNumChannels = tempInt;
5015
5016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5017 "Number of channels are: %d", *pNumChannels);
5018
5019 for (j = 0; j < (*pNumChannels); j++)
5020 {
5021 /*inPtr pointing to the beginning of first space after number of channels*/
5022 inPtr = strpbrk( inPtr, " " );
5023 /*no channel list after the number of channels argument*/
5024 if (NULL == inPtr)
5025 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005026 if (0 != j)
5027 {
5028 *pNumChannels = j;
5029 return VOS_STATUS_SUCCESS;
5030 }
5031 else
5032 {
5033 return -EINVAL;
5034 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005035 }
5036
5037 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005038 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08005039
5040 /*no channel list after the number of channels argument and spaces*/
5041 if ( '\0' == *inPtr )
5042 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07005043 if (0 != j)
5044 {
5045 *pNumChannels = j;
5046 return VOS_STATUS_SUCCESS;
5047 }
5048 else
5049 {
5050 return -EINVAL;
5051 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005052 }
5053
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005054 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005055 if (1 != v) return -EINVAL;
5056
Srinivas Girigowdade697412013-02-14 16:31:48 -08005057 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07005058 if ((v < 0) ||
5059 (tempInt <= 0) ||
5060 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5061 {
5062 return -EINVAL;
5063 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08005064 pChannelList[j] = tempInt;
5065
5066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5067 "Channel %d added to preferred channel list",
5068 pChannelList[j] );
5069 }
5070
Srinivas Girigowdade697412013-02-14 16:31:48 -08005071 return VOS_STATUS_SUCCESS;
5072}
5073
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005074
5075/**---------------------------------------------------------------------------
5076
5077 \brief hdd_parse_reassoc_command_data() - HDD Parse reassoc command data
5078
5079 This function parses the reasoc command data passed in the format
5080 REASSOC<space><bssid><space><channel>
5081
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005082 \param - pValue Pointer to input data (its a NUL terminated string)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005083 \param - pTargetApBssid Pointer to target Ap bssid
5084 \param - pChannel Pointer to the Target AP channel
5085
5086 \return - 0 for success non-zero for failure
5087
5088 --------------------------------------------------------------------------*/
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005089VOS_STATUS hdd_parse_reassoc_command_data(tANI_U8 *pValue,
5090 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005091{
5092 tANI_U8 *inPtr = pValue;
5093 int tempInt;
5094 int v = 0;
5095 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08005096 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005097 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005098
5099 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5100 /*no argument after the command*/
5101 if (NULL == inPtr)
5102 {
5103 return -EINVAL;
5104 }
5105
5106 /*no space after the command*/
5107 else if (SPACE_ASCII_VALUE != *inPtr)
5108 {
5109 return -EINVAL;
5110 }
5111
5112 /*removing empty spaces*/
5113 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5114
5115 /*no argument followed by spaces*/
5116 if ('\0' == *inPtr)
5117 {
5118 return -EINVAL;
5119 }
5120
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005121 v = sscanf(inPtr, "%17s", macAddress);
5122 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005123 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5125 "Invalid MAC address or All hex inputs are not read (%d)", v);
5126 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005127 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005128
5129 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
5130 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
5131 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
5132 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
5133 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
5134 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005135
5136 /* point to the next argument */
5137 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
5138 /*no argument after the command*/
5139 if (NULL == inPtr) return -EINVAL;
5140
5141 /*removing empty spaces*/
5142 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5143
5144 /*no argument followed by spaces*/
5145 if ('\0' == *inPtr)
5146 {
5147 return -EINVAL;
5148 }
5149
5150 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08005151 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005152 if (1 != v) return -EINVAL;
5153
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005154 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005155 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05305156 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005157 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
5158 {
5159 return -EINVAL;
5160 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005161
5162 *pChannel = tempInt;
5163 return VOS_STATUS_SUCCESS;
5164}
5165
5166#endif
5167
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005168#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005169/**---------------------------------------------------------------------------
5170
5171 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
5172
5173 This function parses the SETCCKM IE command
5174 SETCCKMIE<space><ie data>
5175
5176 \param - pValue Pointer to input data
5177 \param - pCckmIe Pointer to output cckm Ie
5178 \param - pCckmIeLen Pointer to output cckm ie length
5179
5180 \return - 0 for success non-zero for failure
5181
5182 --------------------------------------------------------------------------*/
5183VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
5184 tANI_U8 *pCckmIeLen)
5185{
5186 tANI_U8 *inPtr = pValue;
5187 tANI_U8 *dataEnd;
5188 int j = 0;
5189 int i = 0;
5190 tANI_U8 tempByte = 0;
5191
5192 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
5193 /*no argument after the command*/
5194 if (NULL == inPtr)
5195 {
5196 return -EINVAL;
5197 }
5198
5199 /*no space after the command*/
5200 else if (SPACE_ASCII_VALUE != *inPtr)
5201 {
5202 return -EINVAL;
5203 }
5204
5205 /*removing empty spaces*/
5206 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
5207
5208 /*no argument followed by spaces*/
5209 if ('\0' == *inPtr)
5210 {
5211 return -EINVAL;
5212 }
5213
5214 /* find the length of data */
5215 dataEnd = inPtr;
5216 while(('\0' != *dataEnd) )
5217 {
5218 dataEnd++;
5219 ++(*pCckmIeLen);
5220 }
5221 if ( *pCckmIeLen <= 0) return -EINVAL;
5222
5223 /* Allocate the number of bytes based on the number of input characters
5224 whether it is even or odd.
5225 if the number of input characters are even, then we need N/2 byte.
5226 if the number of input characters are odd, then we need do (N+1)/2 to
5227 compensate rounding off.
5228 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
5229 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
5230 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
5231 if (NULL == *pCckmIe)
5232 {
5233 hddLog(VOS_TRACE_LEVEL_FATAL,
5234 "%s: vos_mem_alloc failed ", __func__);
5235 return -EINVAL;
5236 }
5237 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
5238 /* the buffer received from the upper layer is character buffer,
5239 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
5240 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
5241 and f0 in 3rd location */
5242 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
5243 {
5244 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
5245 (*pCckmIe)[i++] = tempByte;
5246 }
5247 *pCckmIeLen = i;
5248
5249 return VOS_STATUS_SUCCESS;
5250}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005251#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005252
Jeff Johnson295189b2012-06-20 16:38:30 -07005253/**---------------------------------------------------------------------------
5254
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07005255 \brief hdd_is_valid_mac_address() - Validate MAC address
5256
5257 This function validates whether the given MAC address is valid or not
5258 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
5259 where X is the hexa decimal digit character and separated by ':'
5260 This algorithm works even if MAC address is not separated by ':'
5261
5262 This code checks given input string mac contains exactly 12 hexadecimal digits.
5263 and a separator colon : appears in the input string only after
5264 an even number of hex digits.
5265
5266 \param - pMacAddr pointer to the input MAC address
5267 \return - 1 for valid and 0 for invalid
5268
5269 --------------------------------------------------------------------------*/
5270
5271v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
5272{
5273 int xdigit = 0;
5274 int separator = 0;
5275 while (*pMacAddr)
5276 {
5277 if (isxdigit(*pMacAddr))
5278 {
5279 xdigit++;
5280 }
5281 else if (':' == *pMacAddr)
5282 {
5283 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
5284 break;
5285
5286 ++separator;
5287 }
5288 else
5289 {
5290 separator = -1;
5291 /* Invalid MAC found */
5292 return 0;
5293 }
5294 ++pMacAddr;
5295 }
5296 return (xdigit == 12 && (separator == 5 || separator == 0));
5297}
5298
5299/**---------------------------------------------------------------------------
5300
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305301 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07005302
5303 \param - dev Pointer to net_device structure
5304
5305 \return - 0 for success non-zero for failure
5306
5307 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305308int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005309{
5310 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5311 hdd_context_t *pHddCtx;
5312 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5313 VOS_STATUS status;
5314 v_BOOL_t in_standby = TRUE;
5315
5316 if (NULL == pAdapter)
5317 {
5318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305319 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005320 return -ENODEV;
5321 }
5322
5323 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305324 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
5325 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07005326 if (NULL == pHddCtx)
5327 {
5328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005329 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005330 return -ENODEV;
5331 }
5332
5333 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5334 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5335 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005336 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5337 {
5338 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305339 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005340 in_standby = FALSE;
5341 break;
5342 }
5343 else
5344 {
5345 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5346 pAdapterNode = pNext;
5347 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005348 }
5349
5350 if (TRUE == in_standby)
5351 {
5352 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
5353 {
5354 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
5355 "wlan out of power save", __func__);
5356 return -EINVAL;
5357 }
5358 }
5359
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005360 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005361 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5362 {
5363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005364 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005365 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305366 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005367 netif_tx_start_all_queues(dev);
5368 }
5369
5370 return 0;
5371}
5372
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305373/**---------------------------------------------------------------------------
5374
5375 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
5376
5377 This is called in response to ifconfig up
5378
5379 \param - dev Pointer to net_device structure
5380
5381 \return - 0 for success non-zero for failure
5382
5383 --------------------------------------------------------------------------*/
5384int hdd_open(struct net_device *dev)
5385{
5386 int ret;
5387
5388 vos_ssr_protect(__func__);
5389 ret = __hdd_open(dev);
5390 vos_ssr_unprotect(__func__);
5391
5392 return ret;
5393}
5394
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305395int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005396{
5397 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5398
5399 if(pAdapter == NULL) {
5400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005401 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005402 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005403 }
5404
5405 netif_start_queue(dev);
5406
5407 return 0;
5408}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05305409
5410int hdd_mon_open (struct net_device *dev)
5411{
5412 int ret;
5413
5414 vos_ssr_protect(__func__);
5415 ret = __hdd_mon_open(dev);
5416 vos_ssr_unprotect(__func__);
5417
5418 return ret;
5419}
5420
Jeff Johnson295189b2012-06-20 16:38:30 -07005421/**---------------------------------------------------------------------------
5422
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305423 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07005424
5425 \param - dev Pointer to net_device structure
5426
5427 \return - 0 for success non-zero for failure
5428
5429 --------------------------------------------------------------------------*/
5430
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305431int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005432{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305433 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005434 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5435 hdd_context_t *pHddCtx;
5436 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5437 VOS_STATUS status;
5438 v_BOOL_t enter_standby = TRUE;
5439
5440 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 if (NULL == pAdapter)
5442 {
5443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05305444 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 return -ENODEV;
5446 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05305447 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305448 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305449
5450 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5451 ret = wlan_hdd_validate_context(pHddCtx);
5452 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07005453 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05305454 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 }
5456
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305457 /* Nothing to be done if the interface is not opened */
5458 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
5459 {
5460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5461 "%s: NETDEV Interface is not OPENED", __func__);
5462 return -ENODEV;
5463 }
5464
5465 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005466 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07005467 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305468
5469 /* Disable TX on the interface, after this hard_start_xmit() will not
5470 * be called on that interface
5471 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05305472 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305474
5475 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 netif_carrier_off(pAdapter->dev);
5477
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305478 /* The interface is marked as down for outside world (aka kernel)
5479 * But the driver is pretty much alive inside. The driver needs to
5480 * tear down the existing connection on the netdev (session)
5481 * cleanup the data pipes and wait until the control plane is stabilized
5482 * for this interface. The call also needs to wait until the above
5483 * mentioned actions are completed before returning to the caller.
5484 * Notice that the hdd_stop_adapter is requested not to close the session
5485 * That is intentional to be able to scan if it is a STA/P2P interface
5486 */
5487 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305488#ifdef FEATURE_WLAN_TDLS
5489 mutex_lock(&pHddCtx->tdls_lock);
5490#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305491 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05305492 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305493#ifdef FEATURE_WLAN_TDLS
5494 mutex_unlock(&pHddCtx->tdls_lock);
5495#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 /* SoftAP ifaces should never go in power save mode
5497 making sure same here. */
5498 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
5499 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07005501 )
5502 {
5503 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5505 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 EXIT();
5507 return 0;
5508 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05305509 /* Find if any iface is up. If any iface is up then can't put device to
5510 * sleep/power save mode
5511 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005512 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5513 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
5514 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005515 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
5516 {
5517 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305518 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07005519 enter_standby = FALSE;
5520 break;
5521 }
5522 else
5523 {
5524 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5525 pAdapterNode = pNext;
5526 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 }
5528
5529 if (TRUE == enter_standby)
5530 {
5531 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
5532 "entering standby", __func__);
5533 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
5534 {
5535 /*log and return success*/
5536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
5537 "wlan in power save", __func__);
5538 }
5539 }
5540
5541 EXIT();
5542 return 0;
5543}
5544
5545/**---------------------------------------------------------------------------
5546
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305547 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07005548
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305549 This is called in response to ifconfig down
5550
5551 \param - dev Pointer to net_device structure
5552
5553 \return - 0 for success non-zero for failure
5554-----------------------------------------------------------------------------*/
5555int hdd_stop (struct net_device *dev)
5556{
5557 int ret;
5558
5559 vos_ssr_protect(__func__);
5560 ret = __hdd_stop(dev);
5561 vos_ssr_unprotect(__func__);
5562
5563 return ret;
5564}
5565
5566/**---------------------------------------------------------------------------
5567
5568 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07005569
5570 \param - dev Pointer to net_device structure
5571
5572 \return - void
5573
5574 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305575static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07005576{
5577 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305578 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 ENTER();
5580
5581 do
5582 {
5583 if (NULL == pAdapter)
5584 {
5585 hddLog(VOS_TRACE_LEVEL_FATAL,
5586 "%s: NULL pAdapter", __func__);
5587 break;
5588 }
5589
5590 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
5591 {
5592 hddLog(VOS_TRACE_LEVEL_FATAL,
5593 "%s: Invalid magic", __func__);
5594 break;
5595 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305596 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5597 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07005598 {
5599 hddLog(VOS_TRACE_LEVEL_FATAL,
5600 "%s: NULL pHddCtx", __func__);
5601 break;
5602 }
5603
5604 if (dev != pAdapter->dev)
5605 {
5606 hddLog(VOS_TRACE_LEVEL_FATAL,
5607 "%s: Invalid device reference", __func__);
5608 /* we haven't validated all cases so let this go for now */
5609 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305610#ifdef FEATURE_WLAN_TDLS
5611 mutex_lock(&pHddCtx->tdls_lock);
5612#endif
c_hpothu002231a2015-02-05 14:58:51 +05305613 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05305614#ifdef FEATURE_WLAN_TDLS
5615 mutex_unlock(&pHddCtx->tdls_lock);
5616#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005617
5618 /* after uninit our adapter structure will no longer be valid */
5619 pAdapter->dev = NULL;
5620 pAdapter->magic = 0;
5621 } while (0);
5622
5623 EXIT();
5624}
5625
5626/**---------------------------------------------------------------------------
5627
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305628 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
5629
5630 This is called during the netdev unregister to uninitialize all data
5631associated with the device
5632
5633 \param - dev Pointer to net_device structure
5634
5635 \return - void
5636
5637 --------------------------------------------------------------------------*/
5638static void hdd_uninit (struct net_device *dev)
5639{
5640 vos_ssr_protect(__func__);
5641 __hdd_uninit(dev);
5642 vos_ssr_unprotect(__func__);
5643}
5644
5645/**---------------------------------------------------------------------------
5646
Jeff Johnson295189b2012-06-20 16:38:30 -07005647 \brief hdd_release_firmware() -
5648
5649 This function calls the release firmware API to free the firmware buffer.
5650
5651 \param - pFileName Pointer to the File Name.
5652 pCtx - Pointer to the adapter .
5653
5654
5655 \return - 0 for success, non zero for failure
5656
5657 --------------------------------------------------------------------------*/
5658
5659VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
5660{
5661 VOS_STATUS status = VOS_STATUS_SUCCESS;
5662 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5663 ENTER();
5664
5665
5666 if (!strcmp(WLAN_FW_FILE, pFileName)) {
5667
5668 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
5669
5670 if(pHddCtx->fw) {
5671 release_firmware(pHddCtx->fw);
5672 pHddCtx->fw = NULL;
5673 }
5674 else
5675 status = VOS_STATUS_E_FAILURE;
5676 }
5677 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
5678 if(pHddCtx->nv) {
5679 release_firmware(pHddCtx->nv);
5680 pHddCtx->nv = NULL;
5681 }
5682 else
5683 status = VOS_STATUS_E_FAILURE;
5684
5685 }
5686
5687 EXIT();
5688 return status;
5689}
5690
5691/**---------------------------------------------------------------------------
5692
5693 \brief hdd_request_firmware() -
5694
5695 This function reads the firmware file using the request firmware
5696 API and returns the the firmware data and the firmware file size.
5697
5698 \param - pfileName - Pointer to the file name.
5699 - pCtx - Pointer to the adapter .
5700 - ppfw_data - Pointer to the pointer of the firmware data.
5701 - pSize - Pointer to the file size.
5702
5703 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
5704
5705 --------------------------------------------------------------------------*/
5706
5707
5708VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
5709{
5710 int status;
5711 VOS_STATUS retval = VOS_STATUS_SUCCESS;
5712 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5713 ENTER();
5714
5715 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
5716
5717 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
5718
5719 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5720 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
5721 __func__, pfileName);
5722 retval = VOS_STATUS_E_FAILURE;
5723 }
5724
5725 else {
5726 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
5727 *pSize = pHddCtx->fw->size;
5728 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
5729 __func__, *pSize);
5730 }
5731 }
5732 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
5733
5734 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
5735
5736 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
5737 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
5738 __func__, pfileName);
5739 retval = VOS_STATUS_E_FAILURE;
5740 }
5741
5742 else {
5743 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
5744 *pSize = pHddCtx->nv->size;
5745 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
5746 __func__, *pSize);
5747 }
5748 }
5749
5750 EXIT();
5751 return retval;
5752}
5753/**---------------------------------------------------------------------------
5754 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
5755
5756 This is the function invoked by SME to inform the result of a full power
5757 request issued by HDD
5758
5759 \param - callbackcontext - Pointer to cookie
5760 status - result of request
5761
5762 \return - None
5763
5764--------------------------------------------------------------------------*/
5765void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
5766{
5767 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
5768
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005769 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005770 if(&pHddCtx->full_pwr_comp_var)
5771 {
5772 complete(&pHddCtx->full_pwr_comp_var);
5773 }
5774}
5775
5776/**---------------------------------------------------------------------------
5777
5778 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
5779
5780 This is the function invoked by SME to inform the result of BMPS
5781 request issued by HDD
5782
5783 \param - callbackcontext - Pointer to cookie
5784 status - result of request
5785
5786 \return - None
5787
5788--------------------------------------------------------------------------*/
5789void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
5790{
5791
5792 struct completion *completion_var = (struct completion*) callbackContext;
5793
Arif Hussain6d2a3322013-11-17 19:50:10 -08005794 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07005795 if(completion_var != NULL)
5796 {
5797 complete(completion_var);
5798 }
5799}
5800
5801/**---------------------------------------------------------------------------
5802
5803 \brief hdd_get_cfg_file_size() -
5804
5805 This function reads the configuration file using the request firmware
5806 API and returns the configuration file size.
5807
5808 \param - pCtx - Pointer to the adapter .
5809 - pFileName - Pointer to the file name.
5810 - pBufSize - Pointer to the buffer size.
5811
5812 \return - 0 for success, non zero for failure
5813
5814 --------------------------------------------------------------------------*/
5815
5816VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
5817{
5818 int status;
5819 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5820
5821 ENTER();
5822
5823 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5824
5825 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5826 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5827 status = VOS_STATUS_E_FAILURE;
5828 }
5829 else {
5830 *pBufSize = pHddCtx->fw->size;
5831 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
5832 release_firmware(pHddCtx->fw);
5833 pHddCtx->fw = NULL;
5834 }
5835
5836 EXIT();
5837 return VOS_STATUS_SUCCESS;
5838}
5839
5840/**---------------------------------------------------------------------------
5841
5842 \brief hdd_read_cfg_file() -
5843
5844 This function reads the configuration file using the request firmware
5845 API and returns the cfg data and the buffer size of the configuration file.
5846
5847 \param - pCtx - Pointer to the adapter .
5848 - pFileName - Pointer to the file name.
5849 - pBuffer - Pointer to the data buffer.
5850 - pBufSize - Pointer to the buffer size.
5851
5852 \return - 0 for success, non zero for failure
5853
5854 --------------------------------------------------------------------------*/
5855
5856VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
5857 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
5858{
5859 int status;
5860 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
5861
5862 ENTER();
5863
5864 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
5865
5866 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
5867 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
5868 return VOS_STATUS_E_FAILURE;
5869 }
5870 else {
5871 if(*pBufSize != pHddCtx->fw->size) {
5872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
5873 "file size", __func__);
5874 release_firmware(pHddCtx->fw);
5875 pHddCtx->fw = NULL;
5876 return VOS_STATUS_E_FAILURE;
5877 }
5878 else {
5879 if(pBuffer) {
5880 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
5881 }
5882 release_firmware(pHddCtx->fw);
5883 pHddCtx->fw = NULL;
5884 }
5885 }
5886
5887 EXIT();
5888
5889 return VOS_STATUS_SUCCESS;
5890}
5891
5892/**---------------------------------------------------------------------------
5893
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305894 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07005895
5896 This function sets the user specified mac address using
5897 the command ifconfig wlanX hw ether <mac adress>.
5898
5899 \param - dev - Pointer to the net device.
5900 - addr - Pointer to the sockaddr.
5901 \return - 0 for success, non zero for failure
5902
5903 --------------------------------------------------------------------------*/
5904
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305905static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07005906{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305907 hdd_adapter_t *pAdapter;
5908 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005909 struct sockaddr *psta_mac_addr = addr;
5910 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305911 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005912
5913 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305914 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5915 if (NULL == pAdapter)
5916 {
5917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5918 "%s: Adapter is NULL",__func__);
5919 return -EINVAL;
5920 }
5921 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5922 ret = wlan_hdd_validate_context(pHddCtx);
5923 if (0 != ret)
5924 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05305925 return ret;
5926 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005927
5928 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
5930
5931 EXIT();
5932 return halStatus;
5933}
5934
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05305935/**---------------------------------------------------------------------------
5936
5937 \brief hdd_set_mac_address() -
5938
5939 Wrapper function to protect __hdd_set_mac_address() function from ssr
5940
5941 \param - dev - Pointer to the net device.
5942 - addr - Pointer to the sockaddr.
5943 \return - 0 for success, non zero for failure
5944
5945 --------------------------------------------------------------------------*/
5946static int hdd_set_mac_address(struct net_device *dev, void *addr)
5947{
5948 int ret;
5949
5950 vos_ssr_protect(__func__);
5951 ret = __hdd_set_mac_address(dev, addr);
5952 vos_ssr_unprotect(__func__);
5953
5954 return ret;
5955}
5956
Jeff Johnson295189b2012-06-20 16:38:30 -07005957tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
5958{
5959 int i;
5960 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5961 {
Abhishek Singheb183782014-02-06 13:37:21 +05305962 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 break;
5964 }
5965
5966 if( VOS_MAX_CONCURRENCY_PERSONA == i)
5967 return NULL;
5968
5969 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
5970 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
5971}
5972
5973void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
5974{
5975 int i;
5976 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
5977 {
5978 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
5979 {
5980 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
5981 break;
5982 }
5983 }
5984 return;
5985}
5986
5987#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
5988 static struct net_device_ops wlan_drv_ops = {
5989 .ndo_open = hdd_open,
5990 .ndo_stop = hdd_stop,
5991 .ndo_uninit = hdd_uninit,
5992 .ndo_start_xmit = hdd_hard_start_xmit,
5993 .ndo_tx_timeout = hdd_tx_timeout,
5994 .ndo_get_stats = hdd_stats,
5995 .ndo_do_ioctl = hdd_ioctl,
5996 .ndo_set_mac_address = hdd_set_mac_address,
5997 .ndo_select_queue = hdd_select_queue,
5998#ifdef WLAN_FEATURE_PACKET_FILTERING
5999#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
6000 .ndo_set_rx_mode = hdd_set_multicast_list,
6001#else
6002 .ndo_set_multicast_list = hdd_set_multicast_list,
6003#endif //LINUX_VERSION_CODE
6004#endif
6005 };
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 static struct net_device_ops wlan_mon_drv_ops = {
6007 .ndo_open = hdd_mon_open,
6008 .ndo_stop = hdd_stop,
6009 .ndo_uninit = hdd_uninit,
6010 .ndo_start_xmit = hdd_mon_hard_start_xmit,
6011 .ndo_tx_timeout = hdd_tx_timeout,
6012 .ndo_get_stats = hdd_stats,
6013 .ndo_do_ioctl = hdd_ioctl,
6014 .ndo_set_mac_address = hdd_set_mac_address,
6015 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05306016
Jeff Johnson295189b2012-06-20 16:38:30 -07006017#endif
6018
6019void hdd_set_station_ops( struct net_device *pWlanDev )
6020{
6021#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07006022 pWlanDev->netdev_ops = &wlan_drv_ops;
6023#else
6024 pWlanDev->open = hdd_open;
6025 pWlanDev->stop = hdd_stop;
6026 pWlanDev->uninit = hdd_uninit;
6027 pWlanDev->hard_start_xmit = NULL;
6028 pWlanDev->tx_timeout = hdd_tx_timeout;
6029 pWlanDev->get_stats = hdd_stats;
6030 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 pWlanDev->set_mac_address = hdd_set_mac_address;
6032#endif
6033}
6034
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006035static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07006036{
6037 struct net_device *pWlanDev = NULL;
6038 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 /*
6040 * cfg80211 initialization and registration....
6041 */
6042 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, ether_setup, NUM_TX_QUEUES);
6043
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 if(pWlanDev != NULL)
6045 {
6046
6047 //Save the pointer to the net_device in the HDD adapter
6048 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
6049
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
6051
6052 pAdapter->dev = pWlanDev;
6053 pAdapter->pHddCtx = pHddCtx;
6054 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05306055 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07006056
6057 init_completion(&pAdapter->session_open_comp_var);
6058 init_completion(&pAdapter->session_close_comp_var);
6059 init_completion(&pAdapter->disconnect_comp_var);
6060 init_completion(&pAdapter->linkup_event_var);
6061 init_completion(&pAdapter->cancel_rem_on_chan_var);
6062 init_completion(&pAdapter->rem_on_chan_ready_event);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05306063 init_completion(&pAdapter->pno_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07006064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6065 init_completion(&pAdapter->offchannel_tx_event);
6066#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 init_completion(&pAdapter->tx_action_cnf_event);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006068#ifdef FEATURE_WLAN_TDLS
6069 init_completion(&pAdapter->tdls_add_station_comp);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006070 init_completion(&pAdapter->tdls_del_station_comp);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006071 init_completion(&pAdapter->tdls_mgmt_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05306072 init_completion(&pAdapter->tdls_link_establish_req_comp);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006073#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 init_completion(&pHddCtx->mc_sus_event_var);
6075 init_completion(&pHddCtx->tx_sus_event_var);
Gopichand Nakkala05621412013-06-19 19:37:38 +05306076 init_completion(&pHddCtx->rx_sus_event_var);
Jeff Johnson9efb9aa2013-03-15 13:59:27 -07006077 init_completion(&pAdapter->ula_complete);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07006078 init_completion(&pAdapter->change_country_code);
Jeff Johnson295189b2012-06-20 16:38:30 -07006079
Rajeev79dbe4c2013-10-05 11:03:42 +05306080#ifdef FEATURE_WLAN_BATCH_SCAN
6081 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
6082 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
6083 pAdapter->pBatchScanRsp = NULL;
6084 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07006085 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006086 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05306087 mutex_init(&pAdapter->hdd_batch_scan_lock);
6088#endif
6089
Jeff Johnson295189b2012-06-20 16:38:30 -07006090 pAdapter->isLinkUpSvcNeeded = FALSE;
6091 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
6092 //Init the net_device structure
6093 strlcpy(pWlanDev->name, name, IFNAMSIZ);
6094
6095 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
6096 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
6097 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
6098 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
6099
6100 hdd_set_station_ops( pAdapter->dev );
6101
6102 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006103 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
6104 pAdapter->wdev.wiphy = pHddCtx->wiphy;
6105 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006106 /* set pWlanDev's parent to underlying device */
6107 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07006108
6109 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006110 }
6111
6112 return pAdapter;
6113}
6114
6115VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
6116{
6117 struct net_device *pWlanDev = pAdapter->dev;
6118 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6119 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6120 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6121
6122 if( rtnl_lock_held )
6123 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08006124 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
6126 {
6127 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
6128 return VOS_STATUS_E_FAILURE;
6129 }
6130 }
6131 if (register_netdevice(pWlanDev))
6132 {
6133 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
6134 return VOS_STATUS_E_FAILURE;
6135 }
6136 }
6137 else
6138 {
6139 if(register_netdev(pWlanDev))
6140 {
6141 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
6142 return VOS_STATUS_E_FAILURE;
6143 }
6144 }
6145 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6146
6147 return VOS_STATUS_SUCCESS;
6148}
6149
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006150static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07006151{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006152 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07006153
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006154 if (NULL == pAdapter)
6155 {
6156 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
6157 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07006158 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006159
6160 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6161 {
6162 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
6163 return eHAL_STATUS_NOT_INITIALIZED;
6164 }
6165
6166 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
6167
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006168#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006169 /* need to make sure all of our scheduled work has completed.
6170 * This callback is called from MC thread context, so it is safe to
6171 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006172 *
6173 * Even though this is called from MC thread context, if there is a faulty
6174 * work item in the system, that can hang this call forever. So flushing
6175 * this global work queue is not safe; and now we make sure that
6176 * individual work queues are stopped correctly. But the cancel work queue
6177 * is a GPL only API, so the proprietary version of the driver would still
6178 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006179 */
6180 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07006181#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006182
6183 /* We can be blocked while waiting for scheduled work to be
6184 * flushed, and the adapter structure can potentially be freed, in
6185 * which case the magic will have been reset. So make sure the
6186 * magic is still good, and hence the adapter structure is still
6187 * valid, before signaling completion */
6188 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
6189 {
6190 complete(&pAdapter->session_close_comp_var);
6191 }
6192
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 return eHAL_STATUS_SUCCESS;
6194}
6195
6196VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
6197{
6198 struct net_device *pWlanDev = pAdapter->dev;
6199 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
6200 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
6201 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
6202 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306203 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006204
6205 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006206 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006207 //Open a SME session for future operation
6208 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07006209 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006210 if ( !HAL_STATUS_SUCCESS( halStatus ) )
6211 {
6212 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006213 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 halStatus, halStatus );
6215 status = VOS_STATUS_E_FAILURE;
6216 goto error_sme_open;
6217 }
6218
6219 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05306220 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006221 &pAdapter->session_open_comp_var,
6222 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306223 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006224 {
6225 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306226 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 status = VOS_STATUS_E_FAILURE;
6228 goto error_sme_open;
6229 }
6230
6231 // Register wireless extensions
6232 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
6233 {
6234 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006235 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 halStatus, halStatus );
6237 status = VOS_STATUS_E_FAILURE;
6238 goto error_register_wext;
6239 }
6240 //Safe to register the hard_start_xmit function again
6241#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
6242 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
6243#else
6244 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
6245#endif
6246
6247 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05306248 hddLog(VOS_TRACE_LEVEL_INFO,
6249 "%s: Set HDD connState to eConnectionState_NotConnected",
6250 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006251 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6252
6253 //Set the default operation channel
6254 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
6255
6256 /* Make the default Auth Type as OPEN*/
6257 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6258
6259 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
6260 {
6261 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006262 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006263 status, status );
6264 goto error_init_txrx;
6265 }
6266
6267 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6268
6269 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
6270 {
6271 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006272 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 status, status );
6274 goto error_wmm_init;
6275 }
6276
6277 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6278
6279 return VOS_STATUS_SUCCESS;
6280
6281error_wmm_init:
6282 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6283 hdd_deinit_tx_rx(pAdapter);
6284error_init_txrx:
6285 hdd_UnregisterWext(pWlanDev);
6286error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006287 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 {
6289 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006290 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 pAdapter->sessionId,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006292 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306294 unsigned long rc;
6295
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306297 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07006299 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306300 if (rc <= 0)
6301 hddLog(VOS_TRACE_LEVEL_ERROR,
6302 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006303 }
6304}
6305error_sme_open:
6306 return status;
6307}
6308
Jeff Johnson295189b2012-06-20 16:38:30 -07006309void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
6310{
6311 hdd_cfg80211_state_t *cfgState;
6312
6313 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
6314
6315 if( NULL != cfgState->buf )
6316 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306317 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
6319 rc = wait_for_completion_interruptible_timeout(
6320 &pAdapter->tx_action_cnf_event,
6321 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306322 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 {
Sudhir Sattayappa Kohalli8ee532d2013-02-15 13:16:26 -08006324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306325 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
6326 , __func__, rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 }
6328 }
6329 return;
6330}
Jeff Johnson295189b2012-06-20 16:38:30 -07006331
c_hpothu002231a2015-02-05 14:58:51 +05306332void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07006333{
6334 ENTER();
6335 switch ( pAdapter->device_mode )
6336 {
6337 case WLAN_HDD_INFRA_STATION:
6338 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006339 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 {
6341 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6342 {
6343 hdd_deinit_tx_rx( pAdapter );
6344 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6345 }
6346
6347 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6348 {
6349 hdd_wmm_adapter_close( pAdapter );
6350 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6351 }
6352
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 break;
6355 }
6356
6357 case WLAN_HDD_SOFTAP:
6358 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05306360
6361 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
6362 {
6363 hdd_wmm_adapter_close( pAdapter );
6364 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
6365 }
6366
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006368
c_hpothu002231a2015-02-05 14:58:51 +05306369 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 wlan_hdd_set_monitor_tx_adapter( WLAN_HDD_GET_CTX(pAdapter), NULL );
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 break;
6373 }
6374
6375 case WLAN_HDD_MONITOR:
6376 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 hdd_adapter_t* pAdapterforTx = pAdapter->sessionCtx.monitor.pAdapterForTx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006378 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
6379 {
6380 hdd_deinit_tx_rx( pAdapter );
6381 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6382 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 if(NULL != pAdapterforTx)
6384 {
6385 hdd_cleanup_actionframe(pHddCtx, pAdapterforTx);
6386 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 break;
6388 }
6389
6390
6391 default:
6392 break;
6393 }
6394
6395 EXIT();
6396}
6397
6398void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
6399{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08006400 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306401
6402 ENTER();
6403 if (NULL == pAdapter)
6404 {
6405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6406 "%s: HDD adapter is Null", __func__);
6407 return;
6408 }
6409
6410 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07006411
Rajeev79dbe4c2013-10-05 11:03:42 +05306412#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306413 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6414 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08006415 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306416 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
6417 )
6418 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006419 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05306420 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08006421 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
6422 {
6423 hdd_deinit_batch_scan(pAdapter);
6424 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306425 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08006426 }
Rajeev79dbe4c2013-10-05 11:03:42 +05306427#endif
6428
Jeff Johnson295189b2012-06-20 16:38:30 -07006429 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
6430 if( rtnl_held )
6431 {
6432 unregister_netdevice(pWlanDev);
6433 }
6434 else
6435 {
6436 unregister_netdev(pWlanDev);
6437 }
6438 // note that the pAdapter is no longer valid at this point
6439 // since the memory has been reclaimed
6440 }
6441
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05306442 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006443}
6444
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006445void hdd_set_pwrparams(hdd_context_t *pHddCtx)
6446{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306447 VOS_STATUS status;
6448 hdd_adapter_t *pAdapter = NULL;
6449 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006450
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306451 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006452
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306453 /*loop through all adapters.*/
6454 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006455 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306456 pAdapter = pAdapterNode->pAdapter;
6457 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
6458 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006459
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306460 { // we skip this registration for modes other than STA and P2P client modes.
6461 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6462 pAdapterNode = pNext;
6463 continue;
6464 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006465
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306466 //Apply Dynamic DTIM For P2P
6467 //Only if ignoreDynamicDtimInP2pMode is not set in ini
6468 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
6469 pHddCtx->cfg_ini->enableModulatedDTIM) &&
6470 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
6471 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
6472 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
6473 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
6474 (eConnectionState_Associated ==
6475 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
6476 (pHddCtx->cfg_ini->fIsBmpsEnabled))
6477 {
6478 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006479
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306480 powerRequest.uIgnoreDTIM = 1;
6481 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
6482
6483 if (pHddCtx->cfg_ini->enableModulatedDTIM)
6484 {
6485 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
6486 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
6487 }
6488 else
6489 {
6490 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
6491 }
6492
6493 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
6494 * specified during Enter/Exit BMPS when LCD off*/
6495 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6496 NULL, eANI_BOOLEAN_FALSE);
6497 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6498 NULL, eANI_BOOLEAN_FALSE);
6499
6500 /* switch to the DTIM specified in cfg.ini */
6501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6502 "Switch to DTIM %d", powerRequest.uListenInterval);
6503 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6504 break;
6505
6506 }
6507
6508 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6509 pAdapterNode = pNext;
6510 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006511}
6512
6513void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
6514{
6515 /*Switch back to DTIM 1*/
6516 tSirSetPowerParamsReq powerRequest = { 0 };
6517
6518 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
6519 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07006520 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08006521
6522 /* Update ignoreDTIM and ListedInterval in CFG with default values */
6523 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
6524 NULL, eANI_BOOLEAN_FALSE);
6525 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
6526 NULL, eANI_BOOLEAN_FALSE);
6527
6528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6529 "Switch to DTIM%d",powerRequest.uListenInterval);
6530 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
6531
6532}
6533
Jeff Johnson295189b2012-06-20 16:38:30 -07006534VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
6535{
6536 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05306537 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
6538 {
6539 hddLog( LOGE, FL("Wlan Unload in progress"));
6540 return VOS_STATUS_E_PERM;
6541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006542 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6543 {
6544 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6545 }
6546
6547 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6548 {
6549 sme_StartAutoBmpsTimer(pHddCtx->hHal);
6550 }
6551
6552 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6553 {
6554 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6555 }
6556
6557 return status;
6558}
6559
6560VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
6561{
6562 hdd_adapter_t *pAdapter = NULL;
6563 eHalStatus halStatus;
6564 VOS_STATUS status = VOS_STATUS_E_INVAL;
6565 v_BOOL_t disableBmps = FALSE;
6566 v_BOOL_t disableImps = FALSE;
6567
6568 switch(session_type)
6569 {
6570 case WLAN_HDD_INFRA_STATION:
6571 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006572 case WLAN_HDD_P2P_CLIENT:
6573 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 //Exit BMPS -> Is Sta/P2P Client is already connected
6575 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6576 if((NULL != pAdapter)&&
6577 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6578 {
6579 disableBmps = TRUE;
6580 }
6581
6582 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
6583 if((NULL != pAdapter)&&
6584 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6585 {
6586 disableBmps = TRUE;
6587 }
6588
6589 //Exit both Bmps and Imps incase of Go/SAP Mode
6590 if((WLAN_HDD_SOFTAP == session_type) ||
6591 (WLAN_HDD_P2P_GO == session_type))
6592 {
6593 disableBmps = TRUE;
6594 disableImps = TRUE;
6595 }
6596
6597 if(TRUE == disableImps)
6598 {
6599 if (pHddCtx->cfg_ini->fIsImpsEnabled)
6600 {
6601 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
6602 }
6603 }
6604
6605 if(TRUE == disableBmps)
6606 {
6607 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
6608 {
6609 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
6610
6611 if(eHAL_STATUS_SUCCESS != halStatus)
6612 {
6613 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006614 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 VOS_ASSERT(0);
6616 return status;
6617 }
6618 }
6619
6620 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
6621 {
6622 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
6623
6624 if(eHAL_STATUS_SUCCESS != halStatus)
6625 {
6626 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006627 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006628 VOS_ASSERT(0);
6629 return status;
6630 }
6631 }
6632 }
6633
6634 if((TRUE == disableBmps) ||
6635 (TRUE == disableImps))
6636 {
6637 /* Now, get the chip into Full Power now */
6638 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
6639 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
6640 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
6641
6642 if(halStatus != eHAL_STATUS_SUCCESS)
6643 {
6644 if(halStatus == eHAL_STATUS_PMC_PENDING)
6645 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306646 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006647 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306648 ret = wait_for_completion_interruptible_timeout(
6649 &pHddCtx->full_pwr_comp_var,
6650 msecs_to_jiffies(1000));
6651 if (ret <= 0)
6652 {
6653 hddLog(VOS_TRACE_LEVEL_ERROR,
6654 "%s: wait on full_pwr_comp_var failed %ld",
6655 __func__, ret);
6656 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006657 }
6658 else
6659 {
6660 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08006661 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006662 VOS_ASSERT(0);
6663 return status;
6664 }
6665 }
6666
6667 status = VOS_STATUS_SUCCESS;
6668 }
6669
6670 break;
6671 }
6672 return status;
6673}
6674
6675hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08006676 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07006677 tANI_U8 rtnl_held )
6678{
6679 hdd_adapter_t *pAdapter = NULL;
6680 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
6681 VOS_STATUS status = VOS_STATUS_E_FAILURE;
6682 VOS_STATUS exitbmpsStatus;
6683
Arif Hussain6d2a3322013-11-17 19:50:10 -08006684 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006685
Nirav Shah436658f2014-02-28 17:05:45 +05306686 if(macAddr == NULL)
6687 {
6688 /* Not received valid macAddr */
6689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6690 "%s:Unable to add virtual intf: Not able to get"
6691 "valid mac address",__func__);
6692 return NULL;
6693 }
6694
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 //Disable BMPS incase of Concurrency
6696 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
6697
6698 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
6699 {
6700 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306701 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 VOS_ASSERT(0);
6703 return NULL;
6704 }
6705
6706 switch(session_type)
6707 {
6708 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006709 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07006710 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07006711 {
6712 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6713
6714 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306715 {
6716 hddLog(VOS_TRACE_LEVEL_FATAL,
6717 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006718 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306719 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006720
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306721#ifdef FEATURE_WLAN_TDLS
6722 /* A Mutex Lock is introduced while changing/initializing the mode to
6723 * protect the concurrent access for the Adapters by TDLS module.
6724 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306725 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306726#endif
6727
Jeff Johnsone7245742012-09-05 17:12:55 -07006728 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
6729 NL80211_IFTYPE_P2P_CLIENT:
6730 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07006731
Jeff Johnson295189b2012-06-20 16:38:30 -07006732 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306733#ifdef FEATURE_WLAN_TDLS
6734 mutex_unlock(&pHddCtx->tdls_lock);
6735#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306736
6737 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 if( VOS_STATUS_SUCCESS != status )
6739 goto err_free_netdev;
6740
6741 status = hdd_register_interface( pAdapter, rtnl_held );
6742 if( VOS_STATUS_SUCCESS != status )
6743 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306744#ifdef FEATURE_WLAN_TDLS
6745 mutex_lock(&pHddCtx->tdls_lock);
6746#endif
c_hpothu002231a2015-02-05 14:58:51 +05306747 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05306748#ifdef FEATURE_WLAN_TDLS
6749 mutex_unlock(&pHddCtx->tdls_lock);
6750#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 goto err_free_netdev;
6752 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306753
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05306754 // Workqueue which gets scheduled in IPv4 notification callback.
6755 INIT_WORK(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
6756
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05306757#ifdef WLAN_NS_OFFLOAD
6758 // Workqueue which gets scheduled in IPv6 notification callback.
6759 INIT_WORK(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
6760#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006761 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 netif_tx_disable(pAdapter->dev);
6764 //netif_tx_disable(pWlanDev);
6765 netif_carrier_off(pAdapter->dev);
6766
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306767 if (WLAN_HDD_P2P_CLIENT == session_type ||
6768 WLAN_HDD_P2P_DEVICE == session_type)
6769 {
6770 /* Initialize the work queue to defer the
6771 * back to back RoC request */
6772 INIT_DELAYED_WORK(&pAdapter->roc_work,
6773 hdd_p2p_roc_work_queue);
6774 }
6775
Jeff Johnson295189b2012-06-20 16:38:30 -07006776 break;
6777 }
6778
Jeff Johnson295189b2012-06-20 16:38:30 -07006779 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006780 case WLAN_HDD_SOFTAP:
6781 {
6782 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
6783 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306784 {
6785 hddLog(VOS_TRACE_LEVEL_FATAL,
6786 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306788 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006789
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
6791 NL80211_IFTYPE_AP:
6792 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006793 pAdapter->device_mode = session_type;
6794
6795 status = hdd_init_ap_mode(pAdapter);
6796 if( VOS_STATUS_SUCCESS != status )
6797 goto err_free_netdev;
6798
6799 status = hdd_register_hostapd( pAdapter, rtnl_held );
6800 if( VOS_STATUS_SUCCESS != status )
6801 {
c_hpothu002231a2015-02-05 14:58:51 +05306802 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 goto err_free_netdev;
6804 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306805 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 netif_tx_disable(pAdapter->dev);
6807 netif_carrier_off(pAdapter->dev);
6808
6809 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05306810
6811 if (WLAN_HDD_P2P_GO == session_type)
6812 {
6813 /* Initialize the work queue to
6814 * defer the back to back RoC request */
6815 INIT_DELAYED_WORK(&pAdapter->roc_work,
6816 hdd_p2p_roc_work_queue);
6817 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 break;
6819 }
6820 case WLAN_HDD_MONITOR:
6821 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6823 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306824 {
6825 hddLog(VOS_TRACE_LEVEL_FATAL,
6826 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006827 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306828 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006829
6830 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
6831 pAdapter->device_mode = session_type;
6832 status = hdd_register_interface( pAdapter, rtnl_held );
6833#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
6834 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
6835#else
6836 pAdapter->dev->open = hdd_mon_open;
6837 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
6838#endif
6839 hdd_init_tx_rx( pAdapter );
6840 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
6841 //Set adapter to be used for data tx. It will use either GO or softap.
6842 pAdapter->sessionCtx.monitor.pAdapterForTx =
6843 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_SOFTAP);
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx)
6845 {
6846 pAdapter->sessionCtx.monitor.pAdapterForTx =
6847 hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_GO);
6848 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 /* This workqueue will be used to transmit management packet over
6850 * monitor interface. */
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006851 if (NULL == pAdapter->sessionCtx.monitor.pAdapterForTx) {
6852 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:hdd_get_adapter",__func__);
6853 return NULL;
6854 }
Madan Mohan Koyyalamudi9f40ceb2012-10-18 19:22:56 -07006855
Jeff Johnson295189b2012-06-20 16:38:30 -07006856 INIT_WORK(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue,
6857 hdd_mon_tx_work_queue);
Jeff Johnson295189b2012-06-20 16:38:30 -07006858 }
6859 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006860 case WLAN_HDD_FTM:
6861 {
6862 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
6863
6864 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306865 {
6866 hddLog(VOS_TRACE_LEVEL_FATAL,
6867 FL("failed to allocate adapter for session %d"), session_type);
6868 return NULL;
6869 }
6870
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
6872 * message while loading driver in FTM mode. */
6873 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
6874 pAdapter->device_mode = session_type;
6875 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306876
6877 hdd_init_tx_rx( pAdapter );
6878
6879 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306880 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05306881 netif_tx_disable(pAdapter->dev);
6882 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 }
6884 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006885 default:
6886 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306887 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
6888 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006889 VOS_ASSERT(0);
6890 return NULL;
6891 }
6892 }
6893
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 if( VOS_STATUS_SUCCESS == status )
6895 {
6896 //Add it to the hdd's session list.
6897 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
6898 if( NULL == pHddAdapterNode )
6899 {
6900 status = VOS_STATUS_E_NOMEM;
6901 }
6902 else
6903 {
6904 pHddAdapterNode->pAdapter = pAdapter;
6905 status = hdd_add_adapter_back ( pHddCtx,
6906 pHddAdapterNode );
6907 }
6908 }
6909
6910 if( VOS_STATUS_SUCCESS != status )
6911 {
6912 if( NULL != pAdapter )
6913 {
6914 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
6915 pAdapter = NULL;
6916 }
6917 if( NULL != pHddAdapterNode )
6918 {
6919 vos_mem_free( pHddAdapterNode );
6920 }
6921
6922 goto resume_bmps;
6923 }
6924
6925 if(VOS_STATUS_SUCCESS == status)
6926 {
6927 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
6928
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07006929 //Initialize the WoWL service
6930 if(!hdd_init_wowl(pAdapter))
6931 {
6932 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
6933 goto err_free_netdev;
6934 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006935 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006936 return pAdapter;
6937
6938err_free_netdev:
6939 free_netdev(pAdapter->dev);
6940 wlan_hdd_release_intf_addr( pHddCtx,
6941 pAdapter->macAddressCurrent.bytes );
6942
6943resume_bmps:
6944 //If bmps disabled enable it
6945 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
6946 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306947 if (pHddCtx->hdd_wlan_suspended)
6948 {
6949 hdd_set_pwrparams(pHddCtx);
6950 }
6951 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 }
6953 return NULL;
6954}
6955
6956VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
6957 tANI_U8 rtnl_held )
6958{
6959 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
6960 VOS_STATUS status;
6961
6962 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
6963 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306964 {
6965 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
6966 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07006967 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306968 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006969
6970 while ( pCurrent->pAdapter != pAdapter )
6971 {
6972 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
6973 if( VOS_STATUS_SUCCESS != status )
6974 break;
6975
6976 pCurrent = pNext;
6977 }
6978 pAdapterNode = pCurrent;
6979 if( VOS_STATUS_SUCCESS == status )
6980 {
6981 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6982 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306983
6984#ifdef FEATURE_WLAN_TDLS
6985
6986 /* A Mutex Lock is introduced while changing/initializing the mode to
6987 * protect the concurrent access for the Adapters by TDLS module.
6988 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306989 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306990#endif
6991
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 hdd_remove_adapter( pHddCtx, pAdapterNode );
6993 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006994 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006995
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306996#ifdef FEATURE_WLAN_TDLS
6997 mutex_unlock(&pHddCtx->tdls_lock);
6998#endif
6999
Jeff Johnson295189b2012-06-20 16:38:30 -07007000
7001 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05307002 if ((!vos_concurrent_open_sessions_running()) &&
7003 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
7004 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07007005 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05307006 if (pHddCtx->hdd_wlan_suspended)
7007 {
7008 hdd_set_pwrparams(pHddCtx);
7009 }
7010 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 }
7012
7013 return VOS_STATUS_SUCCESS;
7014 }
7015
7016 return VOS_STATUS_E_FAILURE;
7017}
7018
7019VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
7020{
7021 hdd_adapter_list_node_t *pHddAdapterNode;
7022 VOS_STATUS status;
7023
7024 ENTER();
7025
7026 do
7027 {
7028 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
7029 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
7030 {
7031 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
7032 vos_mem_free( pHddAdapterNode );
7033 }
7034 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
7035
7036 EXIT();
7037
7038 return VOS_STATUS_SUCCESS;
7039}
7040
7041void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
7042{
7043 v_U8_t addIE[1] = {0};
7044
7045 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7046 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
7047 eANI_BOOLEAN_FALSE) )
7048 {
7049 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007050 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 }
7052
7053 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7054 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7055 eANI_BOOLEAN_FALSE) )
7056 {
7057 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007058 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 }
7060
7061 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7062 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7063 eANI_BOOLEAN_FALSE) )
7064 {
7065 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007066 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007067 }
7068}
7069
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307070VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
7071 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07007072{
7073 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7074 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307075 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307077 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307078 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007079
Anand N Sunkad26d71b92014-12-24 18:08:22 +05307080 if (pHddCtx->isLogpInProgress) {
7081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7082 "%s:LOGP in Progress. Ignore!!!",__func__);
7083 return VOS_STATUS_E_FAILURE;
7084 }
7085
Jeff Johnson295189b2012-06-20 16:38:30 -07007086 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307087
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307088 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 switch(pAdapter->device_mode)
7090 {
7091 case WLAN_HDD_INFRA_STATION:
7092 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007093 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307094 {
7095 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7096 if( hdd_connIsConnected(pstation) ||
7097 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307099#ifdef FEATURE_WLAN_TDLS
7100 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307101 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307102 mutex_unlock(&pHddCtx->tdls_lock);
7103#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
7105 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7106 pAdapter->sessionId,
7107 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7108 else
7109 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
7110 pAdapter->sessionId,
7111 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7112 //success implies disconnect command got queued up successfully
7113 if(halStatus == eHAL_STATUS_SUCCESS)
7114 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307115 ret = wait_for_completion_interruptible_timeout(
7116 &pAdapter->disconnect_comp_var,
7117 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7118 if (ret <= 0)
7119 {
7120 hddLog(VOS_TRACE_LEVEL_ERROR,
7121 "%s: wait on disconnect_comp_var failed %ld",
7122 __func__, ret);
7123 }
7124 }
7125 else
7126 {
7127 hddLog(LOGE, "%s: failed to post disconnect event to SME",
7128 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007129 }
7130 memset(&wrqu, '\0', sizeof(wrqu));
7131 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7132 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7133 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
7134 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307135 else if(pstation->conn_info.connState ==
7136 eConnectionState_Disconnecting)
7137 {
7138 ret = wait_for_completion_interruptible_timeout(
7139 &pAdapter->disconnect_comp_var,
7140 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
7141 if (ret <= 0)
7142 {
7143 hddLog(VOS_TRACE_LEVEL_ERROR,
7144 FL("wait on disconnect_comp_var failed %ld"), ret);
7145 }
7146 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307147 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07007148 {
Kaushik, Sushant4975a572014-10-21 16:07:48 +05307149 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05307150 eCSR_SCAN_ABORT_DEFAULT);
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307152 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION)
7153 {
7154 while (pAdapter->is_roc_inprogress)
7155 {
7156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7157 "%s: ROC in progress for session %d!!!",
7158 __func__, pAdapter->sessionId);
7159 // waiting for ROC to expire
7160 msleep(500);
7161 /* In GO present case , if retry exceeds 3,
7162 it means something went wrong. */
7163 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
7164 {
7165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7166 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05307167 if (eHAL_STATUS_SUCCESS !=
7168 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
7169 pAdapter->sessionId ))
7170 {
7171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7172 FL("Failed to Cancel Remain on Channel"));
7173 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307174 wait_for_completion_interruptible_timeout(
7175 &pAdapter->cancel_rem_on_chan_var,
7176 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7177 break;
7178 }
7179 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307180#ifdef WLAN_OPEN_SOURCE
7181 cancel_delayed_work_sync(&pAdapter->roc_work);
7182#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307183 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307184#ifdef WLAN_NS_OFFLOAD
Vinay Krishna Eranna941360f2014-01-16 15:38:22 +05307185#ifdef WLAN_OPEN_SOURCE
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05307186 cancel_work_sync(&pAdapter->ipv6NotifierWorkQueue);
7187#endif
7188#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307189
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05307190#ifdef WLAN_OPEN_SOURCE
7191 cancel_work_sync(&pAdapter->ipv4NotifierWorkQueue);
7192#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05307193
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307194 /* It is possible that the caller of this function does not
7195 * wish to close the session
7196 */
7197 if (VOS_TRUE == bCloseSession &&
7198 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007199 {
7200 INIT_COMPLETION(pAdapter->session_close_comp_var);
7201 if (eHAL_STATUS_SUCCESS ==
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307202 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId,
7203 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07007204 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307205 unsigned long ret;
7206
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307208 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307209 &pAdapter->session_close_comp_var,
7210 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307211 if ( 0 >= ret)
7212 {
7213 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307214 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307215 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 }
7217 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05307218 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 break;
7220
7221 case WLAN_HDD_SOFTAP:
7222 case WLAN_HDD_P2P_GO:
7223 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307224 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
7225 while (pAdapter->is_roc_inprogress) {
7226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7227 "%s: ROC in progress for session %d!!!",
7228 __func__, pAdapter->sessionId);
7229 msleep(500);
7230 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
7231 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7232 "%s: ROC completion is not received.!!!", __func__);
7233 WLANSAP_CancelRemainOnChannel(
7234 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
7235 wait_for_completion_interruptible_timeout(
7236 &pAdapter->cancel_rem_on_chan_var,
7237 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
7238 break;
7239 }
7240 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05307241
7242#ifdef WLAN_OPEN_SOURCE
7243 cancel_delayed_work_sync(&pAdapter->roc_work);
7244#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +05307245 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007246 mutex_lock(&pHddCtx->sap_lock);
7247 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7248 {
7249 VOS_STATUS status;
7250 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7251
7252 //Stop Bss.
7253 status = WLANSAP_StopBss(pHddCtx->pvosContext);
7254 if (VOS_IS_STATUS_SUCCESS(status))
7255 {
7256 hdd_hostapd_state_t *pHostapdState =
7257 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7258
7259 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7260
7261 if (!VOS_IS_STATUS_SUCCESS(status))
7262 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307263 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
7264 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007265 }
7266 }
7267 else
7268 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007269 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007270 }
7271 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307272 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007273
7274 if (eHAL_STATUS_FAILURE ==
7275 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
7276 0, NULL, eANI_BOOLEAN_FALSE))
7277 {
7278 hddLog(LOGE,
7279 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007280 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007281 }
7282
7283 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7284 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7285 eANI_BOOLEAN_FALSE) )
7286 {
7287 hddLog(LOGE,
7288 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
7289 }
7290
7291 // Reset WNI_CFG_PROBE_RSP Flags
7292 wlan_hdd_reset_prob_rspies(pAdapter);
7293 kfree(pAdapter->sessionCtx.ap.beacon);
7294 pAdapter->sessionCtx.ap.beacon = NULL;
7295 }
7296 mutex_unlock(&pHddCtx->sap_lock);
7297 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007298
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 case WLAN_HDD_MONITOR:
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007300#ifdef WLAN_OPEN_SOURCE
7301 cancel_work_sync(&pAdapter->sessionCtx.monitor.pAdapterForTx->monTxWorkQueue);
7302#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007304
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 default:
7306 break;
7307 }
7308
7309 EXIT();
7310 return VOS_STATUS_SUCCESS;
7311}
7312
7313VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
7314{
7315 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7316 VOS_STATUS status;
7317 hdd_adapter_t *pAdapter;
7318
7319 ENTER();
7320
7321 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7322
7323 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7324 {
7325 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07007326
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307327 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007328
7329 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7330 pAdapterNode = pNext;
7331 }
7332
7333 EXIT();
7334
7335 return VOS_STATUS_SUCCESS;
7336}
7337
Rajeev Kumarf999e582014-01-09 17:33:29 -08007338
7339#ifdef FEATURE_WLAN_BATCH_SCAN
7340/**---------------------------------------------------------------------------
7341
7342 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
7343 structures
7344
7345 \param - pAdapter Pointer to HDD adapter
7346
7347 \return - None
7348
7349 --------------------------------------------------------------------------*/
7350void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
7351{
7352 tHddBatchScanRsp *pNode;
7353 tHddBatchScanRsp *pPrev;
7354
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307355 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08007356 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05307357 hddLog(VOS_TRACE_LEVEL_ERROR,
7358 "%s: Adapter context is Null", __func__);
7359 return;
7360 }
7361
7362 pNode = pAdapter->pBatchScanRsp;
7363 while (pNode)
7364 {
7365 pPrev = pNode;
7366 pNode = pNode->pNext;
7367 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08007368 }
7369
7370 pAdapter->pBatchScanRsp = NULL;
7371 pAdapter->numScanList = 0;
7372 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
7373 pAdapter->prev_batch_id = 0;
7374
7375 return;
7376}
7377#endif
7378
7379
Jeff Johnson295189b2012-06-20 16:38:30 -07007380VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
7381{
7382 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7383 VOS_STATUS status;
7384 hdd_adapter_t *pAdapter;
7385
7386 ENTER();
7387
7388 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7389
7390 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7391 {
7392 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307393 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007394 netif_tx_disable(pAdapter->dev);
7395 netif_carrier_off(pAdapter->dev);
7396
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007397 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
7398
Jeff Johnson295189b2012-06-20 16:38:30 -07007399 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05307400
7401 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
7402
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05307403 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
7404 {
7405 hdd_wmm_adapter_close( pAdapter );
7406 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
7407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007408
Siddharth Bhal2db319d2014-12-03 12:37:18 +05307409 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7410 {
7411 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7412 }
7413
Rajeev Kumarf999e582014-01-09 17:33:29 -08007414#ifdef FEATURE_WLAN_BATCH_SCAN
7415 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
7416 {
7417 hdd_deinit_batch_scan(pAdapter);
7418 }
7419#endif
7420
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307421#ifdef FEATURE_WLAN_TDLS
7422 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05307423 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05307424 mutex_unlock(&pHddCtx->tdls_lock);
7425#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7427 pAdapterNode = pNext;
7428 }
7429
7430 EXIT();
7431
7432 return VOS_STATUS_SUCCESS;
7433}
7434
7435VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
7436{
7437 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7438 VOS_STATUS status;
7439 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307440 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07007441
7442 ENTER();
7443
7444 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7445
7446 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7447 {
7448 pAdapter = pAdapterNode->pAdapter;
7449
Kumar Anand82c009f2014-05-29 00:29:42 -07007450 hdd_wmm_init( pAdapter );
7451
Jeff Johnson295189b2012-06-20 16:38:30 -07007452 switch(pAdapter->device_mode)
7453 {
7454 case WLAN_HDD_INFRA_STATION:
7455 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07007456 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307457
7458 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
7459
Jeff Johnson295189b2012-06-20 16:38:30 -07007460 hdd_init_station_mode(pAdapter);
7461 /* Open the gates for HDD to receive Wext commands */
7462 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007463 pHddCtx->scan_info.mScanPending = FALSE;
7464 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007465
7466 //Trigger the initial scan
7467 hdd_wlan_initial_scan(pAdapter);
7468
7469 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307470 if (eConnectionState_Associated == connState ||
7471 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07007472 {
7473 union iwreq_data wrqu;
7474 memset(&wrqu, '\0', sizeof(wrqu));
7475 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7476 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
7477 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07007478 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007479
Jeff Johnson295189b2012-06-20 16:38:30 -07007480 /* indicate disconnected event to nl80211 */
7481 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
7482 NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007483 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05307484 else if (eConnectionState_Connecting == connState)
7485 {
7486 /*
7487 * Indicate connect failure to supplicant if we were in the
7488 * process of connecting
7489 */
7490 cfg80211_connect_result(pAdapter->dev, NULL,
7491 NULL, 0, NULL, 0,
7492 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
7493 GFP_KERNEL);
7494 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 break;
7496
7497 case WLAN_HDD_SOFTAP:
7498 /* softAP can handle SSR */
7499 break;
7500
7501 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07007504 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 break;
7506
7507 case WLAN_HDD_MONITOR:
7508 /* monitor interface start */
7509 break;
7510 default:
7511 break;
7512 }
7513
7514 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7515 pAdapterNode = pNext;
7516 }
7517
7518 EXIT();
7519
7520 return VOS_STATUS_SUCCESS;
7521}
7522
7523VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
7524{
7525 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7526 hdd_adapter_t *pAdapter;
7527 VOS_STATUS status;
7528 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307529 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007530
7531 ENTER();
7532
7533 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7534
7535 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7536 {
7537 pAdapter = pAdapterNode->pAdapter;
7538
7539 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
7540 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
7541 {
7542 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7543 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7544
Abhishek Singhf4669da2014-05-26 15:07:49 +05307545 hddLog(VOS_TRACE_LEVEL_INFO,
7546 "%s: Set HDD connState to eConnectionState_NotConnected",
7547 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
7549 init_completion(&pAdapter->disconnect_comp_var);
7550 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
7551 eCSR_DISCONNECT_REASON_UNSPECIFIED);
7552
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307553 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07007554 &pAdapter->disconnect_comp_var,
7555 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307556 if (0 >= ret)
7557 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
7558 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07007559
7560 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
7561 pHddCtx->isAmpAllowed = VOS_FALSE;
7562 sme_RoamConnect(pHddCtx->hHal,
7563 pAdapter->sessionId, &(pWextState->roamProfile),
7564 &roamId);
7565 }
7566
7567 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7568 pAdapterNode = pNext;
7569 }
7570
7571 EXIT();
7572
7573 return VOS_STATUS_SUCCESS;
7574}
7575
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07007576void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
7577{
7578 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7579 VOS_STATUS status;
7580 hdd_adapter_t *pAdapter;
7581 hdd_station_ctx_t *pHddStaCtx;
7582 hdd_ap_ctx_t *pHddApCtx;
7583 hdd_hostapd_state_t * pHostapdState;
7584 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
7585 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
7586 const char *p2pMode = "DEV";
7587 const char *ccMode = "Standalone";
7588 int n;
7589
7590 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7591 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7592 {
7593 pAdapter = pAdapterNode->pAdapter;
7594 switch (pAdapter->device_mode) {
7595 case WLAN_HDD_INFRA_STATION:
7596 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7597 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7598 staChannel = pHddStaCtx->conn_info.operationChannel;
7599 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
7600 }
7601 break;
7602 case WLAN_HDD_P2P_CLIENT:
7603 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7604 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
7605 p2pChannel = pHddStaCtx->conn_info.operationChannel;
7606 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
7607 p2pMode = "CLI";
7608 }
7609 break;
7610 case WLAN_HDD_P2P_GO:
7611 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7612 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7613 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7614 p2pChannel = pHddApCtx->operatingChannel;
7615 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
7616 }
7617 p2pMode = "GO";
7618 break;
7619 case WLAN_HDD_SOFTAP:
7620 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7621 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7622 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
7623 apChannel = pHddApCtx->operatingChannel;
7624 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
7625 }
7626 break;
7627 default:
7628 break;
7629 }
7630 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7631 pAdapterNode = pNext;
7632 }
7633 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
7634 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
7635 }
7636 n = pr_info("wlan(%d) " MAC_ADDRESS_STR " %s",
7637 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
7638 if (p2pChannel > 0) {
7639 n += pr_info("p2p-%s(%d) " MAC_ADDRESS_STR,
7640 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
7641 }
7642 if (apChannel > 0) {
7643 n += pr_info("AP(%d) " MAC_ADDRESS_STR,
7644 apChannel, MAC_ADDR_ARRAY(apBssid));
7645 }
7646
7647 if (p2pChannel > 0 && apChannel > 0) {
7648 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
7649 }
7650}
7651
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007652bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07007653{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007654 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07007655}
7656
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007657/* Once SSR is disabled then it cannot be set. */
7658void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07007659{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07007660 if (HDD_SSR_DISABLED == isSsrRequired)
7661 return;
7662
Jeff Johnson295189b2012-06-20 16:38:30 -07007663 isSsrRequired = value;
7664}
7665
7666VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
7667 hdd_adapter_list_node_t** ppAdapterNode)
7668{
7669 VOS_STATUS status;
7670 spin_lock(&pHddCtx->hddAdapters.lock);
7671 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
7672 (hdd_list_node_t**) ppAdapterNode );
7673 spin_unlock(&pHddCtx->hddAdapters.lock);
7674 return status;
7675}
7676
7677VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
7678 hdd_adapter_list_node_t* pAdapterNode,
7679 hdd_adapter_list_node_t** pNextAdapterNode)
7680{
7681 VOS_STATUS status;
7682 spin_lock(&pHddCtx->hddAdapters.lock);
7683 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
7684 (hdd_list_node_t*) pAdapterNode,
7685 (hdd_list_node_t**)pNextAdapterNode );
7686
7687 spin_unlock(&pHddCtx->hddAdapters.lock);
7688 return status;
7689}
7690
7691VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
7692 hdd_adapter_list_node_t* pAdapterNode)
7693{
7694 VOS_STATUS status;
7695 spin_lock(&pHddCtx->hddAdapters.lock);
7696 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
7697 &pAdapterNode->node );
7698 spin_unlock(&pHddCtx->hddAdapters.lock);
7699 return status;
7700}
7701
7702VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
7703 hdd_adapter_list_node_t** ppAdapterNode)
7704{
7705 VOS_STATUS status;
7706 spin_lock(&pHddCtx->hddAdapters.lock);
7707 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
7708 (hdd_list_node_t**) ppAdapterNode );
7709 spin_unlock(&pHddCtx->hddAdapters.lock);
7710 return status;
7711}
7712
7713VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
7714 hdd_adapter_list_node_t* pAdapterNode)
7715{
7716 VOS_STATUS status;
7717 spin_lock(&pHddCtx->hddAdapters.lock);
7718 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
7719 (hdd_list_node_t*) pAdapterNode );
7720 spin_unlock(&pHddCtx->hddAdapters.lock);
7721 return status;
7722}
7723
7724VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
7725 hdd_adapter_list_node_t* pAdapterNode)
7726{
7727 VOS_STATUS status;
7728 spin_lock(&pHddCtx->hddAdapters.lock);
7729 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
7730 (hdd_list_node_t*) pAdapterNode );
7731 spin_unlock(&pHddCtx->hddAdapters.lock);
7732 return status;
7733}
7734
7735hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
7736 tSirMacAddr macAddr )
7737{
7738 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7739 hdd_adapter_t *pAdapter;
7740 VOS_STATUS status;
7741
7742 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7743
7744 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7745 {
7746 pAdapter = pAdapterNode->pAdapter;
7747
7748 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
7749 macAddr, sizeof(tSirMacAddr) ) )
7750 {
7751 return pAdapter;
7752 }
7753 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7754 pAdapterNode = pNext;
7755 }
7756
7757 return NULL;
7758
7759}
7760
7761hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
7762{
7763 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7764 hdd_adapter_t *pAdapter;
7765 VOS_STATUS status;
7766
7767 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7768
7769 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7770 {
7771 pAdapter = pAdapterNode->pAdapter;
7772
7773 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
7774 IFNAMSIZ ) )
7775 {
7776 return pAdapter;
7777 }
7778 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7779 pAdapterNode = pNext;
7780 }
7781
7782 return NULL;
7783
7784}
7785
7786hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
7787{
7788 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7789 hdd_adapter_t *pAdapter;
7790 VOS_STATUS status;
7791
7792 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7793
7794 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7795 {
7796 pAdapter = pAdapterNode->pAdapter;
7797
7798 if( pAdapter && (mode == pAdapter->device_mode) )
7799 {
7800 return pAdapter;
7801 }
7802 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7803 pAdapterNode = pNext;
7804 }
7805
7806 return NULL;
7807
7808}
7809
7810//Remove this function later
7811hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
7812{
7813 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7814 hdd_adapter_t *pAdapter;
7815 VOS_STATUS status;
7816
7817 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7818
7819 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7820 {
7821 pAdapter = pAdapterNode->pAdapter;
7822
7823 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
7824 {
7825 return pAdapter;
7826 }
7827
7828 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7829 pAdapterNode = pNext;
7830 }
7831
7832 return NULL;
7833
7834}
7835
Jeff Johnson295189b2012-06-20 16:38:30 -07007836/**---------------------------------------------------------------------------
7837
7838 \brief hdd_set_monitor_tx_adapter() -
7839
7840 This API initializes the adapter to be used while transmitting on monitor
7841 adapter.
7842
7843 \param - pHddCtx - Pointer to the HDD context.
7844 pAdapter - Adapter that will used for TX. This can be NULL.
7845 \return - None.
7846 --------------------------------------------------------------------------*/
7847void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
7848{
7849 hdd_adapter_t *pMonAdapter;
7850
7851 pMonAdapter = hdd_get_adapter( pHddCtx, WLAN_HDD_MONITOR );
7852
7853 if( NULL != pMonAdapter )
7854 {
7855 pMonAdapter->sessionCtx.monitor.pAdapterForTx = pAdapter;
7856 }
7857}
Jeff Johnson295189b2012-06-20 16:38:30 -07007858/**---------------------------------------------------------------------------
7859
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307860 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007861
7862 This API returns the operating channel of the requested device mode
7863
7864 \param - pHddCtx - Pointer to the HDD context.
7865 - mode - Device mode for which operating channel is required
7866 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
7867 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
7868 \return - channel number. "0" id the requested device is not found OR it is not connected.
7869 --------------------------------------------------------------------------*/
7870v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
7871{
7872 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7873 VOS_STATUS status;
7874 hdd_adapter_t *pAdapter;
7875 v_U8_t operatingChannel = 0;
7876
7877 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7878
7879 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
7880 {
7881 pAdapter = pAdapterNode->pAdapter;
7882
7883 if( mode == pAdapter->device_mode )
7884 {
7885 switch(pAdapter->device_mode)
7886 {
7887 case WLAN_HDD_INFRA_STATION:
7888 case WLAN_HDD_P2P_CLIENT:
7889 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
7890 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
7891 break;
7892 case WLAN_HDD_SOFTAP:
7893 case WLAN_HDD_P2P_GO:
7894 /*softap connection info */
7895 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7896 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
7897 break;
7898 default:
7899 break;
7900 }
7901
7902 break; //Found the device of interest. break the loop
7903 }
7904
7905 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7906 pAdapterNode = pNext;
7907 }
7908 return operatingChannel;
7909}
7910
7911#ifdef WLAN_FEATURE_PACKET_FILTERING
7912/**---------------------------------------------------------------------------
7913
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307914 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007915
7916 This used to set the multicast address list.
7917
7918 \param - dev - Pointer to the WLAN device.
7919 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307920 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07007921
7922 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307923static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007924{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307925 hdd_adapter_t *pAdapter;
7926 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007927 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307928 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007929 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307930
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307931 ENTER();
7932
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307933 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307934 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 {
7936 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307937 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007938 return;
7939 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307940 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7941 ret = wlan_hdd_validate_context(pHddCtx);
7942 if (0 != ret)
7943 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307944 return;
7945 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007946 if (dev->flags & IFF_ALLMULTI)
7947 {
7948 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007949 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307950 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307952 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 {
7954 mc_count = netdev_mc_count(dev);
7955 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007956 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07007957 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
7958 {
7959 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007960 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307961 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 return;
7963 }
7964
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307965 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07007966
7967 netdev_for_each_mc_addr(ha, dev) {
7968 if (i == mc_count)
7969 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307970 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
7971 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08007972 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307973 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05307974 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 i++;
7976 }
7977 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307978
7979 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 return;
7981}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307982
7983static void hdd_set_multicast_list(struct net_device *dev)
7984{
7985 vos_ssr_protect(__func__);
7986 __hdd_set_multicast_list(dev);
7987 vos_ssr_unprotect(__func__);
7988}
Jeff Johnson295189b2012-06-20 16:38:30 -07007989#endif
7990
7991/**---------------------------------------------------------------------------
7992
7993 \brief hdd_select_queue() -
7994
7995 This function is registered with the Linux OS for network
7996 core to decide which queue to use first.
7997
7998 \param - dev - Pointer to the WLAN device.
7999 - skb - Pointer to OS packet (sk_buff).
8000 \return - ac, Queue Index/access category corresponding to UP in IP header
8001
8002 --------------------------------------------------------------------------*/
8003v_U16_t hdd_select_queue(struct net_device *dev,
8004 struct sk_buff *skb)
8005{
8006 return hdd_wmm_select_queue(dev, skb);
8007}
8008
8009
8010/**---------------------------------------------------------------------------
8011
8012 \brief hdd_wlan_initial_scan() -
8013
8014 This function triggers the initial scan
8015
8016 \param - pAdapter - Pointer to the HDD adapter.
8017
8018 --------------------------------------------------------------------------*/
8019void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
8020{
8021 tCsrScanRequest scanReq;
8022 tCsrChannelInfo channelInfo;
8023 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07008024 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008025 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8026
8027 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
8028 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
8029 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
8030
8031 if(sme_Is11dSupported(pHddCtx->hHal))
8032 {
8033 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
8034 if ( HAL_STATUS_SUCCESS( halStatus ) )
8035 {
8036 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
8037 if( !scanReq.ChannelInfo.ChannelList )
8038 {
8039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
8040 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008041 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008042 return;
8043 }
8044 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
8045 channelInfo.numOfChannels);
8046 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
8047 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008048 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 }
8050
8051 scanReq.scanType = eSIR_PASSIVE_SCAN;
8052 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
8053 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
8054 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
8055 }
8056 else
8057 {
8058 scanReq.scanType = eSIR_ACTIVE_SCAN;
8059 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8060 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
8061 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
8062 }
8063
8064 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
8065 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8066 {
8067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
8068 __func__, halStatus );
8069 }
8070
8071 if(sme_Is11dSupported(pHddCtx->hHal))
8072 vos_mem_free(scanReq.ChannelInfo.ChannelList);
8073}
8074
Jeff Johnson295189b2012-06-20 16:38:30 -07008075/**---------------------------------------------------------------------------
8076
8077 \brief hdd_full_power_callback() - HDD full power callback function
8078
8079 This is the function invoked by SME to inform the result of a full power
8080 request issued by HDD
8081
8082 \param - callbackcontext - Pointer to cookie
8083 \param - status - result of request
8084
8085 \return - None
8086
8087 --------------------------------------------------------------------------*/
8088static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
8089{
Jeff Johnson72a40512013-12-19 10:14:15 -08008090 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008091
8092 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308093 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008094
8095 if (NULL == callbackContext)
8096 {
8097 hddLog(VOS_TRACE_LEVEL_ERROR,
8098 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008099 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 return;
8101 }
8102
Jeff Johnson72a40512013-12-19 10:14:15 -08008103 /* there is a race condition that exists between this callback
8104 function and the caller since the caller could time out either
8105 before or while this code is executing. we use a spinlock to
8106 serialize these actions */
8107 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008108
8109 if (POWER_CONTEXT_MAGIC != pContext->magic)
8110 {
8111 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08008112 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008113 hddLog(VOS_TRACE_LEVEL_WARN,
8114 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008115 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 return;
8117 }
8118
Jeff Johnson72a40512013-12-19 10:14:15 -08008119 /* context is valid so caller is still waiting */
8120
8121 /* paranoia: invalidate the magic */
8122 pContext->magic = 0;
8123
8124 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -07008125 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08008126
8127 /* serialization is complete */
8128 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07008129}
8130
8131/**---------------------------------------------------------------------------
8132
8133 \brief hdd_wlan_exit() - HDD WLAN exit function
8134
8135 This is the driver exit point (invoked during rmmod)
8136
8137 \param - pHddCtx - Pointer to the HDD Context
8138
8139 \return - None
8140
8141 --------------------------------------------------------------------------*/
8142void hdd_wlan_exit(hdd_context_t *pHddCtx)
8143{
8144 eHalStatus halStatus;
8145 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
8146 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +05308147 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008148 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -08008149 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008150 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +05308151 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008152
8153 ENTER();
8154
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308155#ifdef WLAN_NS_OFFLOAD
8156 hddLog(LOGE, FL("Unregister IPv6 notifier"));
8157 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
8158#endif
8159 hddLog(LOGE, FL("Unregister IPv4 notifier"));
8160 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
8161
Jeff Johnson88ba7742013-02-27 14:36:02 -08008162 if (VOS_FTM_MODE != hdd_get_conparam())
8163 {
Katya Nigamdc373382015-02-25 18:52:19 +05308164 /* This will issue a dump command which will clean up
8165 BTQM queues and unblock MC thread */
Mahesh A Saptasagar4f6d8622015-03-16 20:37:10 +05308166 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
Jeff Johnson88ba7742013-02-27 14:36:02 -08008167 // Unloading, restart logic is no more required.
8168 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -07008169
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +05308170#ifdef FEATURE_WLAN_TDLS
8171 /* At the time of driver unloading; if tdls connection is present;
8172 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
8173 * wlan_hdd_tdls_find_peer always checks for valid context;
8174 * as load/unload in progress there can be a race condition.
8175 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
8176 * when tdls state is enabled.
8177 * As soon as driver set load/unload flag; tdls flag also needs
8178 * to be disabled so that hdd_rx_packet_cbk won't call
8179 * wlan_hdd_tdls_find_peer.
8180 */
8181 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
8182#endif
8183
c_hpothu5ab05e92014-06-13 17:34:05 +05308184 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8185 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -07008186 {
c_hpothu5ab05e92014-06-13 17:34:05 +05308187 pAdapter = pAdapterNode->pAdapter;
8188 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308190 /* Disable TX on the interface, after this hard_start_xmit() will
8191 * not be called on that interface
8192 */
8193 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
8194 netif_tx_disable(pAdapter->dev);
8195
8196 /* Mark the interface status as "down" for outside world */
8197 netif_carrier_off(pAdapter->dev);
8198
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308199 /* DeInit the adapter. This ensures that all data packets
8200 * are freed.
8201 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308202#ifdef FEATURE_WLAN_TDLS
8203 mutex_lock(&pHddCtx->tdls_lock);
8204#endif
c_hpothu002231a2015-02-05 14:58:51 +05308205 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308206#ifdef FEATURE_WLAN_TDLS
8207 mutex_unlock(&pHddCtx->tdls_lock);
8208#endif
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +05308209
c_hpothu5ab05e92014-06-13 17:34:05 +05308210 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
8211 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
8212 {
8213 wlan_hdd_cfg80211_deregister_frames(pAdapter);
8214 hdd_UnregisterWext(pAdapter->dev);
8215 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308216
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308218 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8219 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -07008220 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308221 // Cancel any outstanding scan requests. We are about to close all
8222 // of our adapters, but an adapter structure is what SME passes back
8223 // to our callback function. Hence if there are any outstanding scan
8224 // requests then there is a race condition between when the adapter
8225 // is closed and when the callback is invoked.We try to resolve that
8226 // race condition here by canceling any outstanding scans before we
8227 // close the adapters.
8228 // Note that the scans may be cancelled in an asynchronous manner,
8229 // so ideally there needs to be some kind of synchronization. Rather
8230 // than introduce a new synchronization here, we will utilize the
8231 // fact that we are about to Request Full Power, and since that is
8232 // synchronized, the expectation is that by the time Request Full
8233 // Power has completed all scans will be cancelled.
8234 if (pHddCtx->scan_info.mScanPending)
8235 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +05308236 if(NULL != pAdapter)
8237 {
8238 hddLog(VOS_TRACE_LEVEL_INFO,
8239 FL("abort scan mode: %d sessionId: %d"),
8240 pAdapter->device_mode,
8241 pAdapter->sessionId);
8242 }
8243 hdd_abort_mac_scan(pHddCtx,
8244 pHddCtx->scan_info.sessionId,
8245 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308246 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008247 }
c_hpothu5ab05e92014-06-13 17:34:05 +05308248 else
Jeff Johnson88ba7742013-02-27 14:36:02 -08008249 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308250 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +05308251 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
8252 {
8253 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
8254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8255 "%s: in middle of FTM START", __func__);
8256 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
8257 msecs_to_jiffies(20000));
8258 if(!lrc)
8259 {
8260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8261 "%s: timedout on ftmStartCmpVar fatal error", __func__);
8262 }
8263 }
Jeff Johnson88ba7742013-02-27 14:36:02 -08008264 wlan_hdd_ftm_close(pHddCtx);
8265 goto free_hdd_ctx;
8266 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308267
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 /* DeRegister with platform driver as client for Suspend/Resume */
8269 vosStatus = hddDeregisterPmOps(pHddCtx);
8270 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8271 {
8272 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
8273 VOS_ASSERT(0);
8274 }
8275
8276 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
8277 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
8278 {
8279 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
8280 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008281
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07008282 //Stop the traffic monitor timer
8283 if ( VOS_TIMER_STATE_RUNNING ==
8284 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
8285 {
8286 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
8287 }
8288
8289 // Destroy the traffic monitor timer
8290 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
8291 &pHddCtx->tx_rx_trafficTmr)))
8292 {
8293 hddLog(VOS_TRACE_LEVEL_ERROR,
8294 "%s: Cannot deallocate Traffic monitor timer", __func__);
8295 }
8296
Jeff Johnson295189b2012-06-20 16:38:30 -07008297 //Disable IMPS/BMPS as we do not want the device to enter any power
8298 //save mode during shutdown
8299 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8300 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8301 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
8302
8303 //Ensure that device is in full power as we will touch H/W during vos_Stop
8304 init_completion(&powerContext.completion);
8305 powerContext.magic = POWER_CONTEXT_MAGIC;
8306
8307 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
8308 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
8309
8310 if (eHAL_STATUS_SUCCESS != halStatus)
8311 {
8312 if (eHAL_STATUS_PMC_PENDING == halStatus)
8313 {
8314 /* request was sent -- wait for the response */
8315 lrc = wait_for_completion_interruptible_timeout(
8316 &powerContext.completion,
8317 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -07008318 if (lrc <= 0)
8319 {
8320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008321 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -07008322 }
8323 }
8324 else
8325 {
8326 hddLog(VOS_TRACE_LEVEL_ERROR,
8327 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008328 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07008329 /* continue -- need to clean up as much as possible */
8330 }
8331 }
8332
Jeff Johnson72a40512013-12-19 10:14:15 -08008333 /* either we never sent a request, we sent a request and received a
8334 response or we sent a request and timed out. if we never sent a
8335 request or if we sent a request and got a response, we want to
8336 clear the magic out of paranoia. if we timed out there is a
8337 race condition such that the callback function could be
8338 executing at the same time we are. of primary concern is if the
8339 callback function had already verified the "magic" but had not
8340 yet set the completion variable when a timeout occurred. we
8341 serialize these activities by invalidating the magic while
8342 holding a shared spinlock which will cause us to block if the
8343 callback is currently executing */
8344 spin_lock(&hdd_context_lock);
8345 powerContext.magic = 0;
8346 spin_unlock(&hdd_context_lock);
8347
Yue Ma0d4891e2013-08-06 17:01:45 -07008348 hdd_debugfs_exit(pHddCtx);
8349
Jeff Johnson295189b2012-06-20 16:38:30 -07008350 // Unregister the Net Device Notifier
8351 unregister_netdevice_notifier(&hdd_netdev_notifier);
8352
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 hdd_stop_all_adapters( pHddCtx );
8354
Jeff Johnson295189b2012-06-20 16:38:30 -07008355#ifdef WLAN_BTAMP_FEATURE
8356 vosStatus = WLANBAP_Stop(pVosContext);
8357 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8358 {
8359 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8360 "%s: Failed to stop BAP",__func__);
8361 }
8362#endif //WLAN_BTAMP_FEATURE
8363
8364 //Stop all the modules
8365 vosStatus = vos_stop( pVosContext );
8366 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8367 {
8368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8369 "%s: Failed to stop VOSS",__func__);
8370 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8371 }
8372
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -07008374 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008375
8376 //Close the scheduler before calling vos_close to make sure no thread is
8377 // scheduled after the each module close is called i.e after all the data
8378 // structures are freed.
8379 vosStatus = vos_sched_close( pVosContext );
8380 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
8381 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
8382 "%s: Failed to close VOSS Scheduler",__func__);
8383 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8384 }
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008385#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07008386#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
8387 /* Destroy the wake lock */
8388 wake_lock_destroy(&pHddCtx->rx_wake_lock);
8389#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08008390 /* Destroy the wake lock */
8391 wake_lock_destroy(&pHddCtx->sap_wake_lock);
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008392#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008393
Mihir Shete7a24b5f2013-12-21 12:18:31 +05308394#ifdef CONFIG_ENABLE_LINUX_REG
8395 vosStatus = vos_nv_close();
8396 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
8397 {
8398 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
8399 "%s: Failed to close NV", __func__);
8400 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
8401 }
8402#endif
8403
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 //Close VOSS
8405 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
8406 vos_close(pVosContext);
8407
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 //Close Watchdog
8409 if(pHddCtx->cfg_ini->fIsLogpEnabled)
8410 vos_watchdog_close(pVosContext);
8411
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308412 //Clean up HDD Nlink Service
8413 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +05308414
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308415#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05308416 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05308417 {
8418 wlan_logging_sock_deactivate_svc();
8419 }
8420#endif
8421
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +05308422#ifdef WLAN_KD_READY_NOTIFIER
8423 nl_srv_exit(pHddCtx->ptt_pid);
8424#else
8425 nl_srv_exit();
8426#endif /* WLAN_KD_READY_NOTIFIER */
8427
8428
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 hdd_close_all_adapters( pHddCtx );
8430
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 /* free the power on lock from platform driver */
8432 if (free_riva_power_on_lock("wlan"))
8433 {
8434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
8435 __func__);
8436 }
8437
Jeff Johnson88ba7742013-02-27 14:36:02 -08008438free_hdd_ctx:
c_hpothu78c7b602014-05-17 17:35:49 +05308439
8440 //Free up dynamically allocated members inside HDD Adapter
8441 if (pHddCtx->cfg_ini)
8442 {
8443 kfree(pHddCtx->cfg_ini);
8444 pHddCtx->cfg_ini= NULL;
8445 }
8446
Leo Changf04ddad2013-09-18 13:46:38 -07008447 /* FTM mode, WIPHY did not registered
8448 If un-register here, system crash will happen */
8449 if (VOS_FTM_MODE != hdd_get_conparam())
8450 {
8451 wiphy_unregister(wiphy) ;
8452 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008453 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008454 if (hdd_is_ssr_required())
8455 {
8456 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -07008457 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 msleep(5000);
8459 }
8460 hdd_set_ssr_required (VOS_FALSE);
8461}
8462
8463
8464/**---------------------------------------------------------------------------
8465
8466 \brief hdd_update_config_from_nv() - Function to update the contents of
8467 the running configuration with parameters taken from NV storage
8468
8469 \param - pHddCtx - Pointer to the HDD global context
8470
8471 \return - VOS_STATUS_SUCCESS if successful
8472
8473 --------------------------------------------------------------------------*/
8474static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
8475{
Jeff Johnson295189b2012-06-20 16:38:30 -07008476 v_BOOL_t itemIsValid = VOS_FALSE;
8477 VOS_STATUS status;
8478 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
8479 v_U8_t macLoop;
8480
8481 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
8482 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
8483 if(status != VOS_STATUS_SUCCESS)
8484 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008485 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 return VOS_STATUS_E_FAILURE;
8487 }
8488
8489 if (itemIsValid == VOS_TRUE)
8490 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008491 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -07008492 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
8493 VOS_MAX_CONCURRENCY_PERSONA);
8494 if(status != VOS_STATUS_SUCCESS)
8495 {
8496 /* Get MAC from NV fail, not update CFG info
8497 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -08008498 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 return VOS_STATUS_E_FAILURE;
8500 }
8501
8502 /* If first MAC is not valid, treat all others are not valid
8503 * Then all MACs will be got from ini file */
8504 if(vos_is_macaddr_zero(&macFromNV[0]))
8505 {
8506 /* MAC address in NV file is not configured yet */
8507 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
8508 return VOS_STATUS_E_INVAL;
8509 }
8510
8511 /* Get MAC address from NV, update CFG info */
8512 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
8513 {
8514 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
8515 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308516 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -07008517 /* This MAC is not valid, skip it
8518 * This MAC will be got from ini file */
8519 }
8520 else
8521 {
8522 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
8523 (v_U8_t *)&macFromNV[macLoop].bytes[0],
8524 VOS_MAC_ADDR_SIZE);
8525 }
8526 }
8527 }
8528 else
8529 {
8530 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
8531 return VOS_STATUS_E_FAILURE;
8532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008533
Jeff Johnson295189b2012-06-20 16:38:30 -07008534
8535 return VOS_STATUS_SUCCESS;
8536}
8537
8538/**---------------------------------------------------------------------------
8539
8540 \brief hdd_post_voss_start_config() - HDD post voss start config helper
8541
8542 \param - pAdapter - Pointer to the HDD
8543
8544 \return - None
8545
8546 --------------------------------------------------------------------------*/
8547VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
8548{
8549 eHalStatus halStatus;
8550 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308551 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -07008552
Jeff Johnson295189b2012-06-20 16:38:30 -07008553
8554 // Send ready indication to the HDD. This will kick off the MAC
8555 // into a 'running' state and should kick off an initial scan.
8556 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
8557 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8558 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308559 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -07008560 "code %08d [x%08x]",__func__, halStatus, halStatus );
8561 return VOS_STATUS_E_FAILURE;
8562 }
8563
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308564 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
8566 // And RIVA will crash
8567 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
8568 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308569 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
8570 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
8571
8572
Jeff Johnson295189b2012-06-20 16:38:30 -07008573 return VOS_STATUS_SUCCESS;
8574}
8575
Jeff Johnson295189b2012-06-20 16:38:30 -07008576/* wake lock APIs for HDD */
8577void hdd_prevent_suspend(void)
8578{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008579#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 wake_lock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008581#else
8582 wcnss_prevent_suspend();
8583#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008584}
8585
8586void hdd_allow_suspend(void)
8587{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008588#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 wake_unlock(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07008590#else
8591 wcnss_allow_suspend();
8592#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008593}
8594
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308595void hdd_prevent_suspend_timeout(v_U32_t timeout)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008596{
Sameer Thalappil50dc0092013-02-19 17:23:33 -08008597#ifdef WLAN_OPEN_SOURCE
Amar Singhal6144c002013-05-03 16:11:42 -07008598 wake_lock_timeout(&wlan_wake_lock, msecs_to_jiffies(timeout));
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008599#else
8600 /* Do nothing as there is no API in wcnss for timeout*/
8601#endif
8602}
8603
Jeff Johnson295189b2012-06-20 16:38:30 -07008604/**---------------------------------------------------------------------------
8605
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008606 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
8607 information between Host and Riva
8608
8609 This function gets reported version of FW
8610 It also finds the version of Riva headers used to compile the host
8611 It compares the above two and prints a warning if they are different
8612 It gets the SW and HW version string
8613 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
8614 indicating the features they support through a bitmap
8615
8616 \param - pHddCtx - Pointer to HDD context
8617
8618 \return - void
8619
8620 --------------------------------------------------------------------------*/
8621
8622void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
8623{
8624
8625 tSirVersionType versionCompiled;
8626 tSirVersionType versionReported;
8627 tSirVersionString versionString;
8628 tANI_U8 fwFeatCapsMsgSupported = 0;
8629 VOS_STATUS vstatus;
8630
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008631 memset(&versionCompiled, 0, sizeof(versionCompiled));
8632 memset(&versionReported, 0, sizeof(versionReported));
8633
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008634 /* retrieve and display WCNSS version information */
8635 do {
8636
8637 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
8638 &versionCompiled);
8639 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8640 {
8641 hddLog(VOS_TRACE_LEVEL_FATAL,
8642 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008643 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008644 break;
8645 }
8646
8647 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
8648 &versionReported);
8649 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8650 {
8651 hddLog(VOS_TRACE_LEVEL_FATAL,
8652 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008653 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008654 break;
8655 }
8656
8657 if ((versionCompiled.major != versionReported.major) ||
8658 (versionCompiled.minor != versionReported.minor) ||
8659 (versionCompiled.version != versionReported.version) ||
8660 (versionCompiled.revision != versionReported.revision))
8661 {
8662 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
8663 "Host expected %u.%u.%u.%u\n",
8664 WLAN_MODULE_NAME,
8665 (int)versionReported.major,
8666 (int)versionReported.minor,
8667 (int)versionReported.version,
8668 (int)versionReported.revision,
8669 (int)versionCompiled.major,
8670 (int)versionCompiled.minor,
8671 (int)versionCompiled.version,
8672 (int)versionCompiled.revision);
8673 }
8674 else
8675 {
8676 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
8677 WLAN_MODULE_NAME,
8678 (int)versionReported.major,
8679 (int)versionReported.minor,
8680 (int)versionReported.version,
8681 (int)versionReported.revision);
8682 }
8683
8684 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
8685 versionString,
8686 sizeof(versionString));
8687 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8688 {
8689 hddLog(VOS_TRACE_LEVEL_FATAL,
8690 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008691 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008692 break;
8693 }
8694
8695 pr_info("%s: WCNSS software version %s\n",
8696 WLAN_MODULE_NAME, versionString);
8697
8698 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
8699 versionString,
8700 sizeof(versionString));
8701 if (!VOS_IS_STATUS_SUCCESS(vstatus))
8702 {
8703 hddLog(VOS_TRACE_LEVEL_FATAL,
8704 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008705 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008706 break;
8707 }
8708
8709 pr_info("%s: WCNSS hardware version %s\n",
8710 WLAN_MODULE_NAME, versionString);
8711
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008712 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
8713 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008714 send the message only if it the riva is 1.1
8715 minor numbers for different riva branches:
8716 0 -> (1.0)Mainline Build
8717 1 -> (1.1)Mainline Build
8718 2->(1.04) Stability Build
8719 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008720 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008721 ((versionReported.minor>=1) && (versionReported.version>=1)))
8722 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
8723 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -07008724
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008725 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -08008726 {
8727#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
8728 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
8729 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
8730#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -07008731 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
8732 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
8733 {
8734 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
8735 }
8736
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008737 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -08008738 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008739
8740 } while (0);
8741
8742}
Neelansh Mittaledafed22014-09-04 18:54:39 +05308743void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
8744{
8745 struct sk_buff *skb;
8746 struct nlmsghdr *nlh;
8747 tAniMsgHdr *ani_hdr;
8748
8749 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL);
8750
8751 if(skb == NULL) {
8752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8753 "%s: alloc_skb failed", __func__);
8754 return;
8755 }
8756
8757 nlh = (struct nlmsghdr *)skb->data;
8758 nlh->nlmsg_pid = 0; /* from kernel */
8759 nlh->nlmsg_flags = 0;
8760 nlh->nlmsg_seq = 0;
8761 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
8762
8763 ani_hdr = NLMSG_DATA(nlh);
8764 ani_hdr->type = type;
8765
8766 switch(type) {
8767 case WLAN_SVC_SAP_RESTART_IND:
8768 ani_hdr->length = 0;
8769 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
8770 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
8771 break;
8772 default:
8773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8774 "Attempt to send unknown nlink message %d", type);
8775 kfree_skb(skb);
8776 return;
8777 }
8778
8779 nl_srv_bcast(skb);
8780
8781 return;
8782}
8783
8784
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07008785
8786/**---------------------------------------------------------------------------
8787
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308788 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
8789
8790 \param - pHddCtx - Pointer to the hdd context
8791
8792 \return - true if hardware supports 5GHz
8793
8794 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308795boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308796{
8797 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
8798 * then hardware support 5Ghz.
8799 */
8800 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
8801 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308803 return true;
8804 }
8805 else
8806 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308807 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308808 __func__);
8809 return false;
8810 }
8811}
8812
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308813/**---------------------------------------------------------------------------
8814
8815 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
8816 generate function
8817
8818 This is generate the random mac address for WLAN interface
8819
8820 \param - pHddCtx - Pointer to HDD context
8821 idx - Start interface index to get auto
8822 generated mac addr.
8823 mac_addr - Mac address
8824
8825 \return - 0 for success, < 0 for failure
8826
8827 --------------------------------------------------------------------------*/
8828
8829static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
8830 int idx, v_MACADDR_t mac_addr)
8831{
8832 int i;
8833 unsigned int serialno;
8834 serialno = wcnss_get_serial_number();
8835
8836 if (0 != serialno)
8837 {
8838 /* MAC address has 3 bytes of OUI so we have a maximum of 3
8839 bytes of the serial number that can be used to generate
8840 the other 3 bytes of the MAC address. Mask off all but
8841 the lower 3 bytes (this will also make sure we don't
8842 overflow in the next step) */
8843 serialno &= 0x00FFFFFF;
8844
8845 /* we need a unique address for each session */
8846 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
8847
8848 /* autogen other Mac addresses */
8849 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8850 {
8851 /* start with the entire default address */
8852 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
8853 /* then replace the lower 3 bytes */
8854 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
8855 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
8856 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
8857
8858 serialno++;
8859 hddLog(VOS_TRACE_LEVEL_ERROR,
8860 "%s: Derived Mac Addr: "
8861 MAC_ADDRESS_STR, __func__,
8862 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
8863 }
8864
8865 }
8866 else
8867 {
8868 hddLog(LOGE, FL("Failed to Get Serial NO"));
8869 return -1;
8870 }
8871 return 0;
8872}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05308873
8874/**---------------------------------------------------------------------------
8875
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05308876 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
8877 completed to flush out the scan results
8878
8879 11d scan is done during driver load and is a passive scan on all
8880 channels supported by the device, 11d scans may find some APs on
8881 frequencies which are forbidden to be used in the regulatory domain
8882 the device is operating in. If these APs are notified to the supplicant
8883 it may try to connect to these APs, thus flush out all the scan results
8884 which are present in SME after 11d scan is done.
8885
8886 \return - eHalStatus
8887
8888 --------------------------------------------------------------------------*/
8889static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
8890 tANI_U32 scanId, eCsrScanStatus status)
8891{
8892 ENTER();
8893
8894 sme_ScanFlushResult(halHandle, 0);
8895
8896 EXIT();
8897
8898 return eHAL_STATUS_SUCCESS;
8899}
8900
8901/**---------------------------------------------------------------------------
8902
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 \brief hdd_wlan_startup() - HDD init function
8904
8905 This is the driver startup code executed once a WLAN device has been detected
8906
8907 \param - dev - Pointer to the underlying device
8908
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008909 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -07008910
8911 --------------------------------------------------------------------------*/
8912
8913int hdd_wlan_startup(struct device *dev )
8914{
8915 VOS_STATUS status;
8916 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008917 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008918 hdd_context_t *pHddCtx = NULL;
8919 v_CONTEXT_t pVosContext= NULL;
8920#ifdef WLAN_BTAMP_FEATURE
8921 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
8922 WLANBAP_ConfigType btAmpConfig;
8923 hdd_config_t *pConfig;
8924#endif
8925 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008926 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05308927 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008928
8929 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008930 /*
8931 * cfg80211: wiphy allocation
8932 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308933 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07008934
8935 if(wiphy == NULL)
8936 {
8937 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008938 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008939 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008940 pHddCtx = wiphy_priv(wiphy);
8941
Jeff Johnson295189b2012-06-20 16:38:30 -07008942 //Initialize the adapter context to zeros.
8943 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
8944
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 pHddCtx->wiphy = wiphy;
Jeff Johnson295189b2012-06-20 16:38:30 -07008946 hdd_prevent_suspend();
Mihir Shete18156292014-03-11 15:38:30 +05308947 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008948
8949 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
8950
8951 /*Get vos context here bcoz vos_open requires it*/
8952 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
8953
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -08008954 if(pVosContext == NULL)
8955 {
8956 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
8957 goto err_free_hdd_context;
8958 }
8959
Jeff Johnson295189b2012-06-20 16:38:30 -07008960 //Save the Global VOSS context in adapter context for future.
8961 pHddCtx->pvosContext = pVosContext;
8962
8963 //Save the adapter context in global context for future.
8964 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
8965
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 pHddCtx->parent_dev = dev;
8967
8968 init_completion(&pHddCtx->full_pwr_comp_var);
8969 init_completion(&pHddCtx->standby_comp_var);
8970 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008971 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008972 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +05308973 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05308974 init_completion(&pHddCtx->ssr_comp_var);
Amar Singhala49cbc52013-10-08 18:37:44 -07008975
8976#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -07008977 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -07008978#else
8979 init_completion(&pHddCtx->driver_crda_req);
8980#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008981
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308982 spin_lock_init(&pHddCtx->schedScan_lock);
8983
Jeff Johnson295189b2012-06-20 16:38:30 -07008984 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
8985
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308986#ifdef FEATURE_WLAN_TDLS
8987 /* tdls_lock is initialized before an hdd_open_adapter ( which is
8988 * invoked by other instances also) to protect the concurrent
8989 * access for the Adapters by TDLS module.
8990 */
8991 mutex_init(&pHddCtx->tdls_lock);
8992#endif
Siddharth Bhal76972212014-10-15 16:22:51 +05308993 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +05308994 mutex_init(&pHddCtx->wmmLock);
8995
Agarwal Ashish1f422872014-07-22 00:11:55 +05308996 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308997
Agarwal Ashish1f422872014-07-22 00:11:55 +05308998 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 // Load all config first as TL config is needed during vos_open
9000 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
9001 if(pHddCtx->cfg_ini == NULL)
9002 {
9003 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
9004 goto err_free_hdd_context;
9005 }
9006
9007 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
9008
9009 // Read and parse the qcom_cfg.ini file
9010 status = hdd_parse_config_ini( pHddCtx );
9011 if ( VOS_STATUS_SUCCESS != status )
9012 {
9013 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
9014 __func__, WLAN_INI_FILE);
9015 goto err_config;
9016 }
Arif Hussaind5218912013-12-05 01:10:55 -08009017#ifdef MEMORY_DEBUG
9018 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
9019 vos_mem_init();
9020
9021 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
9022 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
9023#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009024
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +05309025 /* INI has been read, initialise the configuredMcastBcastFilter with
9026 * INI value as this will serve as the default value
9027 */
9028 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
9029 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
9030 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +05309031
9032 if (false == hdd_is_5g_supported(pHddCtx))
9033 {
9034 //5Ghz is not supported.
9035 if (1 != pHddCtx->cfg_ini->nBandCapability)
9036 {
9037 hddLog(VOS_TRACE_LEVEL_INFO,
9038 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
9039 pHddCtx->cfg_ini->nBandCapability = 1;
9040 }
9041 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309042
9043 /* If SNR Monitoring is enabled, FW has to parse all beacons
9044 * for calcaluting and storing the average SNR, so set Nth beacon
9045 * filter to 1 to enable FW to parse all the beaocons
9046 */
9047 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
9048 {
9049 /* The log level is deliberately set to WARN as overriding
9050 * nthBeaconFilter to 1 will increase power cosumption and this
9051 * might just prove helpful to detect the power issue.
9052 */
9053 hddLog(VOS_TRACE_LEVEL_WARN,
9054 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
9055 pHddCtx->cfg_ini->nthBeaconFilter = 1;
9056 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009057 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309058 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -07009059 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009060 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -08009062 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
9063 {
9064 hddLog(VOS_TRACE_LEVEL_FATAL,
9065 "%s: wlan_hdd_cfg80211_init return failure", __func__);
9066 goto err_config;
9067 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009068 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009069
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009070 // Update VOS trace levels based upon the cfg.ini
9071 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
9072 pHddCtx->cfg_ini->vosTraceEnableBAP);
9073 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
9074 pHddCtx->cfg_ini->vosTraceEnableTL);
9075 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
9076 pHddCtx->cfg_ini->vosTraceEnableWDI);
9077 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
9078 pHddCtx->cfg_ini->vosTraceEnableHDD);
9079 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
9080 pHddCtx->cfg_ini->vosTraceEnableSME);
9081 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
9082 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +05309083 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
9084 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009085 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
9086 pHddCtx->cfg_ini->vosTraceEnableWDA);
9087 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
9088 pHddCtx->cfg_ini->vosTraceEnableSYS);
9089 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
9090 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009091 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
9092 pHddCtx->cfg_ini->vosTraceEnableSAP);
9093 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
9094 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -08009095
Jeff Johnson295189b2012-06-20 16:38:30 -07009096 // Update WDI trace levels based upon the cfg.ini
9097 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
9098 pHddCtx->cfg_ini->wdiTraceEnableDAL);
9099 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
9100 pHddCtx->cfg_ini->wdiTraceEnableCTL);
9101 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
9102 pHddCtx->cfg_ini->wdiTraceEnableDAT);
9103 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
9104 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009105
Jeff Johnson88ba7742013-02-27 14:36:02 -08009106 if (VOS_FTM_MODE == hdd_get_conparam())
9107 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009108 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
9109 {
9110 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
9111 goto err_free_hdd_context;
9112 }
9113 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +05309114 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +05309115 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -08009117 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009118
Jeff Johnson88ba7742013-02-27 14:36:02 -08009119 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -07009120 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9121 {
9122 status = vos_watchdog_open(pVosContext,
9123 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
9124
9125 if(!VOS_IS_STATUS_SUCCESS( status ))
9126 {
9127 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309128 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009129 }
9130 }
9131
9132 pHddCtx->isLogpInProgress = FALSE;
9133 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9134
Amar Singhala49cbc52013-10-08 18:37:44 -07009135#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009136 /* initialize the NV module. This is required so that
9137 we can initialize the channel information in wiphy
9138 from the NV.bin data. The channel information in
9139 wiphy needs to be initialized before wiphy registration */
9140
9141 status = vos_nv_open();
9142 if (!VOS_IS_STATUS_SUCCESS(status))
9143 {
9144 /* NV module cannot be initialized */
9145 hddLog( VOS_TRACE_LEVEL_FATAL,
9146 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +05309147 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -07009148 }
9149
9150 status = vos_init_wiphy_from_nv_bin();
9151 if (!VOS_IS_STATUS_SUCCESS(status))
9152 {
9153 /* NV module cannot be initialized */
9154 hddLog( VOS_TRACE_LEVEL_FATAL,
9155 "%s: vos_init_wiphy failed", __func__);
9156 goto err_vos_nv_close;
9157 }
9158
Amar Singhala49cbc52013-10-08 18:37:44 -07009159#endif
Girish Gowlibf0e1ab2015-01-19 16:05:16 +05309160 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +05309161 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009162 if ( !VOS_IS_STATUS_SUCCESS( status ))
9163 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009164 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mihir Shetee1093ba2014-01-21 20:13:32 +05309165 goto err_vos_nv_close;
Jeff Johnson295189b2012-06-20 16:38:30 -07009166 }
9167
Jeff Johnson295189b2012-06-20 16:38:30 -07009168 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
9169
9170 if ( NULL == pHddCtx->hHal )
9171 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009172 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009173 goto err_vosclose;
9174 }
9175
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009176 status = vos_preStart( pHddCtx->pvosContext );
9177 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9178 {
9179 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309180 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009181 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009182
Arif Hussaineaf68602013-12-30 23:10:44 -08009183 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
9184 {
9185 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
9186 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
9187 __func__, enable_dfs_chan_scan);
9188 }
9189 if (0 == enable_11d || 1 == enable_11d)
9190 {
9191 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
9192 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
9193 __func__, enable_11d);
9194 }
9195
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009196 /* Note that the vos_preStart() sequence triggers the cfg download.
9197 The cfg download must occur before we update the SME config
9198 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 status = hdd_set_sme_config( pHddCtx );
9200
9201 if ( VOS_STATUS_SUCCESS != status )
9202 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009203 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309204 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009205 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009206
Jeff Johnson295189b2012-06-20 16:38:30 -07009207 /* In the integrated architecture we update the configuration from
9208 the INI file and from NV before vOSS has been started so that
9209 the final contents are available to send down to the cCPU */
9210
9211 // Apply the cfg.ini to cfg.dat
9212 if (FALSE == hdd_update_config_dat(pHddCtx))
9213 {
9214 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309215 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 }
9217
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309218 // Get mac addr from platform driver
9219 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
9220
9221 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309223 /* Store the mac addr for first interface */
9224 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
9225
9226 hddLog(VOS_TRACE_LEVEL_ERROR,
9227 "%s: WLAN Mac Addr: "
9228 MAC_ADDRESS_STR, __func__,
9229 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9230
9231 /* Here, passing Arg2 as 1 because we do not want to change the
9232 last 3 bytes (means non OUI bytes) of first interface mac
9233 addr.
9234 */
9235 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
9236 {
9237 hddLog(VOS_TRACE_LEVEL_ERROR,
9238 "%s: Failed to generate wlan interface mac addr "
9239 "using MAC from ini file ", __func__);
9240 }
9241 }
9242 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
9243 {
9244 // Apply the NV to cfg.dat
9245 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -07009246#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
9247 /* There was not a valid set of MAC Addresses in NV. See if the
9248 default addresses were modified by the cfg.ini settings. If so,
9249 we'll use them, but if not, we'll autogenerate a set of MAC
9250 addresses based upon the device serial number */
9251
9252 static const v_MACADDR_t default_address =
9253 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -07009254
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309255 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
9256 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009257 {
9258 /* cfg.ini has the default address, invoke autogen logic */
9259
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309260 /* Here, passing Arg2 as 0 because we want to change the
9261 last 3 bytes (means non OUI bytes) of all the interfaces
9262 mac addr.
9263 */
9264 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
9265 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309267 hddLog(VOS_TRACE_LEVEL_ERROR,
9268 "%s: Failed to generate wlan interface mac addr "
9269 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
9270 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009272 }
9273 else
9274#endif //WLAN_AUTOGEN_MACADDR_FEATURE
9275 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009276 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 "%s: Invalid MAC address in NV, using MAC from ini file "
9278 MAC_ADDRESS_STR, __func__,
9279 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
9280 }
9281 }
9282 {
9283 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309284
9285 /* Set the MAC Address Currently this is used by HAL to
9286 * add self sta. Remove this once self sta is added as
9287 * part of session open.
9288 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009289 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
9290 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
9291 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +05309292
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 if (!HAL_STATUS_SUCCESS( halStatus ))
9294 {
9295 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
9296 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309297 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 }
9299 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009300
9301 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
9302 Note: Firmware image will be read and downloaded inside vos_start API */
9303 status = vos_start( pHddCtx->pvosContext );
9304 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9305 {
9306 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309307 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 }
9309
Leo Chang6cec3e22014-01-21 15:33:49 -08009310#ifdef FEATURE_WLAN_CH_AVOID
9311 /* Plug in avoid channel notification callback
9312 * This should happen before ADD_SELF_STA
9313 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +05309314
9315 /* check the Channel Avoidance is enabled */
9316 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
9317 {
9318 sme_AddChAvoidCallback(pHddCtx->hHal,
9319 hdd_hostapd_ch_avoid_cb);
9320 }
Leo Chang6cec3e22014-01-21 15:33:49 -08009321#endif /* FEATURE_WLAN_CH_AVOID */
9322
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -07009323 /* Exchange capability info between Host and FW and also get versioning info from FW */
9324 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009325
Agarwal Ashishad9281b2014-06-10 14:57:30 +05309326#ifdef CONFIG_ENABLE_LINUX_REG
9327 status = wlan_hdd_init_channels(pHddCtx);
9328 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9329 {
9330 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
9331 __func__);
9332 goto err_vosstop;
9333 }
9334#endif
9335
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 status = hdd_post_voss_start_config( pHddCtx );
9337 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9338 {
9339 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
9340 __func__);
9341 goto err_vosstop;
9342 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009343
9344#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309345 wlan_hdd_cfg80211_update_reg_info( wiphy );
9346
9347 /* registration of wiphy dev with cfg80211 */
9348 if (0 > wlan_hdd_cfg80211_register(wiphy))
9349 {
9350 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9351 goto err_vosstop;
9352 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009353#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009354
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309355#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309356 /* registration of wiphy dev with cfg80211 */
9357 if (0 > wlan_hdd_cfg80211_register(wiphy))
9358 {
9359 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9360 goto err_vosstop;
9361 }
9362
Agarwal Ashish6db9d532014-09-30 18:19:10 +05309363 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309364 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9365 {
9366 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
9367 __func__);
9368 goto err_unregister_wiphy;
9369 }
9370#endif
9371
c_hpothu4a298be2014-12-22 21:12:51 +05309372 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
9373
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 if (VOS_STA_SAP_MODE == hdd_get_conparam())
9375 {
9376 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
9377 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9378 }
9379 else
9380 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
9382 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
9383 if (pAdapter != NULL)
9384 {
Katya Nigama7d81d72014-11-12 12:44:34 +05309385 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309387 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
9388 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
9389 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -07009390
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309391 /* Generate the P2P Device Address. This consists of the device's
9392 * primary MAC address with the locally administered bit set.
9393 */
9394 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -07009395 }
9396 else
9397 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +05309398 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
9399 if (p2p_dev_addr != NULL)
9400 {
9401 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
9402 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
9403 }
9404 else
9405 {
9406 hddLog(VOS_TRACE_LEVEL_FATAL,
9407 "%s: Failed to allocate mac_address for p2p_device",
9408 __func__);
9409 goto err_close_adapter;
9410 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009412
9413 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
9414 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
9415 if ( NULL == pP2pAdapter )
9416 {
9417 hddLog(VOS_TRACE_LEVEL_FATAL,
9418 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009419 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009420 goto err_close_adapter;
9421 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009422 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009424
9425 if( pAdapter == NULL )
9426 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
9428 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009430
Arif Hussain66559122013-11-21 10:11:40 -08009431 if (country_code)
9432 {
9433 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -08009434 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -08009435 hdd_checkandupdate_dfssetting(pAdapter, country_code);
9436#ifndef CONFIG_ENABLE_LINUX_REG
9437 hdd_checkandupdate_phymode(pAdapter, country_code);
9438#endif
Arif Hussaineaf68602013-12-30 23:10:44 -08009439 ret = sme_ChangeCountryCode(pHddCtx->hHal,
9440 (void *)(tSmeChangeCountryCallback)
9441 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -08009442 country_code,
9443 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309444 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -08009445 if (eHAL_STATUS_SUCCESS == ret)
9446 {
Arif Hussaincb607082013-12-20 11:57:42 -08009447 ret = wait_for_completion_interruptible_timeout(
9448 &pAdapter->change_country_code,
9449 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
9450
9451 if (0 >= ret)
9452 {
9453 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9454 "%s: SME while setting country code timed out", __func__);
9455 }
Arif Hussain66559122013-11-21 10:11:40 -08009456 }
9457 else
9458 {
Arif Hussaincb607082013-12-20 11:57:42 -08009459 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9460 "%s: SME Change Country code from module param fail ret=%d",
9461 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -08009462 }
9463 }
9464
Jeff Johnson295189b2012-06-20 16:38:30 -07009465#ifdef WLAN_BTAMP_FEATURE
9466 vStatus = WLANBAP_Open(pVosContext);
9467 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9468 {
9469 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9470 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07009471 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 }
9473
9474 vStatus = BSL_Init(pVosContext);
9475 if(!VOS_IS_STATUS_SUCCESS(vStatus))
9476 {
9477 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9478 "%s: Failed to Init BSL",__func__);
9479 goto err_bap_close;
9480 }
9481 vStatus = WLANBAP_Start(pVosContext);
9482 if (!VOS_IS_STATUS_SUCCESS(vStatus))
9483 {
9484 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9485 "%s: Failed to start TL",__func__);
9486 goto err_bap_close;
9487 }
9488
9489 pConfig = pHddCtx->cfg_ini;
9490 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
9491 status = WLANBAP_SetConfig(&btAmpConfig);
9492
9493#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -07009494
Mihir Shete9c238772014-10-15 14:35:16 +05309495 /*
9496 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
9497 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
9498 * which is greater than 0xf. So the below check is safe to make
9499 * sure that there is no entry for UapsdMask in the ini
9500 */
9501 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
9502 {
9503 if(IS_DYNAMIC_WMM_PS_ENABLED)
9504 {
9505 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
9506 __func__);
9507 pHddCtx->cfg_ini->UapsdMask =
9508 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
9509 }
9510 else
9511 {
9512 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
9513 __func__);
9514 pHddCtx->cfg_ini->UapsdMask =
9515 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
9516 }
9517 }
9518
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -07009519#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
9520 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
9521 {
9522 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
9523 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
9524 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
9525 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
9526 }
9527#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009528
Agarwal Ashish4b87f922014-06-18 03:03:21 +05309529 wlan_hdd_tdls_init(pHddCtx);
9530
Mihir Shetefc7ff5b2014-01-27 11:30:05 +05309531 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
9532
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 /* Register with platform driver as client for Suspend/Resume */
9534 status = hddRegisterPmOps(pHddCtx);
9535 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9536 {
9537 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
9538#ifdef WLAN_BTAMP_FEATURE
9539 goto err_bap_stop;
9540#else
Jeff Johnsone7245742012-09-05 17:12:55 -07009541 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009542#endif //WLAN_BTAMP_FEATURE
9543 }
9544
Yue Ma0d4891e2013-08-06 17:01:45 -07009545 /* Open debugfs interface */
9546 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
9547 {
9548 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
9549 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -07009550 }
9551
Jeff Johnson295189b2012-06-20 16:38:30 -07009552 /* Register TM level change handler function to the platform */
9553 status = hddDevTmRegisterNotifyCallback(pHddCtx);
9554 if ( !VOS_IS_STATUS_SUCCESS( status ) )
9555 {
9556 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
9557 goto err_unregister_pmops;
9558 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009559
9560 /* register for riva power on lock to platform driver */
9561 if (req_riva_power_on_lock("wlan"))
9562 {
9563 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
9564 __func__);
9565 goto err_unregister_pmops;
9566 }
9567
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 // register net device notifier for device change notification
9569 ret = register_netdevice_notifier(&hdd_netdev_notifier);
9570
9571 if(ret < 0)
9572 {
9573 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
9574 goto err_free_power_on_lock;
9575 }
9576
9577 //Initialize the nlink service
9578 if(nl_srv_init() != 0)
9579 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309580 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 goto err_reg_netdev;
9582 }
9583
Leo Chang4ce1cc52013-10-21 18:27:15 -07009584#ifdef WLAN_KD_READY_NOTIFIER
9585 pHddCtx->kd_nl_init = 1;
9586#endif /* WLAN_KD_READY_NOTIFIER */
9587
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 //Initialize the BTC service
9589 if(btc_activate_service(pHddCtx) != 0)
9590 {
9591 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
9592 goto err_nl_srv;
9593 }
9594
9595#ifdef PTT_SOCK_SVC_ENABLE
9596 //Initialize the PTT service
9597 if(ptt_sock_activate_svc(pHddCtx) != 0)
9598 {
9599 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
9600 goto err_nl_srv;
9601 }
9602#endif
9603
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309604#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9605 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
9606 {
Deepthi Gowri78083a32014-11-04 12:55:51 +05309607 if(wlan_logging_sock_activate_svc(
9608 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
9609 pHddCtx->cfg_ini->wlanLoggingNumBuf))
9610 {
9611 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
9612 " failed", __func__);
9613 goto err_nl_srv;
9614 }
9615 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
9616 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +05309617 if (!pHddCtx->cfg_ini->gEnableDebugLog)
9618 pHddCtx->cfg_ini->gEnableDebugLog =
9619 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +05309620 }
9621#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -07009625 /* Action frame registered in one adapter which will
9626 * applicable to all interfaces
9627 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309628 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009629 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009630
9631 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +05309632 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009633
Jeff Johnson295189b2012-06-20 16:38:30 -07009634
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009635#ifdef WLAN_OPEN_SOURCE
Jeff Johnsone7245742012-09-05 17:12:55 -07009636#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
9637 /* Initialize the wake lcok */
9638 wake_lock_init(&pHddCtx->rx_wake_lock,
9639 WAKE_LOCK_SUSPEND,
9640 "qcom_rx_wakelock");
9641#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -08009642 /* Initialize the wake lcok */
9643 wake_lock_init(&pHddCtx->sap_wake_lock,
9644 WAKE_LOCK_SUSPEND,
9645 "qcom_sap_wakelock");
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009646#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009647
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009648 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
9649 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -07009650
Katya Nigam5c306ea2014-06-19 15:39:54 +05309651 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
9653 hdd_allow_suspend();
Katya Nigam5c306ea2014-06-19 15:39:54 +05309654
9655#ifdef FEATURE_WLAN_SCAN_PNO
9656 /*SME must send channel update configuration to RIVA*/
9657 sme_UpdateChannelConfig(pHddCtx->hHal);
9658#endif
Abhishek Singhf644b272014-08-21 02:59:39 +05309659 /* Send the update default channel list to the FW*/
9660 sme_UpdateChannelList(pHddCtx->hHal);
Abhishek Singha306a442013-11-07 18:39:01 +05309661#ifndef CONFIG_ENABLE_LINUX_REG
9662 /*updating wiphy so that regulatory user hints can be processed*/
9663 if (wiphy)
9664 {
9665 regulatory_hint(wiphy, "00");
9666 }
9667#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009668 // Initialize the restart logic
9669 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +05309670
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07009671 //Register the traffic monitor timer now
9672 if ( pHddCtx->cfg_ini->dynSplitscan)
9673 {
9674 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
9675 VOS_TIMER_TYPE_SW,
9676 hdd_tx_rx_pkt_cnt_stat_timer_handler,
9677 (void *)pHddCtx);
9678 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05309679#ifdef WLAN_FEATURE_EXTSCAN
9680 sme_EXTScanRegisterCallback(pHddCtx->hHal,
9681 wlan_hdd_cfg80211_extscan_callback,
9682 pHddCtx);
9683#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309684
9685#ifdef WLAN_NS_OFFLOAD
9686 // Register IPv6 notifier to notify if any change in IP
9687 // So that we can reconfigure the offload parameters
9688 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
9689 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
9690 if (ret)
9691 {
9692 hddLog(LOGE, FL("Failed to register IPv6 notifier"));
9693 }
9694 else
9695 {
9696 hddLog(LOGE, FL("Registered IPv6 notifier"));
9697 }
9698#endif
9699
9700 // Register IPv4 notifier to notify if any change in IP
9701 // So that we can reconfigure the offload parameters
9702 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
9703 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
9704 if (ret)
9705 {
9706 hddLog(LOGE, FL("Failed to register IPv4 notifier"));
9707 }
9708 else
9709 {
9710 hddLog(LOGE, FL("Registered IPv4 notifier"));
9711 }
9712
Jeff Johnson295189b2012-06-20 16:38:30 -07009713 goto success;
9714
9715err_nl_srv:
Leo Chang59cdc7e2013-07-10 10:08:21 -07009716#ifdef WLAN_KD_READY_NOTIFIER
9717 nl_srv_exit(pHddCtx->ptt_pid);
9718#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009719 nl_srv_exit();
Leo Chang59cdc7e2013-07-10 10:08:21 -07009720#endif /* WLAN_KD_READY_NOTIFIER */
Jeff Johnson295189b2012-06-20 16:38:30 -07009721err_reg_netdev:
9722 unregister_netdevice_notifier(&hdd_netdev_notifier);
9723
9724err_free_power_on_lock:
9725 free_riva_power_on_lock("wlan");
9726
9727err_unregister_pmops:
9728 hddDevTmUnregisterNotifyCallback(pHddCtx);
9729 hddDeregisterPmOps(pHddCtx);
9730
Yue Ma0d4891e2013-08-06 17:01:45 -07009731 hdd_debugfs_exit(pHddCtx);
9732
Jeff Johnson295189b2012-06-20 16:38:30 -07009733#ifdef WLAN_BTAMP_FEATURE
9734err_bap_stop:
9735 WLANBAP_Stop(pVosContext);
9736#endif
9737
9738#ifdef WLAN_BTAMP_FEATURE
9739err_bap_close:
9740 WLANBAP_Close(pVosContext);
9741#endif
9742
Jeff Johnson295189b2012-06-20 16:38:30 -07009743err_close_adapter:
9744 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309745#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +05309746err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +05309747#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309748 wiphy_unregister(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009749err_vosstop:
9750 vos_stop(pVosContext);
9751
Amar Singhala49cbc52013-10-08 18:37:44 -07009752err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 status = vos_sched_close( pVosContext );
9754 if (!VOS_IS_STATUS_SUCCESS(status)) {
9755 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
9756 "%s: Failed to close VOSS Scheduler", __func__);
9757 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
9758 }
Amar Singhala49cbc52013-10-08 18:37:44 -07009759 vos_close(pVosContext );
9760
Amar Singhal0a402232013-10-11 20:57:16 -07009761err_vos_nv_close:
9762
c_hpothue6a36282014-03-19 12:27:38 +05309763#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009764 vos_nv_close();
9765
c_hpothu70f8d812014-03-22 22:59:23 +05309766#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009767
9768err_wdclose:
9769 if(pHddCtx->cfg_ini->fIsLogpEnabled)
9770 vos_watchdog_close(pVosContext);
9771
Jeff Johnson295189b2012-06-20 16:38:30 -07009772err_config:
9773 kfree(pHddCtx->cfg_ini);
9774 pHddCtx->cfg_ini= NULL;
9775
9776err_free_hdd_context:
9777 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 wiphy_free(wiphy) ;
9779 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -07009780 VOS_BUG(1);
9781
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -08009782 if (hdd_is_ssr_required())
9783 {
9784 /* WDI timeout had happened during load, so SSR is needed here */
9785 subsystem_restart("wcnss");
9786 msleep(5000);
9787 }
9788 hdd_set_ssr_required (VOS_FALSE);
9789
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08009790 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009791
9792success:
9793 EXIT();
9794 return 0;
9795}
9796
9797/**---------------------------------------------------------------------------
9798
Jeff Johnson32d95a32012-09-10 13:15:23 -07009799 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -07009800
Jeff Johnson32d95a32012-09-10 13:15:23 -07009801 This is the driver entry point - called in different timeline depending
9802 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -07009803
9804 \param - None
9805
9806 \return - 0 for success, non zero for failure
9807
9808 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -07009809static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009810{
9811 VOS_STATUS status;
9812 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009813 struct device *dev = NULL;
9814 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009815#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9816 int max_retries = 0;
9817#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309818#ifdef HAVE_CBC_DONE
9819 int max_cbc_retries = 0;
9820#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009821
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309822#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9823 wlan_logging_sock_init_svc();
9824#endif
9825
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 ENTER();
9827
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009828#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 wake_lock_init(&wlan_wake_lock, WAKE_LOCK_SUSPEND, "wlan");
Jeff Johnsone7245742012-09-05 17:12:55 -07009830#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009831
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309832 hddTraceInit();
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
9834 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
9835
Jeff Johnson295189b2012-06-20 16:38:30 -07009836#ifdef ANI_BUS_TYPE_PCI
9837
9838 dev = wcnss_wlan_get_device();
9839
9840#endif // ANI_BUS_TYPE_PCI
9841
9842#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009843
9844#ifdef HAVE_WCNSS_CAL_DOWNLOAD
9845 /* wait until WCNSS driver downloads NV */
9846 while (!wcnss_device_ready() && 5 >= ++max_retries) {
9847 msleep(1000);
9848 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309849
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009850 if (max_retries >= 5) {
9851 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
madan mohan koyyalamudi8c96ce12013-07-10 19:14:39 +05309852#ifdef WLAN_OPEN_SOURCE
9853 wake_lock_destroy(&wlan_wake_lock);
9854#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309855
9856#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9857 wlan_logging_sock_deinit_svc();
9858#endif
9859
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -07009860 return -ENODEV;
9861 }
9862#endif
9863
Siddharth Bhalc7e79b62014-10-10 22:37:38 +05309864#ifdef HAVE_CBC_DONE
9865 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
9866 msleep(1000);
9867 }
9868 if (max_cbc_retries >= 10) {
9869 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
9870 }
9871#endif
9872
Jeff Johnson295189b2012-06-20 16:38:30 -07009873 dev = wcnss_wlan_get_device();
9874#endif // ANI_BUS_TYPE_PLATFORM
9875
9876
9877 do {
9878 if (NULL == dev) {
9879 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
9880 ret_status = -1;
9881 break;
9882 }
9883
Jeff Johnson295189b2012-06-20 16:38:30 -07009884#ifdef TIMER_MANAGER
9885 vos_timer_manager_init();
9886#endif
9887
9888 /* Preopen VOSS so that it is ready to start at least SAL */
9889 status = vos_preOpen(&pVosContext);
9890
9891 if (!VOS_IS_STATUS_SUCCESS(status))
9892 {
9893 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
9894 ret_status = -1;
9895 break;
9896 }
9897
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009898#ifndef MODULE
9899 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
9900 */
9901 hdd_set_conparam((v_UINT_t)con_mode);
9902#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009903
9904 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009905 if (hdd_wlan_startup(dev))
9906 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -08009908 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009909 vos_preClose( &pVosContext );
9910 ret_status = -1;
9911 break;
9912 }
9913
Jeff Johnson295189b2012-06-20 16:38:30 -07009914 } while (0);
9915
9916 if (0 != ret_status)
9917 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009918#ifdef TIMER_MANAGER
9919 vos_timer_exit();
9920#endif
9921#ifdef MEMORY_DEBUG
9922 vos_mem_exit();
9923#endif
9924
Sameer Thalappil50dc0092013-02-19 17:23:33 -08009925#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -07009926 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -07009927#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +05309928
9929#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9930 wlan_logging_sock_deinit_svc();
9931#endif
9932
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
9934 }
9935 else
9936 {
9937 //Send WLAN UP indication to Nlink Service
9938 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
9939
9940 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 }
9942
9943 EXIT();
9944
9945 return ret_status;
9946}
9947
Jeff Johnson32d95a32012-09-10 13:15:23 -07009948/**---------------------------------------------------------------------------
9949
9950 \brief hdd_module_init() - Init Function
9951
9952 This is the driver entry point (invoked when module is loaded using insmod)
9953
9954 \param - None
9955
9956 \return - 0 for success, non zero for failure
9957
9958 --------------------------------------------------------------------------*/
9959#ifdef MODULE
9960static int __init hdd_module_init ( void)
9961{
9962 return hdd_driver_init();
9963}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009964#else /* #ifdef MODULE */
9965static int __init hdd_module_init ( void)
9966{
9967 /* Driver initialization is delayed to fwpath_changed_handler */
9968 return 0;
9969}
Jeff Johnson32d95a32012-09-10 13:15:23 -07009970#endif /* #ifdef MODULE */
9971
Jeff Johnson295189b2012-06-20 16:38:30 -07009972
9973/**---------------------------------------------------------------------------
9974
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009975 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -07009976
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009977 This is the driver exit point (invoked when module is unloaded using rmmod
9978 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -07009979
9980 \param - None
9981
9982 \return - None
9983
9984 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -07009985static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009986{
9987 hdd_context_t *pHddCtx = NULL;
9988 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +05309989 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +05309990 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009991
9992 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
9993
9994 //Get the global vos context
9995 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
9996
9997 if(!pVosContext)
9998 {
9999 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
10000 goto done;
10001 }
10002
10003 //Get the HDD context.
10004 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
10005
10006 if(!pHddCtx)
10007 {
10008 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
10009 }
10010 else
10011 {
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010012 INIT_COMPLETION(pHddCtx->ssr_comp_var);
10013 if ((pHddCtx->isLogpInProgress) && (FALSE ==
10014 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
10015 {
Siddharth Bhala204f572015-01-17 02:03:36 +053010016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010017 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053010018 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
10019 msecs_to_jiffies(30000));
10020 if(!rc)
10021 {
10022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10023 "%s:SSR timedout, fatal error", __func__);
10024 VOS_BUG(0);
10025 }
10026 }
10027
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010028 rtnl_lock();
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053010029 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
10030 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010031 rtnl_unlock();
Jeff Johnson295189b2012-06-20 16:38:30 -070010032
c_hpothu8adb97b2014-12-08 19:38:20 +053010033 /* Driver Need to send country code 00 in below condition
10034 * 1) If gCountryCodePriority is set to 1; and last country
10035 * code set is through 11d. This needs to be done in case
10036 * when NV country code is 00.
10037 * This Needs to be done as when kernel store last country
10038 * code and if stored country code is not through 11d,
10039 * in sme_HandleChangeCountryCodeByUser we will disable 11d
10040 * in next load/unload as soon as we get any country through
10041 * 11d. In sme_HandleChangeCountryCodeByUser
10042 * pMsg->countryCode will be last countryCode and
10043 * pMac->scan.countryCode11d will be country through 11d so
10044 * due to mismatch driver will disable 11d.
10045 *
10046 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053010047
c_hpothu8adb97b2014-12-08 19:38:20 +053010048 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010049 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053010050 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053010051 {
10052 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053010053 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053010054 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
10055 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053010056
c_hpothu8adb97b2014-12-08 19:38:20 +053010057 //Do all the cleanup before deregistering the driver
10058 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 }
10060
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 vos_preClose( &pVosContext );
10062
10063#ifdef TIMER_MANAGER
10064 vos_timer_exit();
10065#endif
10066#ifdef MEMORY_DEBUG
10067 vos_mem_exit();
10068#endif
10069
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010070#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10071 wlan_logging_sock_deinit_svc();
10072#endif
10073
Jeff Johnson295189b2012-06-20 16:38:30 -070010074done:
Sameer Thalappil50dc0092013-02-19 17:23:33 -080010075#ifdef WLAN_OPEN_SOURCE
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 wake_lock_destroy(&wlan_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010077#endif
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010078
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
10080}
10081
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010082/**---------------------------------------------------------------------------
10083
10084 \brief hdd_module_exit() - Exit function
10085
10086 This is the driver exit point (invoked when module is unloaded using rmmod)
10087
10088 \param - None
10089
10090 \return - None
10091
10092 --------------------------------------------------------------------------*/
10093static void __exit hdd_module_exit(void)
10094{
10095 hdd_driver_exit();
10096}
10097
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010098#ifdef MODULE
10099static int fwpath_changed_handler(const char *kmessage,
10100 struct kernel_param *kp)
10101{
Jeff Johnson76052702013-04-16 13:55:05 -070010102 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010103}
10104
10105static int con_mode_handler(const char *kmessage,
10106 struct kernel_param *kp)
10107{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070010108 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010109}
10110#else /* #ifdef MODULE */
10111/**---------------------------------------------------------------------------
10112
Jeff Johnson76052702013-04-16 13:55:05 -070010113 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010114
Jeff Johnson76052702013-04-16 13:55:05 -070010115 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010116 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070010117 - invoked when module parameter fwpath is modified from userspace to signal
10118 initializing the WLAN driver or when con_mode is modified from userspace
10119 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010120
10121 \return - 0 for success, non zero for failure
10122
10123 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010124static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010125{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010126 int ret_status;
10127
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010128 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010129 ret_status = hdd_driver_init();
10130 wlan_hdd_inited = ret_status ? 0 : 1;
10131 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010132 }
10133
10134 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070010135
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010136 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070010137
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070010138 ret_status = hdd_driver_init();
10139 wlan_hdd_inited = ret_status ? 0 : 1;
10140 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070010141}
10142
Jeff Johnson295189b2012-06-20 16:38:30 -070010143/**---------------------------------------------------------------------------
10144
Jeff Johnson76052702013-04-16 13:55:05 -070010145 \brief fwpath_changed_handler() - Handler Function
10146
10147 Handle changes to the fwpath parameter
10148
10149 \return - 0 for success, non zero for failure
10150
10151 --------------------------------------------------------------------------*/
10152static int fwpath_changed_handler(const char *kmessage,
10153 struct kernel_param *kp)
10154{
10155 int ret;
10156
10157 ret = param_set_copystring(kmessage, kp);
10158 if (0 == ret)
10159 ret = kickstart_driver();
10160 return ret;
10161}
10162
10163/**---------------------------------------------------------------------------
10164
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010165 \brief con_mode_handler() -
10166
10167 Handler function for module param con_mode when it is changed by userspace
10168 Dynamically linked - do nothing
10169 Statically linked - exit and init driver, as in rmmod and insmod
10170
Jeff Johnson76052702013-04-16 13:55:05 -070010171 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010172
Jeff Johnson76052702013-04-16 13:55:05 -070010173 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010174
10175 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070010176static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010177{
Jeff Johnson76052702013-04-16 13:55:05 -070010178 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010179
Jeff Johnson76052702013-04-16 13:55:05 -070010180 ret = param_set_int(kmessage, kp);
10181 if (0 == ret)
10182 ret = kickstart_driver();
10183 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010184}
10185#endif /* #ifdef MODULE */
10186
10187/**---------------------------------------------------------------------------
10188
Jeff Johnson295189b2012-06-20 16:38:30 -070010189 \brief hdd_get_conparam() -
10190
10191 This is the driver exit point (invoked when module is unloaded using rmmod)
10192
10193 \param - None
10194
10195 \return - tVOS_CON_MODE
10196
10197 --------------------------------------------------------------------------*/
10198tVOS_CON_MODE hdd_get_conparam ( void )
10199{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010200#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010202#else
10203 return (tVOS_CON_MODE)curr_con_mode;
10204#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010205}
10206void hdd_set_conparam ( v_UINT_t newParam )
10207{
10208 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010209#ifndef MODULE
10210 curr_con_mode = con_mode;
10211#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010212}
10213/**---------------------------------------------------------------------------
10214
10215 \brief hdd_softap_sta_deauth() - function
10216
10217 This to take counter measure to handle deauth req from HDD
10218
10219 \param - pAdapter - Pointer to the HDD
10220
10221 \param - enable - boolean value
10222
10223 \return - None
10224
10225 --------------------------------------------------------------------------*/
10226
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010227VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
10228 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070010229{
Jeff Johnson295189b2012-06-20 16:38:30 -070010230 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010231 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070010232
10233 ENTER();
10234
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070010235 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
10236 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010237
10238 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010239 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010240 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010241
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010242 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070010243
10244 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080010245 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070010246}
10247
10248/**---------------------------------------------------------------------------
10249
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010250 \brief hdd_del_all_sta() - function
10251
10252 This function removes all the stations associated on stopping AP/P2P GO.
10253
10254 \param - pAdapter - Pointer to the HDD
10255
10256 \return - None
10257
10258 --------------------------------------------------------------------------*/
10259
10260int hdd_del_all_sta(hdd_adapter_t *pAdapter)
10261{
10262 v_U16_t i;
10263 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010264 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10265 ptSapContext pSapCtx = NULL;
10266 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10267 if(pSapCtx == NULL){
10268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10269 FL("psapCtx is NULL"));
10270 return 1;
10271 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010272 ENTER();
10273
10274 hddLog(VOS_TRACE_LEVEL_INFO,
10275 "%s: Delete all STAs associated.",__func__);
10276 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10277 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
10278 )
10279 {
10280 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
10281 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010282 if ((pSapCtx->aStaInfo[i].isUsed) &&
10283 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010284 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010285 struct tagCsrDelStaParams delStaParams;
10286
10287 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010288 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053010289 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
10290 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053010291 &delStaParams);
10292 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010293 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010294 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053010295 }
10296 }
10297 }
10298
10299 EXIT();
10300 return 0;
10301}
10302
10303/**---------------------------------------------------------------------------
10304
Jeff Johnson295189b2012-06-20 16:38:30 -070010305 \brief hdd_softap_sta_disassoc() - function
10306
10307 This to take counter measure to handle deauth req from HDD
10308
10309 \param - pAdapter - Pointer to the HDD
10310
10311 \param - enable - boolean value
10312
10313 \return - None
10314
10315 --------------------------------------------------------------------------*/
10316
10317void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
10318{
10319 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10320
10321 ENTER();
10322
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010323 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010324
10325 //Ignore request to disassoc bcmc station
10326 if( pDestMacAddress[0] & 0x1 )
10327 return;
10328
10329 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
10330}
10331
10332void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
10333{
10334 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10335
10336 ENTER();
10337
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010338 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010339
10340 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
10341}
10342
Jeff Johnson295189b2012-06-20 16:38:30 -070010343/**---------------------------------------------------------------------------
10344 *
10345 * \brief hdd_get__concurrency_mode() -
10346 *
10347 *
10348 * \param - None
10349 *
10350 * \return - CONCURRENCY MODE
10351 *
10352 * --------------------------------------------------------------------------*/
10353tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
10354{
10355 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
10356 hdd_context_t *pHddCtx;
10357
10358 if (NULL != pVosContext)
10359 {
10360 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
10361 if (NULL != pHddCtx)
10362 {
10363 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
10364 }
10365 }
10366
10367 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010368 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 return VOS_STA;
10370}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010371v_BOOL_t
10372wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
10373{
10374 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010375
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010376 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
10377 if (pAdapter == NULL)
10378 {
10379 hddLog(VOS_TRACE_LEVEL_INFO,
10380 FL("GO doesn't exist"));
10381 return TRUE;
10382 }
10383 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10384 {
10385 hddLog(VOS_TRACE_LEVEL_INFO,
10386 FL("GO started"));
10387 return TRUE;
10388 }
10389 else
10390 /* wait till GO changes its interface to p2p device */
10391 hddLog(VOS_TRACE_LEVEL_INFO,
10392 FL("Del_bss called, avoid apps suspend"));
10393 return FALSE;
10394
10395}
Jeff Johnson295189b2012-06-20 16:38:30 -070010396/* Decide whether to allow/not the apps power collapse.
10397 * Allow apps power collapse if we are in connected state.
10398 * if not, allow only if we are in IMPS */
10399v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
10400{
10401 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080010402 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010403 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010404 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10405 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10406 hdd_adapter_t *pAdapter = NULL;
10407 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080010408 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010409
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 if (VOS_STA_SAP_MODE == hdd_get_conparam())
10411 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010412
Yathish9f22e662012-12-10 14:21:35 -080010413 concurrent_state = hdd_get_concurrency_mode();
10414
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010415 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
10416 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
10417 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080010418#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010419
Yathish9f22e662012-12-10 14:21:35 -080010420 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053010421 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080010422 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
10423 return TRUE;
10424#endif
10425
Jeff Johnson295189b2012-06-20 16:38:30 -070010426 /*loop through all adapters. TBD fix for Concurrency */
10427 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10428 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10429 {
10430 pAdapter = pAdapterNode->pAdapter;
10431 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
10432 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
10433 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080010434 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053010435 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053010436 && pmcState != STOPPED && pmcState != STANDBY &&
10437 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010438 (eANI_BOOLEAN_TRUE == scanRspPending) ||
10439 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 {
Mukul Sharma4be88422015-03-09 20:29:07 +053010441 if(pmcState == FULL_POWER &&
10442 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
10443 {
10444 /*
10445 * When SCO indication comes from Coex module , host will
10446 * enter in to full power mode, but this should not prevent
10447 * apps processor power collapse.
10448 */
10449 hddLog(LOG1,
10450 FL("Allow apps power collapse"
10451 "even when sco indication is set"));
10452 return TRUE;
10453 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080010454 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080010455 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
10456 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 return FALSE;
10458 }
10459 }
10460 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10461 pAdapterNode = pNext;
10462 }
10463 return TRUE;
10464}
10465
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080010466/* Decides whether to send suspend notification to Riva
10467 * if any adapter is in BMPS; then it is required */
10468v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
10469{
10470 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
10471 hdd_config_t *pConfig = pHddCtx->cfg_ini;
10472
10473 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
10474 {
10475 return TRUE;
10476 }
10477 return FALSE;
10478}
10479
Jeff Johnson295189b2012-06-20 16:38:30 -070010480void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10481{
10482 switch(mode)
10483 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010484 case VOS_STA_MODE:
10485 case VOS_P2P_CLIENT_MODE:
10486 case VOS_P2P_GO_MODE:
10487 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070010488 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010489 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070010490 break;
10491 default:
10492 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070010493 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010494 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10495 "Number of open sessions for mode %d = %d"),
10496 pHddCtx->concurrency_mode, mode,
10497 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010498}
10499
10500
10501void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10502{
10503 switch(mode)
10504 {
Chilam Ngc4244af2013-04-01 15:37:32 -070010505 case VOS_STA_MODE:
10506 case VOS_P2P_CLIENT_MODE:
10507 case VOS_P2P_GO_MODE:
10508 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053010509 pHddCtx->no_of_open_sessions[mode]--;
10510 if (!(pHddCtx->no_of_open_sessions[mode]))
10511 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070010512 break;
10513 default:
10514 break;
10515 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010516 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
10517 "Number of open sessions for mode %d = %d"),
10518 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
10519
10520}
10521/**---------------------------------------------------------------------------
10522 *
10523 * \brief wlan_hdd_incr_active_session()
10524 *
10525 * This function increments the number of active sessions
10526 * maintained per device mode
10527 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
10528 * Incase of SAP/P2P GO upon bss start it is incremented
10529 *
10530 * \param pHddCtx - HDD Context
10531 * \param mode - device mode
10532 *
10533 * \return - None
10534 *
10535 * --------------------------------------------------------------------------*/
10536void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10537{
10538 switch (mode) {
10539 case VOS_STA_MODE:
10540 case VOS_P2P_CLIENT_MODE:
10541 case VOS_P2P_GO_MODE:
10542 case VOS_STA_SAP_MODE:
10543 pHddCtx->no_of_active_sessions[mode]++;
10544 break;
10545 default:
10546 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10547 break;
10548 }
10549 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10550 mode,
10551 pHddCtx->no_of_active_sessions[mode]);
10552}
10553
10554/**---------------------------------------------------------------------------
10555 *
10556 * \brief wlan_hdd_decr_active_session()
10557 *
10558 * This function decrements the number of active sessions
10559 * maintained per device mode
10560 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
10561 * Incase of SAP/P2P GO upon bss stop it is decremented
10562 *
10563 * \param pHddCtx - HDD Context
10564 * \param mode - device mode
10565 *
10566 * \return - None
10567 *
10568 * --------------------------------------------------------------------------*/
10569void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
10570{
10571 switch (mode) {
10572 case VOS_STA_MODE:
10573 case VOS_P2P_CLIENT_MODE:
10574 case VOS_P2P_GO_MODE:
10575 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053010576 if (pHddCtx->no_of_active_sessions[mode] > 0)
10577 pHddCtx->no_of_active_sessions[mode]--;
10578 else
10579 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
10580 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053010581 break;
10582 default:
10583 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
10584 break;
10585 }
10586 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
10587 mode,
10588 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070010589}
10590
Jeff Johnsone7245742012-09-05 17:12:55 -070010591/**---------------------------------------------------------------------------
10592 *
10593 * \brief wlan_hdd_restart_init
10594 *
10595 * This function initalizes restart timer/flag. An internal function.
10596 *
10597 * \param - pHddCtx
10598 *
10599 * \return - None
10600 *
10601 * --------------------------------------------------------------------------*/
10602
10603static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
10604{
10605 /* Initialize */
10606 pHddCtx->hdd_restart_retries = 0;
10607 atomic_set(&pHddCtx->isRestartInProgress, 0);
10608 vos_timer_init(&pHddCtx->hdd_restart_timer,
10609 VOS_TIMER_TYPE_SW,
10610 wlan_hdd_restart_timer_cb,
10611 pHddCtx);
10612}
10613/**---------------------------------------------------------------------------
10614 *
10615 * \brief wlan_hdd_restart_deinit
10616 *
10617 * This function cleans up the resources used. An internal function.
10618 *
10619 * \param - pHddCtx
10620 *
10621 * \return - None
10622 *
10623 * --------------------------------------------------------------------------*/
10624
10625static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
10626{
10627
10628 VOS_STATUS vos_status;
10629 /* Block any further calls */
10630 atomic_set(&pHddCtx->isRestartInProgress, 1);
10631 /* Cleanup */
10632 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
10633 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010634 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010635 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
10636 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010637 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070010638
10639}
10640
10641/**---------------------------------------------------------------------------
10642 *
10643 * \brief wlan_hdd_framework_restart
10644 *
10645 * This function uses a cfg80211 API to start a framework initiated WLAN
10646 * driver module unload/load.
10647 *
10648 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
10649 *
10650 *
10651 * \param - pHddCtx
10652 *
10653 * \return - VOS_STATUS_SUCCESS: Success
10654 * VOS_STATUS_E_EMPTY: Adapter is Empty
10655 * VOS_STATUS_E_NOMEM: No memory
10656
10657 * --------------------------------------------------------------------------*/
10658
10659static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
10660{
10661 VOS_STATUS status = VOS_STATUS_SUCCESS;
10662 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010663 int len = (sizeof (struct ieee80211_mgmt));
10664 struct ieee80211_mgmt *mgmt = NULL;
10665
10666 /* Prepare the DEAUTH managment frame with reason code */
10667 mgmt = kzalloc(len, GFP_KERNEL);
10668 if(mgmt == NULL)
10669 {
10670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10671 "%s: memory allocation failed (%d bytes)", __func__, len);
10672 return VOS_STATUS_E_NOMEM;
10673 }
10674 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070010675
10676 /* Iterate over all adapters/devices */
10677 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10678 do
10679 {
10680 if( (status == VOS_STATUS_SUCCESS) &&
10681 pAdapterNode &&
10682 pAdapterNode->pAdapter)
10683 {
10684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10685 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
10686 pAdapterNode->pAdapter->dev->name,
10687 pAdapterNode->pAdapter->device_mode,
10688 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010689 /*
10690 * CFG80211 event to restart the driver
10691 *
10692 * 'cfg80211_send_unprot_deauth' sends a
10693 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
10694 * of SME(Linux Kernel) state machine.
10695 *
10696 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
10697 * the driver.
10698 *
10699 */
10700
10701 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Jeff Johnsone7245742012-09-05 17:12:55 -070010702 }
10703 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10704 pAdapterNode = pNext;
10705 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
10706
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070010707
10708 /* Free the allocated management frame */
10709 kfree(mgmt);
10710
Jeff Johnsone7245742012-09-05 17:12:55 -070010711 /* Retry until we unload or reach max count */
10712 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
10713 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
10714
10715 return status;
10716
10717}
10718/**---------------------------------------------------------------------------
10719 *
10720 * \brief wlan_hdd_restart_timer_cb
10721 *
10722 * Restart timer callback. An internal function.
10723 *
10724 * \param - User data:
10725 *
10726 * \return - None
10727 *
10728 * --------------------------------------------------------------------------*/
10729
10730void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
10731{
10732 hdd_context_t *pHddCtx = usrDataForCallback;
10733 wlan_hdd_framework_restart(pHddCtx);
10734 return;
10735
10736}
10737
10738
10739/**---------------------------------------------------------------------------
10740 *
10741 * \brief wlan_hdd_restart_driver
10742 *
10743 * This function sends an event to supplicant to restart the WLAN driver.
10744 *
10745 * This function is called from vos_wlanRestart.
10746 *
10747 * \param - pHddCtx
10748 *
10749 * \return - VOS_STATUS_SUCCESS: Success
10750 * VOS_STATUS_E_EMPTY: Adapter is Empty
10751 * VOS_STATUS_E_ALREADY: Request already in progress
10752
10753 * --------------------------------------------------------------------------*/
10754VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
10755{
10756 VOS_STATUS status = VOS_STATUS_SUCCESS;
10757
10758 /* A tight check to make sure reentrancy */
10759 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
10760 {
Mihir Shetefd528652014-06-23 19:07:50 +053010761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070010762 "%s: WLAN restart is already in progress", __func__);
10763
10764 return VOS_STATUS_E_ALREADY;
10765 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070010766 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080010767#ifdef HAVE_WCNSS_RESET_INTR
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070010768 wcnss_reset_intr();
10769#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010770
Jeff Johnsone7245742012-09-05 17:12:55 -070010771 return status;
10772}
10773
Mihir Shetee1093ba2014-01-21 20:13:32 +053010774/**---------------------------------------------------------------------------
10775 *
10776 * \brief wlan_hdd_init_channels
10777 *
10778 * This function is used to initialize the channel list in CSR
10779 *
10780 * This function is called from hdd_wlan_startup
10781 *
10782 * \param - pHddCtx: HDD context
10783 *
10784 * \return - VOS_STATUS_SUCCESS: Success
10785 * VOS_STATUS_E_FAULT: Failure reported by SME
10786
10787 * --------------------------------------------------------------------------*/
10788static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
10789{
10790 eHalStatus status;
10791
10792 status = sme_InitChannels(pHddCtx->hHal);
10793 if (HAL_STATUS_SUCCESS(status))
10794 {
10795 return VOS_STATUS_SUCCESS;
10796 }
10797 else
10798 {
10799 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
10800 __func__, status);
10801 return VOS_STATUS_E_FAULT;
10802 }
10803}
10804
Mihir Shete04206452014-11-20 17:50:58 +053010805#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010806VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010807{
10808 eHalStatus status;
10809
Agarwal Ashish6db9d532014-09-30 18:19:10 +053010810 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053010811 if (HAL_STATUS_SUCCESS(status))
10812 {
10813 return VOS_STATUS_SUCCESS;
10814 }
10815 else
10816 {
10817 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
10818 __func__, status);
10819 return VOS_STATUS_E_FAULT;
10820 }
10821}
Mihir Shete04206452014-11-20 17:50:58 +053010822#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070010823/*
10824 * API to find if there is any STA or P2P-Client is connected
10825 */
10826VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
10827{
10828 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
10829}
Jeff Johnsone7245742012-09-05 17:12:55 -070010830
Agarwal Ashish57e84372014-12-05 18:26:53 +053010831/*
10832 * API to find if there is any session connected
10833 */
10834VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
10835{
10836 return sme_is_any_session_connected(pHddCtx->hHal);
10837}
10838
10839
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010840int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
10841{
10842 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10843 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053010844 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053010845 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010846
10847 pScanInfo = &pHddCtx->scan_info;
10848 if (pScanInfo->mScanPending)
10849 {
c_hpothua3d45d52015-01-05 14:11:17 +053010850 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
10851 eCSR_SCAN_ABORT_DEFAULT);
10852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10853 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010854
c_hpothua3d45d52015-01-05 14:11:17 +053010855 /* If there is active scan command lets wait for the completion else
10856 * there is no need to wait as scan command might be in the SME pending
10857 * command list.
10858 */
10859 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
10860 {
10861 INIT_COMPLETION(pScanInfo->abortscan_event_var);
10862 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010863 &pScanInfo->abortscan_event_var,
10864 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053010865 if (0 >= status)
10866 {
10867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053010868 "%s: Timeout or Interrupt occurred while waiting for abort"
10869 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053010870 return -ETIMEDOUT;
10871 }
10872 }
10873 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
10874 {
10875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10876 FL("hdd_abort_mac_scan failed"));
10877 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010878 }
10879 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053010880 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053010881}
10882
c_hpothu225aa7c2014-10-22 17:45:13 +053010883VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
10884{
10885 hdd_adapter_t *pAdapter;
10886 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10887 VOS_STATUS vosStatus;
10888
10889 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10890 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10891 {
10892 pAdapter = pAdapterNode->pAdapter;
10893 if (NULL != pAdapter)
10894 {
10895 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
10896 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
10897 WLAN_HDD_P2P_GO == pAdapter->device_mode)
10898 {
10899 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
10900 pAdapter->device_mode);
10901 if (VOS_STATUS_SUCCESS !=
10902 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
10903 {
10904 hddLog(LOGE, FL("failed to abort ROC"));
10905 return VOS_STATUS_E_FAILURE;
10906 }
10907 }
10908 }
10909 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10910 pAdapterNode = pNext;
10911 }
10912 return VOS_STATUS_SUCCESS;
10913}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053010914
Mihir Shete0be28772015-02-17 18:42:14 +053010915hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
10916{
10917 hdd_adapter_t *pAdapter;
10918 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10919 hdd_cfg80211_state_t *cfgState;
10920 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
10921 VOS_STATUS vosStatus;
10922
10923 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
10924 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
10925 {
10926 pAdapter = pAdapterNode->pAdapter;
10927 if (NULL != pAdapter)
10928 {
10929 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
10930 pRemainChanCtx = cfgState->remain_on_chan_ctx;
10931 if (pRemainChanCtx)
10932 break;
10933 }
10934 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
10935 pAdapterNode = pNext;
10936 }
10937 return pRemainChanCtx;
10938}
10939
Jeff Johnson295189b2012-06-20 16:38:30 -070010940//Register the module init/exit functions
10941module_init(hdd_module_init);
10942module_exit(hdd_module_exit);
10943
10944MODULE_LICENSE("Dual BSD/GPL");
10945MODULE_AUTHOR("Qualcomm Atheros, Inc.");
10946MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
10947
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070010948module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
10949 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010950
Jeff Johnson76052702013-04-16 13:55:05 -070010951module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070010952 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080010953
10954module_param(enable_dfs_chan_scan, int,
10955 S_IRUSR | S_IRGRP | S_IROTH);
10956
10957module_param(enable_11d, int,
10958 S_IRUSR | S_IRGRP | S_IROTH);
10959
10960module_param(country_code, charp,
10961 S_IRUSR | S_IRGRP | S_IROTH);