blob: 6592eb4fc0696e1a5dd52dcf152c3d4fa1de37f4 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +05302 * Copyright (c) 2012-2016 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
Abhishek Singh00b71972016-01-07 10:51:04 +0530179#ifdef WLAN_FEATURE_RMC
180/*
181 * Ibss prop IE from command will be of size:
182 * size = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length)
183 * OUI_DATA should be at least 3 bytes long
184 */
185#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3)
186#endif
187
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800188#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700189#define TID_MIN_VALUE 0
190#define TID_MAX_VALUE 15
191static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
192 tAniTrafStrmMetrics* pTsmMetrics);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800193static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
194 tCsrEseBeaconReq *pEseBcnReq);
195#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700196
Atul Mittal1d722422014-03-19 11:15:07 +0530197/*
198 * Maximum buffer size used for returning the data back to user space
199 */
200#define WLAN_MAX_BUF_SIZE 1024
201#define WLAN_PRIV_DATA_MAX_LEN 8192
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -0700202
Abhishek Singh00b71972016-01-07 10:51:04 +0530203/*
204 * When ever we need to print IBSSPEERINFOALL for morethan 16 STA
205 * we will split the printing.
206 */
207#define NUM_OF_STA_DATA_TO_PRINT 16
208
209#ifdef WLAN_FEATURE_RMC
210#define WLAN_NLINK_CESIUM 30
211#endif
212
c_hpothu92367912014-05-01 15:18:17 +0530213//wait time for beacon miss rate.
214#define BCN_MISS_RATE_TIME 500
215
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530216/*
217 * Android DRIVER command structures
218 */
219struct android_wifi_reassoc_params {
220 unsigned char bssid[18];
221 int channel;
222};
223
Sushant Kaushik83392fa2015-05-05 17:44:40 +0530224static vos_wake_lock_t wlan_wake_lock;
225
Jeff Johnson295189b2012-06-20 16:38:30 -0700226/* set when SSR is needed after unload */
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -0700227static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED;
Jeff Johnson295189b2012-06-20 16:38:30 -0700228
229//internal function declaration
Jeff Johnsone7245742012-09-05 17:12:55 -0700230static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx);
231static void wlan_hdd_restart_init(hdd_context_t *pHddCtx);
232static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx);
Abhishek Singh00b71972016-01-07 10:51:04 +0530233
234#ifdef WLAN_FEATURE_RMC
235static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo);
236
237static int hdd_open_cesium_nl_sock(void);
238static void hdd_close_cesium_nl_sock(void);
239static struct sock *cesium_nl_srv_sock;
240static v_U16_t cesium_pid;
241
242static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
243 tANI_U8 *tx_fail_count,
244 tANI_U16 *pid);
245
246static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
247
248#endif /* WLAN_FEATURE_RMC */
Jeff Johnsone7245742012-09-05 17:12:55 -0700249void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
Sameer Thalappil45931fb2013-02-01 11:18:05 -0800250void hdd_set_wlan_suspend_mode(bool suspend);
Jeff Johnsone7245742012-09-05 17:12:55 -0700251
Jeff Johnson295189b2012-06-20 16:38:30 -0700252v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530253 struct sk_buff *skb
254#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
255 , void *accel_priv
256#endif
257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
258 , select_queue_fallback_t fallback
259#endif
260);
Jeff Johnson295189b2012-06-20 16:38:30 -0700261
262#ifdef WLAN_FEATURE_PACKET_FILTERING
263static void hdd_set_multicast_list(struct net_device *dev);
264#endif
265
266void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
267
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800268#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800269void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
270static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700271static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
272 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
273 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530274static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
275 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800276#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530277
278/* Store WLAN driver info in a global variable such that crash debugger
279 can extract it from driver debug symbol and crashdump for post processing */
280tANI_U8 g_wlan_driver[ ] = "pronto_driver";
281
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800282#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700283VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800284#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700285
Mihir Shetee1093ba2014-01-21 20:13:32 +0530286static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530287const char * hdd_device_modetoString(v_U8_t device_mode)
288{
289 switch(device_mode)
290 {
291 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
292 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
293 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
294 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
295 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
296 CASE_RETURN_STRING( WLAN_HDD_FTM );
297 CASE_RETURN_STRING( WLAN_HDD_IBSS );
298 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
299 default:
300 return "device_mode Unknown";
301 }
302}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530303
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530304static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700305 unsigned long state,
306 void *ndev)
307{
308 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700309 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700310 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700311#ifdef WLAN_BTAMP_FEATURE
312 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700313#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530314 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700315
316 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700317 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700318 (strncmp(dev->name, "p2p", 3)))
319 return NOTIFY_DONE;
320
Jeff Johnson295189b2012-06-20 16:38:30 -0700321 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700322 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700323
Jeff Johnson27cee452013-03-27 11:10:24 -0700324 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800326 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700327 VOS_ASSERT(0);
328 return NOTIFY_DONE;
329 }
330
Jeff Johnson27cee452013-03-27 11:10:24 -0700331 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
332 if (NULL == pHddCtx)
333 {
334 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
335 VOS_ASSERT(0);
336 return NOTIFY_DONE;
337 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800338 if (pHddCtx->isLogpInProgress)
339 return NOTIFY_DONE;
340
Jeff Johnson27cee452013-03-27 11:10:24 -0700341
342 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
343 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700344
345 switch (state) {
346 case NETDEV_REGISTER:
347 break;
348
349 case NETDEV_UNREGISTER:
350 break;
351
352 case NETDEV_UP:
353 break;
354
355 case NETDEV_DOWN:
356 break;
357
358 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700359 if(TRUE == pAdapter->isLinkUpSvcNeeded)
360 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700361 break;
362
363 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530364 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530365 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530366 {
367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
368 "%s: Timeout occurred while waiting for abortscan %ld",
369 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 }
371 else
372 {
373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530374 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700375 }
376#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 status = WLANBAP_StopAmp();
379 if(VOS_STATUS_SUCCESS != status )
380 {
381 pHddCtx->isAmpAllowed = VOS_TRUE;
382 hddLog(VOS_TRACE_LEVEL_FATAL,
383 "%s: Failed to stop AMP", __func__);
384 }
385 else
386 {
387 //a state m/c implementation in PAL is TBD to avoid this delay
388 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700389 if ( pHddCtx->isAmpAllowed )
390 {
391 WLANBAP_DeregisterFromHCI();
392 pHddCtx->isAmpAllowed = VOS_FALSE;
393 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700394 }
395#endif //WLAN_BTAMP_FEATURE
396 break;
397
398 default:
399 break;
400 }
401
402 return NOTIFY_DONE;
403}
404
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530405static int hdd_netdev_notifier_call(struct notifier_block * nb,
406 unsigned long state,
407 void *ndev)
408{
409 int ret;
410 vos_ssr_protect(__func__);
411 ret = __hdd_netdev_notifier_call( nb, state, ndev);
412 vos_ssr_unprotect(__func__);
413 return ret;
414}
415
Jeff Johnson295189b2012-06-20 16:38:30 -0700416struct notifier_block hdd_netdev_notifier = {
417 .notifier_call = hdd_netdev_notifier_call,
418};
419
420/*---------------------------------------------------------------------------
421 * Function definitions
422 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700423void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
424void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700425//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700426static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700427#ifndef MODULE
428/* current con_mode - used only for statically linked driver
429 * con_mode is changed by userspace to indicate a mode change which will
430 * result in calling the module exit and init functions. The module
431 * exit function will clean up based on the value of con_mode prior to it
432 * being changed by userspace. So curr_con_mode records the current con_mode
433 * for exit when con_mode becomes the next mode for init
434 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700435static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700436#endif
437
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530438#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
439/**
440 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
441 * @hdd_ctx: hdd global context
442 *
443 * Return: none
444 */
445static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
446{
447 uint8_t i;
448
449 mutex_init(&hdd_ctx->op_ctx.op_lock);
450 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
451 {
452 hdd_ctx->op_ctx.op_table[i].request_id = 0;
453 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
454 }
455}
456#else
457static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
458{
459}
460#endif
461
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800462/**---------------------------------------------------------------------------
463
464 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
465
466 Called immediately after the cfg.ini is read in order to configure
467 the desired trace levels.
468
469 \param - moduleId - module whose trace level is being configured
470 \param - bitmask - bitmask of log levels to be enabled
471
472 \return - void
473
474 --------------------------------------------------------------------------*/
475static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
476{
477 wpt_tracelevel level;
478
479 /* if the bitmask is the default value, then a bitmask was not
480 specified in cfg.ini, so leave the logging level alone (it
481 will remain at the "compiled in" default value) */
482 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
483 {
484 return;
485 }
486
487 /* a mask was specified. start by disabling all logging */
488 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
489
490 /* now cycle through the bitmask until all "set" bits are serviced */
491 level = VOS_TRACE_LEVEL_FATAL;
492 while (0 != bitmask)
493 {
494 if (bitmask & 1)
495 {
496 vos_trace_setValue(moduleId, level, 1);
497 }
498 level++;
499 bitmask >>= 1;
500 }
501}
502
503
Jeff Johnson295189b2012-06-20 16:38:30 -0700504/**---------------------------------------------------------------------------
505
506 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
507
508 Called immediately after the cfg.ini is read in order to configure
509 the desired trace levels in the WDI.
510
511 \param - moduleId - module whose trace level is being configured
512 \param - bitmask - bitmask of log levels to be enabled
513
514 \return - void
515
516 --------------------------------------------------------------------------*/
517static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
518{
519 wpt_tracelevel level;
520
521 /* if the bitmask is the default value, then a bitmask was not
522 specified in cfg.ini, so leave the logging level alone (it
523 will remain at the "compiled in" default value) */
524 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
525 {
526 return;
527 }
528
529 /* a mask was specified. start by disabling all logging */
530 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
531
532 /* now cycle through the bitmask until all "set" bits are serviced */
533 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
534 while (0 != bitmask)
535 {
536 if (bitmask & 1)
537 {
538 wpalTraceSetLevel(moduleId, level, 1);
539 }
540 level++;
541 bitmask >>= 1;
542 }
543}
Jeff Johnson295189b2012-06-20 16:38:30 -0700544
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530545/*
546 * FUNCTION: wlan_hdd_validate_context
547 * This function is used to check the HDD context
548 */
549int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
550{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530551
552 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
553 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530555 "%s: HDD context is Null", __func__);
556 return -ENODEV;
557 }
558
559 if (pHddCtx->isLogpInProgress)
560 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530562 "%s: LOGP %s. Ignore!!", __func__,
563 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
564 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530565 return -EAGAIN;
566 }
567
Mihir Shete18156292014-03-11 15:38:30 +0530568 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530569 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530571 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
572 return -EAGAIN;
573 }
574 return 0;
575}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700576#ifdef CONFIG_ENABLE_LINUX_REG
577void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
578{
579 hdd_adapter_t *pAdapter = NULL;
580 hdd_station_ctx_t *pHddStaCtx = NULL;
581 eCsrPhyMode phyMode;
582 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530583
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700584 if (NULL == pHddCtx)
585 {
586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
587 "HDD Context is null !!");
588 return ;
589 }
590
591 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
592 if (NULL == pAdapter)
593 {
594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
595 "pAdapter is null !!");
596 return ;
597 }
598
599 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
600 if (NULL == pHddStaCtx)
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
603 "pHddStaCtx is null !!");
604 return ;
605 }
606
607 cfg_param = pHddCtx->cfg_ini;
608 if (NULL == cfg_param)
609 {
610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
611 "cfg_params not available !!");
612 return ;
613 }
614
615 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
616
617 if (!pHddCtx->isVHT80Allowed)
618 {
619 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
620 (eCSR_DOT11_MODE_11ac == phyMode) ||
621 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
622 {
623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
624 "Setting phymode to 11n!!");
625 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
626 }
627 }
628 else
629 {
630 /*New country Supports 11ac as well resetting value back from .ini*/
631 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
632 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
633 return ;
634 }
635
636 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
637 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
638 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
639 {
640 VOS_STATUS vosStatus;
641
642 // need to issue a disconnect to CSR.
643 INIT_COMPLETION(pAdapter->disconnect_comp_var);
644 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
645 pAdapter->sessionId,
646 eCSR_DISCONNECT_REASON_UNSPECIFIED );
647
648 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530649 {
650 long ret;
651
652 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700653 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530654 if (0 >= ret)
655 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
656 ret);
657 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700658
659 }
660}
661#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530662void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
663{
664 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
665 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
666 hdd_config_t *cfg_param;
667 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530668 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530669
670 if (NULL == pHddCtx)
671 {
672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
673 "HDD Context is null !!");
674 return ;
675 }
676
677 cfg_param = pHddCtx->cfg_ini;
678
679 if (NULL == cfg_param)
680 {
681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
682 "cfg_params not available !!");
683 return ;
684 }
685
686 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
687
688 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
689 {
690 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
691 (eCSR_DOT11_MODE_11ac == phyMode) ||
692 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
693 {
694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
695 "Setting phymode to 11n!!");
696 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
697 }
698 }
699 else
700 {
701 /*New country Supports 11ac as well resetting value back from .ini*/
702 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
703 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
704 return ;
705 }
706
707 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
708 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
709 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
710 {
711 VOS_STATUS vosStatus;
712
713 // need to issue a disconnect to CSR.
714 INIT_COMPLETION(pAdapter->disconnect_comp_var);
715 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
716 pAdapter->sessionId,
717 eCSR_DISCONNECT_REASON_UNSPECIFIED );
718
719 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530720 {
721 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530722 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530723 if (ret <= 0)
724 {
725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
726 "wait on disconnect_comp_var is failed %ld", ret);
727 }
728 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530729
730 }
731}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700732#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530733
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700734void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
735{
736 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
737 hdd_config_t *cfg_param;
738
739 if (NULL == pHddCtx)
740 {
741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
742 "HDD Context is null !!");
743 return ;
744 }
745
746 cfg_param = pHddCtx->cfg_ini;
747
748 if (NULL == cfg_param)
749 {
750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
751 "cfg_params not available !!");
752 return ;
753 }
754
Agarwal Ashish738843c2014-09-25 12:27:56 +0530755 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
756 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700757 {
758 /*New country doesn't support DFS */
759 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
760 }
761 else
762 {
763 /*New country Supports DFS as well resetting value back from .ini*/
764 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), cfg_param->enableDFSChnlScan);
765 }
766
767}
768
Abhishek Singh00b71972016-01-07 10:51:04 +0530769#ifdef WLAN_FEATURE_RMC
770static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
771{
772 tANI_U8 *inPtr = pValue;
773 int tempInt;
774 int v = 0;
775 char buf[32];
776 *pRmcEnable = 0;
777
778 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
779 /*no argument after the command*/
780 if (NULL == inPtr)
781 {
782 return 0;
783 }
784
785 /*no space after the command*/
786 else if (SPACE_ASCII_VALUE != *inPtr)
787 {
788 return 0;
789 }
790
791 /*removing empty spaces*/
792 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
793
794 /*no argument followed by spaces*/
795 if ('\0' == *inPtr)
796 {
797 return 0;
798 }
799
800 /* getting the first argument which enables or disables RMC
801 * for input IP v4 address*/
802 sscanf(inPtr, "%32s ", buf);
803 v = kstrtos32(buf, 10, &tempInt);
804 if ( v < 0)
805 {
806 return -EINVAL;
807 }
808
809 *pRmcEnable = tempInt;
810
811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
812 "ucRmcEnable: %d", *pRmcEnable);
813
814 return 0;
815}
816
817/* Function header left blank Intentionally */
818static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
819 tANI_U32 *pActionPeriod)
820{
821 tANI_U8 *inPtr = pValue;
822 int tempInt;
823 int v = 0;
824 char buf[32];
825 *pActionPeriod = 0;
826
827 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
828 /*no argument after the command*/
829 if (NULL == inPtr)
830 {
831 return -EINVAL;
832 }
833
834 /*no space after the command*/
835 else if (SPACE_ASCII_VALUE != *inPtr)
836 {
837 return -EINVAL;
838 }
839
840 /*removing empty spaces*/
841 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
842
843 /*no argument followed by spaces*/
844 if ('\0' == *inPtr)
845 {
846 return 0;
847 }
848
849 /* getting the first argument which enables or disables RMC
850 * for input IP v4 address*/
851 sscanf(inPtr, "%32s ", buf);
852 v = kstrtos32(buf, 10, &tempInt);
853 if ( v < 0)
854 {
855 return -EINVAL;
856 }
857
858 /* Range checking for passed paramter */
859 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
860 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
861 {
862 return -EINVAL;
863 }
864
865 *pActionPeriod = tempInt;
866
867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
868 "uActionPeriod: %d", *pActionPeriod);
869
870 return 0;
871}
872
873/* Function header left blank Intentionally */
874static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
875 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
876{
877 tANI_U8 *inPtr = pValue;
878 int tempInt;
879 int v = 0;
880 char buf[32];
881 *pRate = 0;
882 *pTxFlags = 0;
883
884 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
885 /*no argument after the command*/
886 if (NULL == inPtr)
887 {
888 return -EINVAL;
889 }
890
891 /*no space after the command*/
892 else if (SPACE_ASCII_VALUE != *inPtr)
893 {
894 return -EINVAL;
895 }
896
897 /*removing empty spaces*/
898 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
899
900 /*no argument followed by spaces*/
901 if ('\0' == *inPtr)
902 {
903 return 0;
904 }
905
906 /*
907 * getting the first argument which sets multicast rate.
908 */
909 sscanf(inPtr, "%32s ", buf);
910 v = kstrtos32(buf, 10, &tempInt);
911 if ( v < 0)
912 {
913 return -EINVAL;
914 }
915
916 /*
917 * Validate the multicast rate.
918 */
919 switch (tempInt)
920 {
921 default:
922 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
923 "Unsupported rate: %d", tempInt);
924 return -EINVAL;
925 case 0:
926 case 6:
927 case 9:
928 case 12:
929 case 18:
930 case 24:
931 case 36:
932 case 48:
933 case 54:
934 *pTxFlags = eHAL_TX_RATE_LEGACY;
935 *pRate = tempInt * 10;
936 break;
937 case 65:
938 *pTxFlags = eHAL_TX_RATE_HT20;
939 *pRate = tempInt * 10;
940 break;
941 case 72:
942 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
943 *pRate = 722; /* fractional rate 72.2 Mbps */
944 break;
945 }
946
947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
948 "Rate: %d", *pRate);
949
950 return 0;
951}
952
953/**---------------------------------------------------------------------------
954
955 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
956 Peer Info request
957
958 This is an asynchronous callback function from SME when the peer info
959 is received
960
961 \pUserData -> Adapter private data
962 \pPeerInfoRsp -> Peer info response
963
964 \return - 0 for success non-zero for failure
965 --------------------------------------------------------------------------*/
966static void
967hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
968{
969 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
970 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
971 hdd_station_ctx_t *pStaCtx;
972 v_U8_t i;
973
974 /*Sanity check*/
975 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
976 {
977 hddLog(LOGE,
978 FL("invalid adapter or adapter has invalid magic"));
979 return;
980 }
981
982 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
983 if (NULL != pStaCtx && NULL != pPeerInfo &&
984 eHAL_STATUS_SUCCESS == pPeerInfo->status)
985 {
986 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
987 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
988
989 /* Paranoia check */
990 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
991 {
992 for (i = 0; i < pPeerInfo->numPeers; i++)
993 {
994 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
995 &pPeerInfo->peerInfoParams[i],
996 sizeof(hdd_ibss_peer_info_params_t));
997 }
998 hddLog(LOG1,
999 FL("Peer Info copied in HDD"));
1000 }
1001 else
1002 {
1003 hddLog(LOGE,
1004 FL(" Number of peers %d returned is more than limit %d"),
1005 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1006 }
1007 }
1008 else
1009 {
1010 hddLog(LOG1,
1011 FL("peerInfo returned is NULL"));
1012 }
1013
1014 complete(&pAdapter->ibss_peer_info_comp);
1015}
1016
1017/**---------------------------------------------------------------------------
1018
1019 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1020
1021 Request function to get IBSS peer info from lower layers
1022
1023 \pAdapter -> Adapter context
1024
1025 \return - 0 for success non-zero for failure
1026 --------------------------------------------------------------------------*/
1027static
1028VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1029{
1030 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1031 long status;
1032 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1033
1034 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1035
1036 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1037 hdd_cfg80211_get_ibss_peer_info_cb,
1038 VOS_TRUE, 0xFF);
1039
1040 if (VOS_STATUS_SUCCESS == retStatus)
1041 {
1042 status = wait_for_completion_interruptible_timeout
1043 (&pAdapter->ibss_peer_info_comp,
1044 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1045
1046 /* status will be 0 if timed out */
1047 if (status <= 0)
1048 {
1049 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1050 __func__, status);
1051 retStatus = VOS_STATUS_E_FAILURE;
1052 return retStatus;
1053 }
1054 }
1055 else
1056 {
1057 hddLog(VOS_TRACE_LEVEL_WARN,
1058 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1059 }
1060
1061 return retStatus;
1062}
1063
1064/**---------------------------------------------------------------------------
1065
1066 \brief hdd_cfg80211_get_ibss_peer_info() -
1067
1068 Request function to get IBSS peer info from lower layers
1069
1070 \pAdapter -> Adapter context
1071 \staIdx -> Sta index for which the peer info is requested
1072
1073 \return - 0 for success non-zero for failure
1074 --------------------------------------------------------------------------*/
1075static VOS_STATUS
1076hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1077{
1078 long status;
1079 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1080 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1081
1082 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1083
1084 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1085 hdd_cfg80211_get_ibss_peer_info_cb,
1086 VOS_FALSE, staIdx);
1087
1088 if (VOS_STATUS_SUCCESS == retStatus)
1089 {
1090 status = wait_for_completion_interruptible_timeout
1091 (&pAdapter->ibss_peer_info_comp,
1092 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1093
1094 /* status = 0 on timeout */
1095 if (status <= 0)
1096 {
1097 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1098 __func__, status);
1099 retStatus = VOS_STATUS_E_FAILURE;
1100 return retStatus;
1101 }
1102 }
1103 else
1104 {
1105 hddLog(VOS_TRACE_LEVEL_WARN,
1106 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1107 }
1108
1109 return retStatus;
1110}
1111
1112/* Function header left blank Intentionally */
1113VOS_STATUS
1114hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1115{
1116 tANI_U8 *inPtr = pValue;
1117 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1118
1119 /*no argument after the command*/
1120 if (NULL == inPtr)
1121 {
1122 return VOS_STATUS_E_FAILURE;;
1123 }
1124
1125 /*no space after the command*/
1126 else if (SPACE_ASCII_VALUE != *inPtr)
1127 {
1128 return VOS_STATUS_E_FAILURE;;
1129 }
1130
1131 /*removing empty spaces*/
1132 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1133
1134 /*no argument followed by spaces*/
1135 if ('\0' == *inPtr)
1136 {
1137 return VOS_STATUS_E_FAILURE;;
1138 }
1139
1140 /*getting the first argument ie the peer mac address */
1141 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1142 inPtr[11] != ':' || inPtr[14] != ':')
1143 {
1144 return VOS_STATUS_E_FAILURE;;
1145 }
1146 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1147 (unsigned int *)&pPeerMacAddr->bytes[0],
1148 (unsigned int *)&pPeerMacAddr->bytes[1],
1149 (unsigned int *)&pPeerMacAddr->bytes[2],
1150 (unsigned int *)&pPeerMacAddr->bytes[3],
1151 (unsigned int *)&pPeerMacAddr->bytes[4],
1152 (unsigned int *)&pPeerMacAddr->bytes[5]);
1153
1154 /* The command buffer seems to be fine */
1155 return VOS_STATUS_SUCCESS;
1156}
1157
1158/* Function header left blank Intentionally */
1159static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1160 tANI_U32 limit)
1161{
1162 tANI_U8 len;
1163 tANI_U8 data;
1164
1165 /* skip white space */
1166 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1167 {
1168 command++;
1169 limit--;
1170 }
1171
1172 /* skip element id and element length */
1173 len = 2;
1174
1175 /* extract oui */
1176 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1177 (limit > 1))
1178 {
1179 /* Convert ASCII to decimal */
1180 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1181 ie[len++] = data;
1182 command += 2;
1183 limit -= 2;
1184 }
1185
1186 /* skip white space */
1187 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1188 {
1189 command++;
1190 limit--;
1191 }
1192
1193 /* extract data */
1194 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1195 (limit > 1))
1196 {
1197 /* Convert ASCII to decimal */
1198 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1199 ie[len++] = data;
1200 command += 2;
1201 limit -= 2;
1202 }
1203
1204 /* fill element id and element length */
1205 ie[0] = IE_EID_VENDOR;
1206 ie[1] = len - 2;
1207
1208 return len;
1209}
1210
1211static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1212{
1213 tANI_U32 ieLenPresent = 0;
1214 int left = addIeLen;
1215 v_U8_t *ptr = addIePtr;
1216 v_U8_t elem_id,elem_len;
1217
1218 while(left >= 2)
1219 {
1220 elem_id = ptr[0];
1221 elem_len = ptr[1];
1222 left -= 2;
1223 if(elem_len > left)
1224 {
1225 hddLog(LOGE,
1226 FL("****Invalid elem_len=%d left=%d*****"),
1227 elem_len,left);
1228 return 0;
1229 }
1230 if ((elem_id == IE_EID_VENDOR) &&
1231 (left >= WPA_OUI_TYPE_SIZE))
1232 {
1233 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1234 WPA_OUI_TYPE_SIZE))
1235 {
1236 ieLenPresent += elem_len + 2;
1237 return ieLenPresent;
1238 }
1239 }
1240 ieLenPresent += (elem_len + 2);
1241 left -= elem_len;
1242 ptr += (elem_len + 2);
1243 }
1244 return 0;
1245}
1246
1247#endif /* WLAN_FEATURE_RMC */
1248
Rajeev79dbe4c2013-10-05 11:03:42 +05301249#ifdef FEATURE_WLAN_BATCH_SCAN
1250
1251/**---------------------------------------------------------------------------
1252
1253 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1254 input string
1255
1256 This function extracts assigned integer from string in below format:
1257 "STRING=10" : extracts integer 10 from this string
1258
1259 \param - pInPtr Pointer to input string
1260 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1261 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1262 assigned
1263 \param - pLastArg to tell whether it is last arguement in input string or
1264 not
1265
1266 \return - NULL for failure cases
1267 pointer to next arguement in input string for success cases
1268 --------------------------------------------------------------------------*/
1269static tANI_U8 *
1270hdd_extract_assigned_int_from_str
1271(
1272 tANI_U8 *pInPtr,
1273 tANI_U8 base,
1274 tANI_U32 *pOutPtr,
1275 tANI_U8 *pLastArg
1276)
1277{
1278 int tempInt;
1279 int v = 0;
1280 char buf[32];
1281 int val = 0;
1282 *pLastArg = FALSE;
1283
1284 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1285 if (NULL == pInPtr)
1286 {
1287 return NULL;
1288 }
1289
1290 pInPtr++;
1291
1292 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1293
1294 val = sscanf(pInPtr, "%32s ", buf);
1295 if (val < 0 && val > strlen(pInPtr))
1296 {
1297 return NULL;
1298 }
1299 pInPtr += val;
1300 v = kstrtos32(buf, base, &tempInt);
1301 if (v < 0)
1302 {
1303 return NULL;
1304 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001305 if (tempInt < 0)
1306 {
1307 tempInt = 0;
1308 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301309 *pOutPtr = tempInt;
1310
1311 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1312 if (NULL == pInPtr)
1313 {
1314 *pLastArg = TRUE;
1315 return NULL;
1316 }
1317 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1318
1319 return pInPtr;
1320}
1321
1322/**---------------------------------------------------------------------------
1323
1324 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1325 input string
1326
1327 This function extracts assigned character from string in below format:
1328 "STRING=A" : extracts char 'A' from this string
1329
1330 \param - pInPtr Pointer to input string
1331 \param - pOutPtr Pointer to variable in which extracted char needs to be
1332 assigned
1333 \param - pLastArg to tell whether it is last arguement in input string or
1334 not
1335
1336 \return - NULL for failure cases
1337 pointer to next arguement in input string for success cases
1338 --------------------------------------------------------------------------*/
1339static tANI_U8 *
1340hdd_extract_assigned_char_from_str
1341(
1342 tANI_U8 *pInPtr,
1343 tANI_U8 *pOutPtr,
1344 tANI_U8 *pLastArg
1345)
1346{
1347 *pLastArg = FALSE;
1348
1349 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1350 if (NULL == pInPtr)
1351 {
1352 return NULL;
1353 }
1354
1355 pInPtr++;
1356
1357 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1358
1359 *pOutPtr = *pInPtr;
1360
1361 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1362 if (NULL == pInPtr)
1363 {
1364 *pLastArg = TRUE;
1365 return NULL;
1366 }
1367 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1368
1369 return pInPtr;
1370}
1371
1372
1373/**---------------------------------------------------------------------------
1374
1375 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1376
1377 This function parses set batch scan command in below format:
1378 WLS_BATCHING_SET <space> followed by below arguements
1379 "SCANFREQ=XX" : Optional defaults to 30 sec
1380 "MSCAN=XX" : Required number of scans to attempt to batch
1381 "BESTN=XX" : Best Network (RSSI) defaults to 16
1382 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1383 A. implies only 5 GHz , B. implies only 2.4GHz
1384 "RTT=X" : optional defaults to 0
1385 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1386 error
1387
1388 For example input commands:
1389 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1390 translated into set batch scan with following parameters:
1391 a) Frequence 60 seconds
1392 b) Batch 10 scans together
1393 c) Best RSSI to be 20
1394 d) 5GHz band only
1395 e) RTT is equal to 0
1396
1397 \param - pValue Pointer to input channel list
1398 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1399
1400 \return - 0 for success non-zero for failure
1401
1402 --------------------------------------------------------------------------*/
1403static int
1404hdd_parse_set_batchscan_command
1405(
1406 tANI_U8 *pValue,
1407 tSirSetBatchScanReq *pHddSetBatchScanReq
1408)
1409{
1410 tANI_U8 *inPtr = pValue;
1411 tANI_U8 val = 0;
1412 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301413 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001414 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301415 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1416 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1417 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001418 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301419
Rajeev79dbe4c2013-10-05 11:03:42 +05301420 /*go to space after WLS_BATCHING_SET command*/
1421 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1422 /*no argument after the command*/
1423 if (NULL == inPtr)
1424 {
1425 return -EINVAL;
1426 }
1427
1428 /*no space after the command*/
1429 else if (SPACE_ASCII_VALUE != *inPtr)
1430 {
1431 return -EINVAL;
1432 }
1433
1434 /*removing empty spaces*/
1435 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1436
1437 /*no argument followed by spaces*/
1438 if ('\0' == *inPtr)
1439 {
1440 return -EINVAL;
1441 }
1442
1443 /*check and parse SCANFREQ*/
1444 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1445 {
1446 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001447 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001448
Rajeev Kumarc933d982013-11-18 20:04:20 -08001449 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001450 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001451 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001452 }
1453
Rajeev79dbe4c2013-10-05 11:03:42 +05301454 if ( (NULL == inPtr) || (TRUE == lastArg))
1455 {
1456 return -EINVAL;
1457 }
1458 }
1459
1460 /*check and parse MSCAN*/
1461 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1462 {
1463 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001464 &nMscan, &lastArg);
1465
1466 if (0 == nMscan)
1467 {
1468 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1469 "invalid MSCAN=%d", nMscan);
1470 return -EINVAL;
1471 }
1472
Rajeev79dbe4c2013-10-05 11:03:42 +05301473 if (TRUE == lastArg)
1474 {
1475 goto done;
1476 }
1477 else if (NULL == inPtr)
1478 {
1479 return -EINVAL;
1480 }
1481 }
1482 else
1483 {
1484 return -EINVAL;
1485 }
1486
1487 /*check and parse BESTN*/
1488 if ((strncmp(inPtr, "BESTN", 5) == 0))
1489 {
1490 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001491 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001492
Rajeev Kumarc933d982013-11-18 20:04:20 -08001493 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001494 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001495 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001496 }
1497
Rajeev79dbe4c2013-10-05 11:03:42 +05301498 if (TRUE == lastArg)
1499 {
1500 goto done;
1501 }
1502 else if (NULL == inPtr)
1503 {
1504 return -EINVAL;
1505 }
1506 }
1507
1508 /*check and parse CHANNEL*/
1509 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1510 {
1511 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001512
Rajeev79dbe4c2013-10-05 11:03:42 +05301513 if (('A' == val) || ('a' == val))
1514 {
c_hpothuebf89732014-02-25 13:00:24 +05301515 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301516 }
1517 else if (('B' == val) || ('b' == val))
1518 {
c_hpothuebf89732014-02-25 13:00:24 +05301519 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301520 }
1521 else
1522 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001523 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1524 }
1525
1526 if (TRUE == lastArg)
1527 {
1528 goto done;
1529 }
1530 else if (NULL == inPtr)
1531 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301532 return -EINVAL;
1533 }
1534 }
1535
1536 /*check and parse RTT*/
1537 if ((strncmp(inPtr, "RTT", 3) == 0))
1538 {
1539 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001540 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301541 if (TRUE == lastArg)
1542 {
1543 goto done;
1544 }
1545 if (NULL == inPtr)
1546 {
1547 return -EINVAL;
1548 }
1549 }
1550
1551
1552done:
1553
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001554 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1555 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1556 pHddSetBatchScanReq->bestNetwork = nBestN;
1557 pHddSetBatchScanReq->rfBand = ucRfBand;
1558 pHddSetBatchScanReq->rtt = nRtt;
1559
Rajeev79dbe4c2013-10-05 11:03:42 +05301560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1561 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1562 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1563 pHddSetBatchScanReq->scanFrequency,
1564 pHddSetBatchScanReq->numberOfScansToBatch,
1565 pHddSetBatchScanReq->bestNetwork,
1566 pHddSetBatchScanReq->rfBand,
1567 pHddSetBatchScanReq->rtt);
1568
1569 return 0;
1570}/*End of hdd_parse_set_batchscan_command*/
1571
1572/**---------------------------------------------------------------------------
1573
1574 \brief hdd_set_batch_scan_req_callback () - This function is called after
1575 receiving set batch scan response from FW and it saves set batch scan
1576 response data FW to HDD context and sets the completion event on
1577 which hdd_ioctl is waiting
1578
1579 \param - callbackContext Pointer to HDD adapter
1580 \param - pRsp Pointer to set batch scan response data received from FW
1581
1582 \return - nothing
1583
1584 --------------------------------------------------------------------------*/
1585static void hdd_set_batch_scan_req_callback
1586(
1587 void *callbackContext,
1588 tSirSetBatchScanRsp *pRsp
1589)
1590{
1591 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1592 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1593
1594 /*sanity check*/
1595 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1596 {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 "%s: Invalid pAdapter magic", __func__);
1599 VOS_ASSERT(0);
1600 return;
1601 }
1602 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1603
1604 /*save set batch scan response*/
1605 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1606
1607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1608 "Received set batch scan rsp from FW with nScansToBatch=%d",
1609 pHddSetBatchScanRsp->nScansToBatch);
1610
1611 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1612 complete(&pAdapter->hdd_set_batch_scan_req_var);
1613
1614 return;
1615}/*End of hdd_set_batch_scan_req_callback*/
1616
1617
1618/**---------------------------------------------------------------------------
1619
1620 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1621 info in hdd batch scan response queue
1622
1623 \param - pAdapter Pointer to hdd adapter
1624 \param - pAPMetaInfo Pointer to access point meta info
1625 \param - scanId scan ID of batch scan response
1626 \param - isLastAp tells whether AP is last AP in batch scan response or not
1627
1628 \return - nothing
1629
1630 --------------------------------------------------------------------------*/
1631static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1632 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1633{
1634 tHddBatchScanRsp *pHead;
1635 tHddBatchScanRsp *pNode;
1636 tHddBatchScanRsp *pPrev;
1637 tHddBatchScanRsp *pTemp;
1638 tANI_U8 ssidLen;
1639
1640 /*head of hdd batch scan response queue*/
1641 pHead = pAdapter->pBatchScanRsp;
1642
1643 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1644 if (NULL == pNode)
1645 {
1646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1647 "%s: Could not allocate memory", __func__);
1648 VOS_ASSERT(0);
1649 return;
1650 }
1651
1652 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1653 sizeof(pNode->ApInfo.bssid));
1654 ssidLen = strlen(pApMetaInfo->ssid);
1655 if (SIR_MAX_SSID_SIZE < ssidLen)
1656 {
1657 /*invalid scan result*/
1658 vos_mem_free(pNode);
1659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1660 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1661 return;
1662 }
1663 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1664 /*null terminate ssid*/
1665 pNode->ApInfo.ssid[ssidLen] = '\0';
1666 pNode->ApInfo.ch = pApMetaInfo->ch;
1667 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1668 pNode->ApInfo.age = pApMetaInfo->timestamp;
1669 pNode->ApInfo.batchId = scanId;
1670 pNode->ApInfo.isLastAp = isLastAp;
1671
1672 pNode->pNext = NULL;
1673 if (NULL == pHead)
1674 {
1675 pAdapter->pBatchScanRsp = pNode;
1676 }
1677 else
1678 {
1679 pTemp = pHead;
1680 while (NULL != pTemp)
1681 {
1682 pPrev = pTemp;
1683 pTemp = pTemp->pNext;
1684 }
1685 pPrev->pNext = pNode;
1686 }
1687
1688 return;
1689}/*End of hdd_populate_batch_scan_rsp_queue*/
1690
1691/**---------------------------------------------------------------------------
1692
1693 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1694 receiving batch scan response indication from FW. It saves get batch scan
1695 response data in HDD batch scan response queue. This callback sets the
1696 completion event on which hdd_ioctl is waiting only after getting complete
1697 batch scan response data from FW
1698
1699 \param - callbackContext Pointer to HDD adapter
1700 \param - pRsp Pointer to get batch scan response data received from FW
1701
1702 \return - nothing
1703
1704 --------------------------------------------------------------------------*/
1705static void hdd_batch_scan_result_ind_callback
1706(
1707 void *callbackContext,
1708 void *pRsp
1709)
1710{
1711 v_BOOL_t isLastAp;
1712 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001713 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301714 tANI_U32 numberScanList;
1715 tANI_U32 nextScanListOffset;
1716 tANI_U32 nextApMetaInfoOffset;
1717 hdd_adapter_t* pAdapter;
1718 tpSirBatchScanList pScanList;
1719 tpSirBatchScanNetworkInfo pApMetaInfo;
1720 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1721 tSirSetBatchScanReq *pReq;
1722
1723 pAdapter = (hdd_adapter_t *)callbackContext;
1724 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001725 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301726 {
1727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1728 "%s: Invalid pAdapter magic", __func__);
1729 VOS_ASSERT(0);
1730 return;
1731 }
1732
1733 /*initialize locals*/
1734 pReq = &pAdapter->hddSetBatchScanReq;
1735 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1736 isLastAp = FALSE;
1737 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001738 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301739 numberScanList = 0;
1740 nextScanListOffset = 0;
1741 nextApMetaInfoOffset = 0;
1742 pScanList = NULL;
1743 pApMetaInfo = NULL;
1744
1745 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1746 {
1747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1748 "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq);
1749 isLastAp = TRUE;
1750 goto done;
1751 }
1752
1753 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1755 "Batch scan rsp: numberScalList %d", numberScanList);
1756
1757 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1758 {
1759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1760 "%s: numberScanList %d", __func__, numberScanList);
1761 isLastAp = TRUE;
1762 goto done;
1763 }
1764
1765 while (numberScanList)
1766 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001767 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301768 nextScanListOffset);
1769 if (NULL == pScanList)
1770 {
1771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1772 "%s: pScanList is %p", __func__, pScanList);
1773 isLastAp = TRUE;
1774 goto done;
1775 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001776 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001778 "Batch scan rsp: numApMetaInfo %d scanId %d",
1779 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301780
1781 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1782 {
1783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1784 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1785 isLastAp = TRUE;
1786 goto done;
1787 }
1788
Rajeev Kumarce651e42013-10-21 18:57:15 -07001789 /*Initialize next AP meta info offset for next scan list*/
1790 nextApMetaInfoOffset = 0;
1791
Rajeev79dbe4c2013-10-05 11:03:42 +05301792 while (numApMetaInfo)
1793 {
1794 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1795 nextApMetaInfoOffset);
1796 if (NULL == pApMetaInfo)
1797 {
1798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1799 "%s: pApMetaInfo is %p", __func__, pApMetaInfo);
1800 isLastAp = TRUE;
1801 goto done;
1802 }
1803 /*calculate AP age*/
1804 pApMetaInfo->timestamp =
1805 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1806
1807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001808 "%s: bssId "MAC_ADDRESS_STR
1809 " ch %d rssi %d timestamp %d", __func__,
1810 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1811 pApMetaInfo->ch, pApMetaInfo->rssi,
1812 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301813
1814 /*mark last AP in batch scan response*/
1815 if ((TRUE == pBatchScanRsp->isLastResult) &&
1816 (1 == numberScanList) && (1 == numApMetaInfo))
1817 {
1818 isLastAp = TRUE;
1819 }
1820
1821 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1822 /*store batch scan repsonse in hdd queue*/
1823 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1824 pScanList->scanId, isLastAp);
1825 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1826
1827 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1828 numApMetaInfo--;
1829 }
1830
Rajeev Kumarce651e42013-10-21 18:57:15 -07001831 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1832 + (sizeof(tSirBatchScanNetworkInfo)
1833 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301834 numberScanList--;
1835 }
1836
1837done:
1838
1839 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1840 requested from hdd_ioctl*/
1841 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1842 (TRUE == isLastAp))
1843 {
1844 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1845 complete(&pAdapter->hdd_get_batch_scan_req_var);
1846 }
1847
1848 return;
1849}/*End of hdd_batch_scan_result_ind_callback*/
1850
1851/**---------------------------------------------------------------------------
1852
1853 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1854 response as per batch scan FR request format by putting proper markers
1855
1856 \param - pDest pointer to destination buffer
1857 \param - cur_len current length
1858 \param - tot_len total remaining size which can be written to user space
1859 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1860 \param - pAdapter Pointer to HDD adapter
1861
1862 \return - ret no of characters written
1863
1864 --------------------------------------------------------------------------*/
1865static tANI_U32
1866hdd_format_batch_scan_rsp
1867(
1868 tANI_U8 *pDest,
1869 tANI_U32 cur_len,
1870 tANI_U32 tot_len,
1871 tHddBatchScanRsp *pApMetaInfo,
1872 hdd_adapter_t* pAdapter
1873)
1874{
1875 tANI_U32 ret = 0;
1876 tANI_U32 rem_len = 0;
1877 tANI_U8 temp_len = 0;
1878 tANI_U8 temp_total_len = 0;
1879 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1880 tANI_U8 *pTemp = temp;
1881
1882 /*Batch scan reponse needs to be returned to user space in
1883 following format:
1884 "scancount=X\n" where X is the number of scans in current batch
1885 batch
1886 "trunc\n" optional present if current scan truncated
1887 "bssid=XX:XX:XX:XX:XX:XX\n"
1888 "ssid=XXXX\n"
1889 "freq=X\n" frequency in Mhz
1890 "level=XX\n"
1891 "age=X\n" ms
1892 "dist=X\n" cm (-1 if not available)
1893 "errror=X\n" (-1if not available)
1894 "====\n" (end of ap marker)
1895 "####\n" (end of scan marker)
1896 "----\n" (end of results)*/
1897 /*send scan result in above format to user space based on
1898 available length*/
1899 /*The GET response may have more data than the driver can return in its
1900 buffer. In that case the buffer should be filled to the nearest complete
1901 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1902 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1903 The final buffer should end with "----\n"*/
1904
1905 /*sanity*/
1906 if (cur_len > tot_len)
1907 {
1908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1909 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1910 return 0;
1911 }
1912 else
1913 {
1914 rem_len = (tot_len - cur_len);
1915 }
1916
1917 /*end scan marker*/
1918 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1919 {
1920 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1921 pTemp += temp_len;
1922 temp_total_len += temp_len;
1923 }
1924
1925 /*bssid*/
1926 temp_len = snprintf(pTemp, sizeof(temp),
1927 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1928 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1929 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1930 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1931 pTemp += temp_len;
1932 temp_total_len += temp_len;
1933
1934 /*ssid*/
1935 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1936 pApMetaInfo->ApInfo.ssid);
1937 pTemp += temp_len;
1938 temp_total_len += temp_len;
1939
1940 /*freq*/
1941 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001942 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301943 pTemp += temp_len;
1944 temp_total_len += temp_len;
1945
1946 /*level*/
1947 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1948 pApMetaInfo->ApInfo.rssi);
1949 pTemp += temp_len;
1950 temp_total_len += temp_len;
1951
1952 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001953 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301954 pApMetaInfo->ApInfo.age);
1955 pTemp += temp_len;
1956 temp_total_len += temp_len;
1957
1958 /*dist*/
1959 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1960 pTemp += temp_len;
1961 temp_total_len += temp_len;
1962
1963 /*error*/
1964 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
1965 pTemp += temp_len;
1966 temp_total_len += temp_len;
1967
1968 /*end AP marker*/
1969 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
1970 pTemp += temp_len;
1971 temp_total_len += temp_len;
1972
1973 /*last AP in batch scan response*/
1974 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
1975 {
1976 /*end scan marker*/
1977 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
1978 pTemp += temp_len;
1979 temp_total_len += temp_len;
1980
1981 /*end batch scan result marker*/
1982 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
1983 pTemp += temp_len;
1984 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08001985
Rajeev79dbe4c2013-10-05 11:03:42 +05301986 }
1987
1988 if (temp_total_len < rem_len)
1989 {
1990 ret = temp_total_len + 1;
1991 strlcpy(pDest, temp, ret);
1992 pAdapter->isTruncated = FALSE;
1993 }
1994 else
1995 {
1996 pAdapter->isTruncated = TRUE;
1997 if (rem_len >= strlen("%%%%"))
1998 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001999 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302000 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002001 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302002 {
2003 ret = 0;
2004 }
2005 }
2006
2007 return ret;
2008
2009}/*End of hdd_format_batch_scan_rsp*/
2010
2011/**---------------------------------------------------------------------------
2012
2013 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2014 buffer starting with head of hdd batch scan response queue
2015
2016 \param - pAdapter Pointer to HDD adapter
2017 \param - pDest Pointer to user data buffer
2018 \param - cur_len current offset in user buffer
2019 \param - rem_len remaining no of bytes in user buffer
2020
2021 \return - number of bytes written in user buffer
2022
2023 --------------------------------------------------------------------------*/
2024
2025tANI_U32 hdd_populate_user_batch_scan_rsp
2026(
2027 hdd_adapter_t* pAdapter,
2028 tANI_U8 *pDest,
2029 tANI_U32 cur_len,
2030 tANI_U32 rem_len
2031)
2032{
2033 tHddBatchScanRsp *pHead;
2034 tHddBatchScanRsp *pPrev;
2035 tANI_U32 len;
2036
Rajeev79dbe4c2013-10-05 11:03:42 +05302037 pAdapter->isTruncated = FALSE;
2038
2039 /*head of hdd batch scan response queue*/
2040 pHead = pAdapter->pBatchScanRsp;
2041 while (pHead)
2042 {
2043 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2044 pAdapter);
2045 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002046 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302047 cur_len += len;
2048 if(TRUE == pAdapter->isTruncated)
2049 {
2050 /*result is truncated return rest of scan rsp in next req*/
2051 cur_len = rem_len;
2052 break;
2053 }
2054 pPrev = pHead;
2055 pHead = pHead->pNext;
2056 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002057 if (TRUE == pPrev->ApInfo.isLastAp)
2058 {
2059 pAdapter->prev_batch_id = 0;
2060 }
2061 else
2062 {
2063 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2064 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302065 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002066 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302067 }
2068
2069 return cur_len;
2070}/*End of hdd_populate_user_batch_scan_rsp*/
2071
2072/**---------------------------------------------------------------------------
2073
2074 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2075 scan response data from HDD queue to user space
2076 It does following in detail:
2077 a) if HDD has enough data in its queue then it 1st copies data to user
2078 space and then send get batch scan indication message to FW. In this
2079 case it does not wait on any event and batch scan response data will
2080 be populated in HDD response queue in MC thread context after receiving
2081 indication from FW
2082 b) else send get batch scan indication message to FW and wait on an event
2083 which will be set once HDD receives complete batch scan response from
2084 FW and then this function returns batch scan response to user space
2085
2086 \param - pAdapter Pointer to HDD adapter
2087 \param - pPrivData Pointer to priv_data
2088
2089 \return - 0 for success -EFAULT for failure
2090
2091 --------------------------------------------------------------------------*/
2092
2093int hdd_return_batch_scan_rsp_to_user
2094(
2095 hdd_adapter_t* pAdapter,
2096 hdd_priv_data_t *pPrivData,
2097 tANI_U8 *command
2098)
2099{
2100 tANI_U8 *pDest;
2101 tANI_U32 count = 0;
2102 tANI_U32 len = 0;
2103 tANI_U32 cur_len = 0;
2104 tANI_U32 rem_len = 0;
2105 eHalStatus halStatus;
2106 unsigned long rc;
2107 tSirTriggerBatchScanResultInd *pReq;
2108
2109 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2110 pReq->param = 0;/*batch scan client*/
2111 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2112 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2113
2114 cur_len = pPrivData->used_len;
2115 if (pPrivData->total_len > pPrivData->used_len)
2116 {
2117 rem_len = pPrivData->total_len - pPrivData->used_len;
2118 }
2119 else
2120 {
2121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2122 "%s: Invalid user data buffer total_len %d used_len %d",
2123 __func__, pPrivData->total_len, pPrivData->used_len);
2124 return -EFAULT;
2125 }
2126
2127 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2128 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2129 cur_len, rem_len);
2130 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2131
2132 /*enough scan result available in cache to return to user space or
2133 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002134 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302135 {
2136 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2137 halStatus = sme_TriggerBatchScanResultInd(
2138 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2139 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2140 pAdapter);
2141 if ( eHAL_STATUS_SUCCESS == halStatus )
2142 {
2143 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2144 {
2145 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2146 rc = wait_for_completion_timeout(
2147 &pAdapter->hdd_get_batch_scan_req_var,
2148 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302149 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302150 {
2151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302152 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2153 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302154 return -EFAULT;
2155 }
2156 }
2157
2158 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002159 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302160 pDest += len;
2161 cur_len += len;
2162
2163 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2164 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2165 cur_len, rem_len);
2166 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2167
2168 count = 0;
2169 len = (len - pPrivData->used_len);
2170 pDest = (command + pPrivData->used_len);
2171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002172 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302173 while(count < len)
2174 {
2175 printk("%c", *(pDest + count));
2176 count++;
2177 }
2178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2179 "%s: copy %d data to user buffer", __func__, len);
2180 if (copy_to_user(pPrivData->buf, pDest, len))
2181 {
2182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2183 "%s: failed to copy data to user buffer", __func__);
2184 return -EFAULT;
2185 }
2186 }
2187 else
2188 {
2189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2190 "sme_GetBatchScanScan returned failure halStatus %d",
2191 halStatus);
2192 return -EINVAL;
2193 }
2194 }
2195 else
2196 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302197 count = 0;
2198 len = (len - pPrivData->used_len);
2199 pDest = (command + pPrivData->used_len);
2200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002201 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302202 while(count < len)
2203 {
2204 printk("%c", *(pDest + count));
2205 count++;
2206 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2208 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302209 if (copy_to_user(pPrivData->buf, pDest, len))
2210 {
2211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2212 "%s: failed to copy data to user buffer", __func__);
2213 return -EFAULT;
2214 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302215 }
2216
2217 return 0;
2218} /*End of hdd_return_batch_scan_rsp_to_user*/
2219
Rajeev Kumar8b373292014-01-08 20:36:55 -08002220/**---------------------------------------------------------------------------
2221
2222 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2223 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2224 WLS_BATCHING VERSION
2225 WLS_BATCHING SET
2226 WLS_BATCHING GET
2227 WLS_BATCHING STOP
2228
2229 \param - pAdapter Pointer to HDD adapter
2230 \param - pPrivdata Pointer to priv_data
2231 \param - command Pointer to command
2232
2233 \return - 0 for success -EFAULT for failure
2234
2235 --------------------------------------------------------------------------*/
2236
2237int hdd_handle_batch_scan_ioctl
2238(
2239 hdd_adapter_t *pAdapter,
2240 hdd_priv_data_t *pPrivdata,
2241 tANI_U8 *command
2242)
2243{
2244 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002245 hdd_context_t *pHddCtx;
2246
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302247 ENTER();
2248
Yue Mae36e3552014-03-05 17:06:20 -08002249 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2250 ret = wlan_hdd_validate_context(pHddCtx);
2251 if (ret)
2252 {
Yue Mae36e3552014-03-05 17:06:20 -08002253 goto exit;
2254 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002255
2256 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2257 {
2258 char extra[32];
2259 tANI_U8 len = 0;
2260 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2261
2262 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2263 {
2264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2265 "%s: Batch scan feature is not supported by FW", __func__);
2266 ret = -EINVAL;
2267 goto exit;
2268 }
2269
2270 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2271 version);
2272 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2273 {
2274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2275 "%s: failed to copy data to user buffer", __func__);
2276 ret = -EFAULT;
2277 goto exit;
2278 }
2279 ret = HDD_BATCH_SCAN_VERSION;
2280 }
2281 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2282 {
2283 int status;
2284 tANI_U8 *value = (command + 16);
2285 eHalStatus halStatus;
2286 unsigned long rc;
2287 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2288 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2289
2290 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2291 {
2292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2293 "%s: Batch scan feature is not supported by FW", __func__);
2294 ret = -EINVAL;
2295 goto exit;
2296 }
2297
2298 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2299 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2300 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2301 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2302 {
2303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302304 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002305 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302306 hdd_device_modetoString(pAdapter->device_mode),
2307 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002308 ret = -EINVAL;
2309 goto exit;
2310 }
2311
2312 status = hdd_parse_set_batchscan_command(value, pReq);
2313 if (status)
2314 {
2315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2316 "Invalid WLS_BATCHING SET command");
2317 ret = -EINVAL;
2318 goto exit;
2319 }
2320
2321
2322 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2323 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2324 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2325 pAdapter);
2326
2327 if ( eHAL_STATUS_SUCCESS == halStatus )
2328 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302329 char extra[32];
2330 tANI_U8 len = 0;
2331 tANI_U8 mScan = 0;
2332
Rajeev Kumar8b373292014-01-08 20:36:55 -08002333 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2334 "sme_SetBatchScanReq returned success halStatus %d",
2335 halStatus);
2336 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2337 {
2338 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2339 rc = wait_for_completion_timeout(
2340 &pAdapter->hdd_set_batch_scan_req_var,
2341 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2342 if (0 == rc)
2343 {
2344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2345 "%s: Timeout waiting for set batch scan to complete",
2346 __func__);
2347 ret = -EINVAL;
2348 goto exit;
2349 }
2350 }
2351 if ( !pRsp->nScansToBatch )
2352 {
2353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2354 "%s: Received set batch scan failure response from FW",
2355 __func__);
2356 ret = -EINVAL;
2357 goto exit;
2358 }
2359 /*As per the Batch Scan Framework API we should return the MIN of
2360 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302361 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002362
2363 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2364
2365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2366 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302367 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2368 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2369 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2370 {
2371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2372 "%s: failed to copy MSCAN value to user buffer", __func__);
2373 ret = -EFAULT;
2374 goto exit;
2375 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002376 }
2377 else
2378 {
2379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2380 "sme_SetBatchScanReq returned failure halStatus %d",
2381 halStatus);
2382 ret = -EINVAL;
2383 goto exit;
2384 }
2385 }
2386 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2387 {
2388 eHalStatus halStatus;
2389 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2390 pInd->param = 0;
2391
2392 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2393 {
2394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2395 "%s: Batch scan feature is not supported by FW", __func__);
2396 ret = -EINVAL;
2397 goto exit;
2398 }
2399
2400 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2401 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002403 "Batch scan is not yet enabled batch scan state %d",
2404 pAdapter->batchScanState);
2405 ret = -EINVAL;
2406 goto exit;
2407 }
2408
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002409 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2410 hdd_deinit_batch_scan(pAdapter);
2411 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2412
Rajeev Kumar8b373292014-01-08 20:36:55 -08002413 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2414
2415 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2416 pAdapter->sessionId);
2417 if ( eHAL_STATUS_SUCCESS == halStatus )
2418 {
2419 ret = 0;
2420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2421 "sme_StopBatchScanInd returned success halStatus %d",
2422 halStatus);
2423 }
2424 else
2425 {
2426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2427 "sme_StopBatchScanInd returned failure halStatus %d",
2428 halStatus);
2429 ret = -EINVAL;
2430 goto exit;
2431 }
2432 }
2433 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2434 {
2435 tANI_U32 remain_len;
2436
2437 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2438 {
2439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2440 "%s: Batch scan feature is not supported by FW", __func__);
2441 ret = -EINVAL;
2442 goto exit;
2443 }
2444
2445 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2446 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002448 "Batch scan is not yet enabled could not return results"
2449 "Batch Scan state %d",
2450 pAdapter->batchScanState);
2451 ret = -EINVAL;
2452 goto exit;
2453 }
2454
2455 pPrivdata->used_len = 16;
2456 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2457 if (remain_len < pPrivdata->total_len)
2458 {
2459 /*Clear previous batch scan response data if any*/
2460 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2461 }
2462 else
2463 {
2464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2465 "Invalid total length from user space can't fetch batch"
2466 " scan response total_len %d used_len %d remain len %d",
2467 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2468 ret = -EINVAL;
2469 goto exit;
2470 }
2471 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2472 }
2473
2474exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302475 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002476 return ret;
2477}
2478
2479
Rajeev79dbe4c2013-10-05 11:03:42 +05302480#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2481
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302482#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2483/**
2484 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2485 * to Handoff request
2486 * @handoffInfo: Pointer to Handoff request
2487 * @src: enum of handoff_src
2488 * Return: None
2489 */
2490#ifndef QCA_WIFI_ISOC
2491static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2492 *handoffInfo, handoff_src src)
2493{
2494 handoffInfo->src = src;
2495}
2496#else
2497static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2498 *handoffInfo, handoff_src src)
2499{
2500}
2501#endif
2502
2503/**
2504 * hdd_reassoc() - perform a userspace-directed reassoc
2505 *
2506 * @pAdapter: Adapter upon which the command was received
2507 * @bssid: BSSID with which to reassociate
2508 * @channel: channel upon which to reassociate
2509 *
2510 * Return: 0 for success non-zero for failure
2511 */
2512#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
2513static int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
2514 const tANI_U8 channel)
2515{
2516 hdd_station_ctx_t *pHddStaCtx;
2517 tCsrHandoffRequest handoffInfo;
2518 hdd_context_t *pHddCtx = NULL;
2519 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2520
2521 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2522
2523 /* if not associated, no need to proceed with reassoc */
2524 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2525 hddLog(LOG1, FL("Not associated"));
2526 return -EINVAL;
2527 }
2528
2529 /* if the target bssid is same as currently associated AP,
2530 then no need to proceed with reassoc */
2531 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2532 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2533 return -EINVAL;
2534 }
2535
2536 /* Check channel number is a valid channel number */
2537 if (VOS_STATUS_SUCCESS !=
2538 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2539 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2540 return -EINVAL;
2541 }
2542
2543 /* Proceed with reassoc */
2544 handoffInfo.channel = channel;
2545 hdd_assign_handoff_src_reassoc(&handoffInfo, REASSOC);
2546 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2547 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2548 return 0;
2549}
2550#else
2551static int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
2552 const tANI_U8 channel)
2553{
2554 return -EPERM;
2555}
2556#endif
2557
2558/**
2559 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2560 * This function parses the v1 REASSOC command with the format
2561 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2562 * Hex-ASCII representation of the BSSID and CH is the ASCII
2563 * representation of the channel. For example
2564 * REASSOC 00:0a:0b:11:22:33 48
2565 *
2566 * @pAdapter: Adapter upon which the command was received
2567 * @command: ASCII text command that was received
2568 *
2569 * Return: 0 for success non-zero for failure
2570 */
2571static int
2572hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2573{
2574 tANI_U8 channel = 0;
2575 tSirMacAddr bssid;
2576 int ret;
2577
2578 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2579 if (ret)
2580 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2581 else
2582 ret = hdd_reassoc(pAdapter, bssid, channel);
2583
2584 return ret;
2585}
2586
2587/**
2588 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2589 * This function parses the v2 REASSOC command with the format
2590 * REASSOC <android_wifi_reassoc_params>
2591 *
2592 * @pAdapter: Adapter upon which the command was received
2593 * @command: command that was received, ASCII command followed
2594 * by binary data
2595 *
2596 * Return: 0 for success non-zero for failure
2597 */
2598static int
2599hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command)
2600{
2601 struct android_wifi_reassoc_params params;
2602 tSirMacAddr bssid;
2603 int ret;
2604
2605 /* The params are located after "REASSOC " */
2606 memcpy(&params, command + 8, sizeof(params));
2607
2608 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2609 hddLog(LOGE, FL("MAC address parsing failed"));
2610 ret = -EINVAL;
2611 } else {
2612 ret = hdd_reassoc(pAdapter, bssid, params.channel);
2613 }
2614 return ret;
2615}
2616
2617/**
2618 * hdd_parse_reassoc() - parse the REASSOC command
2619 * There are two different versions of the REASSOC command.Version 1
2620 * of the command contains a parameter list that is ASCII characters
2621 * whereas version 2 contains a combination of ASCII and binary
2622 * payload. Determine if a version 1 or a version 2 command is being
2623 * parsed by examining the parameters, and then dispatch the parser
2624 * that is appropriate for the command.
2625 *
2626 * @pAdapter: Adapter upon which the command was received
2627 * @command: command that was received
2628 *
2629 * Return: 0 for success non-zero for failure
2630 */
2631static int
2632hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command)
2633{
2634 int ret;
2635
2636 /*
2637 * both versions start with "REASSOC"
2638 * v1 has a bssid and channel # as an ASCII string
2639 * REASSOC xx:xx:xx:xx:xx:xx CH
2640 * v2 has a C struct
2641 * REASSOC <binary c struct>
2642 *
2643 * The first field in the v2 struct is also the bssid in ASCII.
2644 * But in the case of a v2 message the BSSID is NUL-terminated.
2645 * Hence we can peek at that offset to see if this is V1 or V2
2646 * REASSOC xx:xx:xx:xx:xx:xx*
2647 * 1111111111222222
2648 * 01234567890123456789012345
2649 */
2650 if (command[25])
2651 ret = hdd_parse_reassoc_v1(pAdapter, command);
2652 else
2653 ret = hdd_parse_reassoc_v2(pAdapter, command);
2654
2655 return ret;
2656}
2657#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2658
c_hpothu92367912014-05-01 15:18:17 +05302659static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
2660{
c_hpothu39eb1e32014-06-26 16:31:50 +05302661 bcnMissRateContext_t *pCBCtx;
2662
2663 if (NULL == data)
2664 {
2665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2666 return;
2667 }
c_hpothu92367912014-05-01 15:18:17 +05302668
2669 /* there is a race condition that exists between this callback
2670 function and the caller since the caller could time out either
2671 before or while this code is executing. we use a spinlock to
2672 serialize these actions */
2673 spin_lock(&hdd_context_lock);
2674
c_hpothu39eb1e32014-06-26 16:31:50 +05302675 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05302676 gbcnMissRate = -1;
2677
c_hpothu39eb1e32014-06-26 16:31:50 +05302678 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05302679 {
2680 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05302681 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05302682 spin_unlock(&hdd_context_lock);
2683 return ;
2684 }
2685
2686 if (VOS_STATUS_SUCCESS == status)
2687 {
c_hpothu39eb1e32014-06-26 16:31:50 +05302688 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05302689 }
c_hpothu39eb1e32014-06-26 16:31:50 +05302690 else
2691 {
2692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
2693 }
2694
c_hpothu92367912014-05-01 15:18:17 +05302695 complete(&(pCBCtx->completion));
2696 spin_unlock(&hdd_context_lock);
2697
2698 return;
2699}
2700
Abhishek Singh08aa7762014-12-16 13:59:03 +05302701void hdd_FWStatisCB( VOS_STATUS status,
2702 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05302703{
2704 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302705 hdd_adapter_t *pAdapter;
2706
2707 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
2708
Abhishek Singh08aa7762014-12-16 13:59:03 +05302709 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302710 {
2711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2712 return;
2713 }
2714 /* there is a race condition that exists between this callback
2715 function and the caller since the caller could time out either
2716 before or while this code is executing. we use a spinlock to
2717 serialize these actions */
2718 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05302719 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302720 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
2721 {
2722 hddLog(VOS_TRACE_LEVEL_ERROR,
2723 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2724 spin_unlock(&hdd_context_lock);
2725 return;
2726 }
2727 pAdapter = fwStatsCtx->pAdapter;
2728 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2729 {
2730 hddLog(VOS_TRACE_LEVEL_ERROR,
2731 FL("pAdapter returned is NULL or invalid"));
2732 spin_unlock(&hdd_context_lock);
2733 return;
2734 }
2735 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302736 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302737 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302738 switch( fwStatsResult->type )
2739 {
2740 case FW_UBSP_STATS:
2741 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302742 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302743 hddLog(VOS_TRACE_LEVEL_INFO,
2744 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302745 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2746 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302747 }
2748 break;
2749 default:
2750 {
2751 hddLog(VOS_TRACE_LEVEL_ERROR,
2752 FL(" No handling for stats type %d"),fwStatsResult->type);
2753 }
2754 }
2755 }
2756 complete(&(fwStatsCtx->completion));
2757 spin_unlock(&hdd_context_lock);
2758 return;
2759}
2760
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302761static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2762{
2763 int ret = 0;
2764
2765 if (!pCfg || !command || !extra || !len)
2766 {
2767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2768 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2769 ret = -EINVAL;
2770 return ret;
2771 }
2772
2773 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2774 {
2775 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2776 (int)pCfg->nActiveMaxChnTime);
2777 return ret;
2778 }
2779 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2780 {
2781 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2782 (int)pCfg->nActiveMinChnTime);
2783 return ret;
2784 }
2785 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2786 {
2787 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2788 (int)pCfg->nPassiveMaxChnTime);
2789 return ret;
2790 }
2791 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2792 {
2793 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2794 (int)pCfg->nPassiveMinChnTime);
2795 return ret;
2796 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302797 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2798 {
2799 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2800 (int)pCfg->nActiveMaxChnTime);
2801 return ret;
2802 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302803 else
2804 {
2805 ret = -EINVAL;
2806 }
2807
2808 return ret;
2809}
2810
2811static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2812{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302813 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302814 hdd_config_t *pCfg;
2815 tANI_U8 *value = command;
2816 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302817 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302818
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302819 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2820 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302821 {
2822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2823 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2824 ret = -EINVAL;
2825 return ret;
2826 }
2827
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302828 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2829 sme_GetConfigParam(hHal, &smeConfig);
2830
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302831 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2832 {
2833 value = value + 24;
2834 temp = kstrtou32(value, 10, &val);
2835 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2836 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2837 {
2838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2839 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2840 ret = -EFAULT;
2841 return ret;
2842 }
2843 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302844 smeConfig.csrConfig.nActiveMaxChnTime = val;
2845 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302846 }
2847 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2848 {
2849 value = value + 24;
2850 temp = kstrtou32(value, 10, &val);
2851 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2852 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2853 {
2854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2855 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2856 ret = -EFAULT;
2857 return ret;
2858 }
2859 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302860 smeConfig.csrConfig.nActiveMinChnTime = val;
2861 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302862 }
2863 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2864 {
2865 value = value + 25;
2866 temp = kstrtou32(value, 10, &val);
2867 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2868 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2869 {
2870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2871 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2872 ret = -EFAULT;
2873 return ret;
2874 }
2875 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302876 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2877 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302878 }
2879 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2880 {
2881 value = value + 25;
2882 temp = kstrtou32(value, 10, &val);
2883 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2884 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2885 {
2886 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2887 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2888 ret = -EFAULT;
2889 return ret;
2890 }
2891 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302892 smeConfig.csrConfig.nPassiveMinChnTime = val;
2893 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302894 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302895 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2896 {
2897 value = value + 13;
2898 temp = kstrtou32(value, 10, &val);
2899 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2900 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2901 {
2902 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2903 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2904 ret = -EFAULT;
2905 return ret;
2906 }
2907 pCfg->nActiveMaxChnTime = val;
2908 smeConfig.csrConfig.nActiveMaxChnTime = val;
2909 sme_UpdateConfig(hHal, &smeConfig);
2910 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302911 else
2912 {
2913 ret = -EINVAL;
2914 }
2915
2916 return ret;
2917}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302918static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2919 tANI_U8 cmd_len)
2920{
2921 tANI_U8 *value;
2922 tANI_U8 fcc_constraint;
2923
2924 eHalStatus status;
2925 int ret = 0;
2926 value = cmd + cmd_len + 1;
2927
2928 ret = kstrtou8(value, 10, &fcc_constraint);
2929 if ((ret < 0) || (fcc_constraint > 1)) {
2930 /*
2931 * If the input value is greater than max value of datatype,
2932 * then also it is a failure
2933 */
2934 hddLog(VOS_TRACE_LEVEL_ERROR,
2935 "%s: value out of range", __func__);
2936 return -EINVAL;
2937 }
2938
2939 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2940 if (status != eHAL_STATUS_SUCCESS)
2941 ret = -EPERM;
2942
2943 return ret;
2944}
2945
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302946/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302947
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302948 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
2949 FW will send *ONE* CA ind to Host(even though it is duplicate).
2950 When Host send IOCTL (disable), FW doesn't perform any action.
2951 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
2952 sends CA ind to host. (regard less of IOCTL status)
2953 \param - pHddCtx - HDD context
2954 \param - command - command received from framework
2955 \param - cmd_len - len of the command
2956
2957 \return - 0 on success, appropriate error values on failure.
2958
2959 --------------------------------------------------------------------------*/
2960int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
2961{
2962 tANI_U8 set_value;
2963 int ret = 0;
2964 eHalStatus status;
2965
2966 ret = wlan_hdd_validate_context(pHddCtx);
2967 if (0 != ret)
2968 {
2969 ret = -EINVAL;
2970 goto exit;
2971 }
2972
2973 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
2974 {
2975 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
2976 " ini param to control channel avooidance indication");
2977 ret = 0;
2978 goto exit;
2979 }
2980
2981 set_value = command[cmd_len + 1] - '0';
2982 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
2983 if (status != eHAL_STATUS_SUCCESS)
2984 {
2985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
2986 " enableDisableChanAoidance command to SME\n", __func__);
2987 ret = -EINVAL;
2988 }
2989
2990exit:
2991 return ret;
2992}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302993
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05302994/**
2995 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
2996 * @pHddCtx: Pointer to the HDD context
2997 * @channel: channel to reassociate
2998 * @targetApBssid: Target AP/BSSID to reassociate
2999 *
3000 * Return: None
3001 */
3002#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3003static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3004 uint8_t channel, tSirMacAddr targetApBssid)
3005{
3006 tCsrHandoffRequest handoffInfo;
3007 handoffInfo.channel = channel;
3008 handoffInfo.src = FASTREASSOC;
3009 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3010 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3011}
3012#else
3013static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3014 uint8_t channel, tSirMacAddr targetApBssid)
3015{
3016}
3017#endif
3018
3019/**
3020 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3021 * @pAdapter: Pointer to HDD adapter
3022 * @channel: Channel to scan/roam
3023 * @targetApBssid: BSSID to roam
3024 *
3025 * Return: None
3026 */
3027#ifdef QCA_WIFI_ISOC
3028static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3029 uint8_t channel, tSirMacAddr targetApBssid)
3030{
3031 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3032 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3033}
3034#else
3035static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3036 uint8_t channel, tSirMacAddr targetApBssid)
3037{
3038}
3039#endif
3040
3041/**
3042 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3043 * @pAdapter: pointer to hdd adapter
3044 * @command: pointer to the command received
3045 *
3046 * Return: VOS_STATUS enum
3047 */
3048static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3049 uint8_t *command)
3050{
3051 tANI_U8 *value = command;
3052 tANI_U8 channel = 0;
3053 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303054 hdd_station_ctx_t *pHddStaCtx = NULL;
3055 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303056 int ret;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303057 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3058 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3059
3060 /* if not associated, no need to proceed with reassoc */
3061 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3062 hddLog(LOG1, FL("Not associated!"));
3063 return eHAL_STATUS_FAILURE;
3064 }
3065
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303066 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3067 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303068 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3069 return eHAL_STATUS_FAILURE;
3070 }
3071
3072 /* if the target bssid is same as currently associated AP,
3073 then no need to proceed with reassoc */
3074 if (vos_mem_compare(targetApBssid,
3075 pHddStaCtx->conn_info.bssId,
3076 sizeof(tSirMacAddr))) {
3077 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
3078 return eHAL_STATUS_FAILURE;
3079 }
3080
3081 /* Check channel number is a valid channel number */
3082 if (VOS_STATUS_SUCCESS !=
3083 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3084 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3085 return eHAL_STATUS_FAILURE;
3086 }
3087
3088 /* Proceed with reassoc */
3089 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3090
3091 /* Proceed with scan/roam */
3092 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3093
3094 return eHAL_STATUS_SUCCESS;
3095}
3096
3097/**
3098 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3099 * @handoffInfo: Pointer to the csr Handoff Request.
3100 *
3101 * Return: None
3102 */
3103#ifndef QCA_WIFI_ISOC
3104static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3105{
3106 handoffInfo->src = REASSOC;
3107}
3108#else
3109static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3110{
3111}
3112#endif
3113
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003114static int hdd_driver_command(hdd_adapter_t *pAdapter,
3115 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003116{
Jeff Johnson295189b2012-06-20 16:38:30 -07003117 hdd_priv_data_t priv_data;
3118 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303119 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3120 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003121 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303122 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303123#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3124 struct cfg80211_mgmt_tx_params params;
3125#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303126
3127 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003128 /*
3129 * Note that valid pointers are provided by caller
3130 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003131
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003132 /* copy to local struct to avoid numerous changes to legacy code */
3133 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003134
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003135 if (priv_data.total_len <= 0 ||
3136 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003137 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003138 hddLog(VOS_TRACE_LEVEL_WARN,
3139 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3140 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003141 ret = -EINVAL;
3142 goto exit;
3143 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303144 status = wlan_hdd_validate_context(pHddCtx);
3145 if (0 != status)
3146 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303147 ret = -EINVAL;
3148 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303149 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003150 /* Allocate +1 for '\0' */
3151 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003152 if (!command)
3153 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003154 hddLog(VOS_TRACE_LEVEL_ERROR,
3155 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003156 ret = -ENOMEM;
3157 goto exit;
3158 }
3159
3160 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3161 {
3162 ret = -EFAULT;
3163 goto exit;
3164 }
3165
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003166 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003167 command[priv_data.total_len] = '\0';
3168
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003169 /* at one time the following block of code was conditional. braces
3170 * have been retained to avoid re-indenting the legacy code
3171 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003172 {
3173 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3174
3175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003176 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003177
3178 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3179 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303180 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3181 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3182 pAdapter->sessionId, (unsigned)
3183 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3184 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3185 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3186 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003187 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3188 sizeof(tSirMacAddr)))
3189 {
3190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003191 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003192 ret = -EFAULT;
3193 }
3194 }
Amar Singhal0974e402013-02-12 14:27:46 -08003195 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003196 {
Amar Singhal0974e402013-02-12 14:27:46 -08003197 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003198
Jeff Johnson295189b2012-06-20 16:38:30 -07003199 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003200
3201 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003202 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003204 "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len);
Anand N Sunkad27354cf2015-07-13 14:39:11 +05303205 if(VOS_FTM_MODE != hdd_get_conparam())
3206 {
3207 /* Change band request received */
3208 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3209 if(ret < 0)
3210 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3211 "%s: failed to set band ret=%d", __func__, ret);
3212 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003213 }
Kiet Lamf040f472013-11-20 21:15:23 +05303214 else if(strncmp(command, "SETWMMPS", 8) == 0)
3215 {
3216 tANI_U8 *ptr = command;
3217 ret = hdd_wmmps_helper(pAdapter, ptr);
3218 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303219
3220 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3221 {
3222 tANI_U8 *ptr = command;
3223 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
3224 }
3225
Jeff Johnson32d95a32012-09-10 13:15:23 -07003226 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
3227 {
3228 char *country_code;
3229
3230 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003231
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003232 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003233 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003234#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05303235 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003236#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003237 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3238 (void *)(tSmeChangeCountryCallback)
3239 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05303240 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003241 if (eHAL_STATUS_SUCCESS == ret)
3242 {
3243 ret = wait_for_completion_interruptible_timeout(
3244 &pAdapter->change_country_code,
3245 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3246 if (0 >= ret)
3247 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303249 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003250 }
3251 }
3252 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07003253 {
3254 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003255 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003256 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07003257 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003258
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003259 }
3260 /*
3261 command should be a string having format
3262 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
3263 */
Amar Singhal0974e402013-02-12 14:27:46 -08003264 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003265 {
Amar Singhal0974e402013-02-12 14:27:46 -08003266 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003267
3268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003269 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003270
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08003271 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07003272 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003273 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
3274 {
3275 int suspend = 0;
3276 tANI_U8 *ptr = (tANI_U8*)command + 15;
3277
3278 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303279 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3280 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
3281 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003282 hdd_set_wlan_suspend_mode(suspend);
3283 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003284#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
3285 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
3286 {
3287 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003288 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003289 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
3290 eHalStatus status = eHAL_STATUS_SUCCESS;
3291
3292 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
3293 value = value + 15;
3294
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003295 /* Convert the value from ascii to integer */
3296 ret = kstrtos8(value, 10, &rssi);
3297 if (ret < 0)
3298 {
3299 /* If the input value is greater than max value of datatype, then also
3300 kstrtou8 fails */
3301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3302 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07003303 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003304 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3305 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3306 ret = -EINVAL;
3307 goto exit;
3308 }
3309
Srinivas Girigowdade697412013-02-14 16:31:48 -08003310 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003311
Srinivas Girigowdade697412013-02-14 16:31:48 -08003312 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
3313 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
3314 {
3315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3316 "Neighbor lookup threshold value %d is out of range"
3317 " (Min: %d Max: %d)", lookUpThreshold,
3318 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3319 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3320 ret = -EINVAL;
3321 goto exit;
3322 }
3323
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303324 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3325 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
3326 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3328 "%s: Received Command to Set Roam trigger"
3329 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
3330
3331 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
3332 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
3333 if (eHAL_STATUS_SUCCESS != status)
3334 {
3335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3336 "%s: Failed to set roam trigger, try again", __func__);
3337 ret = -EPERM;
3338 goto exit;
3339 }
3340
3341 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05303342 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003343 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
3344 }
3345 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
3346 {
3347 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
3348 int rssi = (-1) * lookUpThreshold;
3349 char extra[32];
3350 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303351 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3352 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
3353 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003354 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05303355 len = VOS_MIN(priv_data.total_len, len + 1);
3356 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003357 {
3358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3359 "%s: failed to copy data to user buffer", __func__);
3360 ret = -EFAULT;
3361 goto exit;
3362 }
3363 }
3364 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
3365 {
3366 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003367 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003368 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003369
Srinivas Girigowdade697412013-02-14 16:31:48 -08003370 /* input refresh period is in terms of seconds */
3371 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
3372 value = value + 18;
3373 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003374 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003375 if (ret < 0)
3376 {
3377 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003378 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003380 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08003381 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003382 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3383 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003384 ret = -EINVAL;
3385 goto exit;
3386 }
3387
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003388 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
3389 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003390 {
3391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003392 "Roam scan period value %d is out of range"
3393 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003394 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3395 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003396 ret = -EINVAL;
3397 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303398 }
3399 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3400 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
3401 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003402 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003403
3404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3405 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003406 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003407
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003408 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
3409 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003410 }
3411 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
3412 {
3413 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3414 char extra[32];
3415 tANI_U8 len = 0;
3416
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303417 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3418 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
3419 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003420 len = scnprintf(extra, sizeof(extra), "%s %d",
3421 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003422 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05303423 len = VOS_MIN(priv_data.total_len, len + 1);
3424 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3426 "%s: failed to copy data to user buffer", __func__);
3427 ret = -EFAULT;
3428 goto exit;
3429 }
3430 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003431 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
3432 {
3433 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003434 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003435 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003436
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003437 /* input refresh period is in terms of seconds */
3438 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
3439 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003440
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003441 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003442 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003443 if (ret < 0)
3444 {
3445 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003446 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003448 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003449 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003450 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3451 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3452 ret = -EINVAL;
3453 goto exit;
3454 }
3455
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003456 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
3457 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
3458 {
3459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3460 "Neighbor scan results refresh period value %d is out of range"
3461 " (Min: %d Max: %d)", roamScanRefreshPeriod,
3462 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3463 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3464 ret = -EINVAL;
3465 goto exit;
3466 }
3467 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
3468
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3470 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003471 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003472
3473 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
3474 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
3475 }
3476 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
3477 {
3478 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3479 char extra[32];
3480 tANI_U8 len = 0;
3481
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003482 len = scnprintf(extra, sizeof(extra), "%s %d",
3483 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003484 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05303485 len = VOS_MIN(priv_data.total_len, len + 1);
3486 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3488 "%s: failed to copy data to user buffer", __func__);
3489 ret = -EFAULT;
3490 goto exit;
3491 }
3492 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003493#ifdef FEATURE_WLAN_LFR
3494 /* SETROAMMODE */
3495 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
3496 {
3497 tANI_U8 *value = command;
3498 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3499
3500 /* Move pointer to ahead of SETROAMMODE<delimiter> */
3501 value = value + SIZE_OF_SETROAMMODE + 1;
3502
3503 /* Convert the value from ascii to integer */
3504 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
3505 if (ret < 0)
3506 {
3507 /* If the input value is greater than max value of datatype, then also
3508 kstrtou8 fails */
3509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3510 "%s: kstrtou8 failed range [%d - %d]", __func__,
3511 CFG_LFR_FEATURE_ENABLED_MIN,
3512 CFG_LFR_FEATURE_ENABLED_MAX);
3513 ret = -EINVAL;
3514 goto exit;
3515 }
3516 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3517 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
3518 {
3519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3520 "Roam Mode value %d is out of range"
3521 " (Min: %d Max: %d)", roamMode,
3522 CFG_LFR_FEATURE_ENABLED_MIN,
3523 CFG_LFR_FEATURE_ENABLED_MAX);
3524 ret = -EINVAL;
3525 goto exit;
3526 }
3527
3528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3529 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
3530 /*
3531 * Note that
3532 * SETROAMMODE 0 is to enable LFR while
3533 * SETROAMMODE 1 is to disable LFR, but
3534 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
3535 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
3536 */
3537 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3538 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
3539 else
3540 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
3541
3542 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
3543 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
3544 }
3545 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303546 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003547 {
3548 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3549 char extra[32];
3550 tANI_U8 len = 0;
3551
3552 /*
3553 * roamMode value shall be inverted because the sementics is different.
3554 */
3555 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3556 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
3557 else
3558 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
3559
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003560 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05303561 len = VOS_MIN(priv_data.total_len, len + 1);
3562 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3564 "%s: failed to copy data to user buffer", __func__);
3565 ret = -EFAULT;
3566 goto exit;
3567 }
3568 }
3569#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08003570#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003571#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003572 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
3573 {
3574 tANI_U8 *value = command;
3575 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
3576
3577 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
3578 value = value + 13;
3579 /* Convert the value from ascii to integer */
3580 ret = kstrtou8(value, 10, &roamRssiDiff);
3581 if (ret < 0)
3582 {
3583 /* If the input value is greater than max value of datatype, then also
3584 kstrtou8 fails */
3585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3586 "%s: kstrtou8 failed range [%d - %d]", __func__,
3587 CFG_ROAM_RSSI_DIFF_MIN,
3588 CFG_ROAM_RSSI_DIFF_MAX);
3589 ret = -EINVAL;
3590 goto exit;
3591 }
3592
3593 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
3594 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
3595 {
3596 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3597 "Roam rssi diff value %d is out of range"
3598 " (Min: %d Max: %d)", roamRssiDiff,
3599 CFG_ROAM_RSSI_DIFF_MIN,
3600 CFG_ROAM_RSSI_DIFF_MAX);
3601 ret = -EINVAL;
3602 goto exit;
3603 }
3604
3605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3606 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
3607
3608 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
3609 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
3610 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303611 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003612 {
3613 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
3614 char extra[32];
3615 tANI_U8 len = 0;
3616
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303617 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3618 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
3619 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003620 len = scnprintf(extra, sizeof(extra), "%s %d",
3621 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05303622 len = VOS_MIN(priv_data.total_len, len + 1);
3623 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3625 "%s: failed to copy data to user buffer", __func__);
3626 ret = -EFAULT;
3627 goto exit;
3628 }
3629 }
3630#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003631#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003632 else if (strncmp(command, "GETBAND", 7) == 0)
3633 {
3634 int band = -1;
3635 char extra[32];
3636 tANI_U8 len = 0;
3637 hdd_getBand_helper(pHddCtx, &band);
3638
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303639 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3640 TRACE_CODE_HDD_GETBAND_IOCTL,
3641 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003642 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05303643 len = VOS_MIN(priv_data.total_len, len + 1);
3644 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3646 "%s: failed to copy data to user buffer", __func__);
3647 ret = -EFAULT;
3648 goto exit;
3649 }
3650 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003651 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
3652 {
3653 tANI_U8 *value = command;
3654 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3655 tANI_U8 numChannels = 0;
3656 eHalStatus status = eHAL_STATUS_SUCCESS;
3657
3658 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3659 if (eHAL_STATUS_SUCCESS != status)
3660 {
3661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3662 "%s: Failed to parse channel list information", __func__);
3663 ret = -EINVAL;
3664 goto exit;
3665 }
3666
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303667 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3668 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
3669 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003670 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3671 {
3672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3673 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3674 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3675 ret = -EINVAL;
3676 goto exit;
3677 }
3678 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
3679 numChannels);
3680 if (eHAL_STATUS_SUCCESS != status)
3681 {
3682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3683 "%s: Failed to update channel list information", __func__);
3684 ret = -EINVAL;
3685 goto exit;
3686 }
3687 }
3688 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
3689 {
3690 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3691 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07003692 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003693 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07003694 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003695
3696 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
3697 ChannelList, &numChannels ))
3698 {
3699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3700 "%s: failed to get roam scan channel list", __func__);
3701 ret = -EFAULT;
3702 goto exit;
3703 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303704 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3705 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
3706 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003707 /* output channel list is of the format
3708 [Number of roam scan channels][Channel1][Channel2]... */
3709 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003710 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05303711 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003712 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003713 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
3714 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003715 }
3716
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05303717 len = VOS_MIN(priv_data.total_len, len + 1);
3718 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003719 {
3720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3721 "%s: failed to copy data to user buffer", __func__);
3722 ret = -EFAULT;
3723 goto exit;
3724 }
3725 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003726 else if (strncmp(command, "GETCCXMODE", 10) == 0)
3727 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003728 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003729 char extra[32];
3730 tANI_U8 len = 0;
3731
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003732 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003733 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003734 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003735 hdd_is_okc_mode_enabled(pHddCtx) &&
3736 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3737 {
3738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003739 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003740 " hence this operation is not permitted!", __func__);
3741 ret = -EPERM;
3742 goto exit;
3743 }
3744
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003745 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003746 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05303747 len = VOS_MIN(priv_data.total_len, len + 1);
3748 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003749 {
3750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3751 "%s: failed to copy data to user buffer", __func__);
3752 ret = -EFAULT;
3753 goto exit;
3754 }
3755 }
3756 else if (strncmp(command, "GETOKCMODE", 10) == 0)
3757 {
3758 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
3759 char extra[32];
3760 tANI_U8 len = 0;
3761
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003762 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003763 then this operation is not permitted (return FAILURE) */
3764 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003765 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003766 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3767 {
3768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003769 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003770 " hence this operation is not permitted!", __func__);
3771 ret = -EPERM;
3772 goto exit;
3773 }
3774
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003775 len = scnprintf(extra, sizeof(extra), "%s %d",
3776 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05303777 len = VOS_MIN(priv_data.total_len, len + 1);
3778 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003779 {
3780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3781 "%s: failed to copy data to user buffer", __func__);
3782 ret = -EFAULT;
3783 goto exit;
3784 }
3785 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003786 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003787 {
3788 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3789 char extra[32];
3790 tANI_U8 len = 0;
3791
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003792 len = scnprintf(extra, sizeof(extra), "%s %d",
3793 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05303794 len = VOS_MIN(priv_data.total_len, len + 1);
3795 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003796 {
3797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3798 "%s: failed to copy data to user buffer", __func__);
3799 ret = -EFAULT;
3800 goto exit;
3801 }
3802 }
3803 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
3804 {
3805 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3806 char extra[32];
3807 tANI_U8 len = 0;
3808
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003809 len = scnprintf(extra, sizeof(extra), "%s %d",
3810 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05303811 len = VOS_MIN(priv_data.total_len, len + 1);
3812 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003813 {
3814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3815 "%s: failed to copy data to user buffer", __func__);
3816 ret = -EFAULT;
3817 goto exit;
3818 }
3819 }
3820 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
3821 {
3822 tANI_U8 *value = command;
3823 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
3824
3825 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
3826 value = value + 26;
3827 /* Convert the value from ascii to integer */
3828 ret = kstrtou8(value, 10, &minTime);
3829 if (ret < 0)
3830 {
3831 /* If the input value is greater than max value of datatype, then also
3832 kstrtou8 fails */
3833 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3834 "%s: kstrtou8 failed range [%d - %d]", __func__,
3835 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3836 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3837 ret = -EINVAL;
3838 goto exit;
3839 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003840 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
3841 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
3842 {
3843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3844 "scan min channel time value %d is out of range"
3845 " (Min: %d Max: %d)", minTime,
3846 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3847 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3848 ret = -EINVAL;
3849 goto exit;
3850 }
3851
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303852 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3853 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
3854 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3856 "%s: Received Command to change channel min time = %d", __func__, minTime);
3857
3858 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
3859 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
3860 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003861 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
3862 {
3863 tANI_U8 *value = command;
3864 tANI_U8 channel = 0;
3865 tANI_U8 dwellTime = 0;
3866 tANI_U8 bufLen = 0;
3867 tANI_U8 *buf = NULL;
3868 tSirMacAddr targetApBssid;
3869 eHalStatus status = eHAL_STATUS_SUCCESS;
3870 struct ieee80211_channel chan;
3871 tANI_U8 finalLen = 0;
3872 tANI_U8 *finalBuf = NULL;
3873 tANI_U8 temp = 0;
3874 u64 cookie;
3875 hdd_station_ctx_t *pHddStaCtx = NULL;
3876 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3877
3878 /* if not associated, no need to send action frame */
3879 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3880 {
3881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3882 ret = -EINVAL;
3883 goto exit;
3884 }
3885
3886 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
3887 &dwellTime, &buf, &bufLen);
3888 if (eHAL_STATUS_SUCCESS != status)
3889 {
3890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3891 "%s: Failed to parse send action frame data", __func__);
3892 ret = -EINVAL;
3893 goto exit;
3894 }
3895
3896 /* if the target bssid is different from currently associated AP,
3897 then no need to send action frame */
3898 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3899 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3900 {
3901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3902 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003903 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003904 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003905 goto exit;
3906 }
3907
3908 /* if the channel number is different from operating channel then
3909 no need to send action frame */
3910 if (channel != pHddStaCtx->conn_info.operationChannel)
3911 {
3912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3913 "%s: channel(%d) is different from operating channel(%d)",
3914 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3915 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003916 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003917 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003918 goto exit;
3919 }
3920 chan.center_freq = sme_ChnToFreq(channel);
3921
3922 finalLen = bufLen + 24;
3923 finalBuf = vos_mem_malloc(finalLen);
3924 if (NULL == finalBuf)
3925 {
3926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3927 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003928 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003929 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003930 goto exit;
3931 }
3932 vos_mem_zero(finalBuf, finalLen);
3933
3934 /* Fill subtype */
3935 temp = SIR_MAC_MGMT_ACTION << 4;
3936 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3937
3938 /* Fill type */
3939 temp = SIR_MAC_MGMT_FRAME;
3940 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3941
3942 /* Fill destination address (bssid of the AP) */
3943 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3944
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003945 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003946 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3947
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003948 /* Fill BSSID (AP mac address) */
3949 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003950
3951 /* Fill received buffer from 24th address */
3952 vos_mem_copy(finalBuf + 24, buf, bufLen);
3953
Jeff Johnson11c33152013-04-16 17:52:40 -07003954 /* done with the parsed buffer */
3955 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003956 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003957
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303958#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3959 params.chan = &chan;
3960 params.offchan = 0;
3961 params.wait = dwellTime;
3962 params.buf = finalBuf;
3963 params.len = finalLen;
3964 params.no_cck = 1;
3965 params.dont_wait_for_ack = 1;
3966 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
3967#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05303968 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003969#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3970 &(pAdapter->wdev),
3971#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003972 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003973#endif
3974 &chan, 0,
3975#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3976 NL80211_CHAN_HT20, 1,
3977#endif
3978 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003979 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303980#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003981 vos_mem_free(finalBuf);
3982 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003983 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3984 {
3985 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3986 char extra[32];
3987 tANI_U8 len = 0;
3988
3989 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003990 len = scnprintf(extra, sizeof(extra), "%s %d",
3991 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303992 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3993 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3994 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303995 len = VOS_MIN(priv_data.total_len, len + 1);
3996 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003997 {
3998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3999 "%s: failed to copy data to user buffer", __func__);
4000 ret = -EFAULT;
4001 goto exit;
4002 }
4003 }
4004 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4005 {
4006 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004007 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004008
4009 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4010 value = value + 19;
4011 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004012 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004013 if (ret < 0)
4014 {
4015 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004016 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004018 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004019 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4020 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4021 ret = -EINVAL;
4022 goto exit;
4023 }
4024
4025 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4026 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4027 {
4028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4029 "lfr mode value %d is out of range"
4030 " (Min: %d Max: %d)", maxTime,
4031 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4032 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4033 ret = -EINVAL;
4034 goto exit;
4035 }
4036
4037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4038 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4039
4040 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4041 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4042 }
4043 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4044 {
4045 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4046 char extra[32];
4047 tANI_U8 len = 0;
4048
4049 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004050 len = scnprintf(extra, sizeof(extra), "%s %d",
4051 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304052 len = VOS_MIN(priv_data.total_len, len + 1);
4053 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004054 {
4055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4056 "%s: failed to copy data to user buffer", __func__);
4057 ret = -EFAULT;
4058 goto exit;
4059 }
4060 }
4061 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4062 {
4063 tANI_U8 *value = command;
4064 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4065
4066 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4067 value = value + 16;
4068 /* Convert the value from ascii to integer */
4069 ret = kstrtou16(value, 10, &val);
4070 if (ret < 0)
4071 {
4072 /* If the input value is greater than max value of datatype, then also
4073 kstrtou16 fails */
4074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4075 "%s: kstrtou16 failed range [%d - %d]", __func__,
4076 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4077 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4078 ret = -EINVAL;
4079 goto exit;
4080 }
4081
4082 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4083 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4084 {
4085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4086 "scan home time value %d is out of range"
4087 " (Min: %d Max: %d)", val,
4088 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4089 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4090 ret = -EINVAL;
4091 goto exit;
4092 }
4093
4094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4095 "%s: Received Command to change scan home time = %d", __func__, val);
4096
4097 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4098 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4099 }
4100 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4101 {
4102 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4103 char extra[32];
4104 tANI_U8 len = 0;
4105
4106 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004107 len = scnprintf(extra, sizeof(extra), "%s %d",
4108 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304109 len = VOS_MIN(priv_data.total_len, len + 1);
4110 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004111 {
4112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4113 "%s: failed to copy data to user buffer", __func__);
4114 ret = -EFAULT;
4115 goto exit;
4116 }
4117 }
4118 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4119 {
4120 tANI_U8 *value = command;
4121 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4122
4123 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4124 value = value + 17;
4125 /* Convert the value from ascii to integer */
4126 ret = kstrtou8(value, 10, &val);
4127 if (ret < 0)
4128 {
4129 /* If the input value is greater than max value of datatype, then also
4130 kstrtou8 fails */
4131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4132 "%s: kstrtou8 failed range [%d - %d]", __func__,
4133 CFG_ROAM_INTRA_BAND_MIN,
4134 CFG_ROAM_INTRA_BAND_MAX);
4135 ret = -EINVAL;
4136 goto exit;
4137 }
4138
4139 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4140 (val > CFG_ROAM_INTRA_BAND_MAX))
4141 {
4142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4143 "intra band mode value %d is out of range"
4144 " (Min: %d Max: %d)", val,
4145 CFG_ROAM_INTRA_BAND_MIN,
4146 CFG_ROAM_INTRA_BAND_MAX);
4147 ret = -EINVAL;
4148 goto exit;
4149 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4151 "%s: Received Command to change intra band = %d", __func__, val);
4152
4153 pHddCtx->cfg_ini->nRoamIntraBand = val;
4154 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
4155 }
4156 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
4157 {
4158 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
4159 char extra[32];
4160 tANI_U8 len = 0;
4161
4162 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004163 len = scnprintf(extra, sizeof(extra), "%s %d",
4164 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05304165 len = VOS_MIN(priv_data.total_len, len + 1);
4166 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004167 {
4168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4169 "%s: failed to copy data to user buffer", __func__);
4170 ret = -EFAULT;
4171 goto exit;
4172 }
4173 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004174 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
4175 {
4176 tANI_U8 *value = command;
4177 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
4178
4179 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
4180 value = value + 15;
4181 /* Convert the value from ascii to integer */
4182 ret = kstrtou8(value, 10, &nProbes);
4183 if (ret < 0)
4184 {
4185 /* If the input value is greater than max value of datatype, then also
4186 kstrtou8 fails */
4187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4188 "%s: kstrtou8 failed range [%d - %d]", __func__,
4189 CFG_ROAM_SCAN_N_PROBES_MIN,
4190 CFG_ROAM_SCAN_N_PROBES_MAX);
4191 ret = -EINVAL;
4192 goto exit;
4193 }
4194
4195 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
4196 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
4197 {
4198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4199 "NProbes value %d is out of range"
4200 " (Min: %d Max: %d)", nProbes,
4201 CFG_ROAM_SCAN_N_PROBES_MIN,
4202 CFG_ROAM_SCAN_N_PROBES_MAX);
4203 ret = -EINVAL;
4204 goto exit;
4205 }
4206
4207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4208 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
4209
4210 pHddCtx->cfg_ini->nProbes = nProbes;
4211 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
4212 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304213 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004214 {
4215 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
4216 char extra[32];
4217 tANI_U8 len = 0;
4218
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004219 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05304220 len = VOS_MIN(priv_data.total_len, len + 1);
4221 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4223 "%s: failed to copy data to user buffer", __func__);
4224 ret = -EFAULT;
4225 goto exit;
4226 }
4227 }
4228 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
4229 {
4230 tANI_U8 *value = command;
4231 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
4232
4233 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
4234 /* input value is in units of msec */
4235 value = value + 20;
4236 /* Convert the value from ascii to integer */
4237 ret = kstrtou16(value, 10, &homeAwayTime);
4238 if (ret < 0)
4239 {
4240 /* If the input value is greater than max value of datatype, then also
4241 kstrtou8 fails */
4242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4243 "%s: kstrtou8 failed range [%d - %d]", __func__,
4244 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4245 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4246 ret = -EINVAL;
4247 goto exit;
4248 }
4249
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004250 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
4251 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
4252 {
4253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4254 "homeAwayTime value %d is out of range"
4255 " (Min: %d Max: %d)", homeAwayTime,
4256 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4257 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4258 ret = -EINVAL;
4259 goto exit;
4260 }
4261
4262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4263 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07004264 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
4265 {
4266 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
4267 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
4268 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004269 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304270 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004271 {
4272 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
4273 char extra[32];
4274 tANI_U8 len = 0;
4275
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004276 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05304277 len = VOS_MIN(priv_data.total_len, len + 1);
4278 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004279 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4280 "%s: failed to copy data to user buffer", __func__);
4281 ret = -EFAULT;
4282 goto exit;
4283 }
4284 }
4285 else if (strncmp(command, "REASSOC", 7) == 0)
4286 {
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05304287 ret = hdd_parse_reassoc(pAdapter, command);
4288 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004289 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004290 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004291 else if (strncmp(command, "SETWESMODE", 10) == 0)
4292 {
4293 tANI_U8 *value = command;
4294 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
4295
4296 /* Move pointer to ahead of SETWESMODE<delimiter> */
4297 value = value + 11;
4298 /* Convert the value from ascii to integer */
4299 ret = kstrtou8(value, 10, &wesMode);
4300 if (ret < 0)
4301 {
4302 /* If the input value is greater than max value of datatype, then also
4303 kstrtou8 fails */
4304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4305 "%s: kstrtou8 failed range [%d - %d]", __func__,
4306 CFG_ENABLE_WES_MODE_NAME_MIN,
4307 CFG_ENABLE_WES_MODE_NAME_MAX);
4308 ret = -EINVAL;
4309 goto exit;
4310 }
4311
4312 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
4313 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
4314 {
4315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4316 "WES Mode value %d is out of range"
4317 " (Min: %d Max: %d)", wesMode,
4318 CFG_ENABLE_WES_MODE_NAME_MIN,
4319 CFG_ENABLE_WES_MODE_NAME_MAX);
4320 ret = -EINVAL;
4321 goto exit;
4322 }
4323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4324 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
4325
4326 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
4327 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
4328 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304329 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004330 {
4331 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
4332 char extra[32];
4333 tANI_U8 len = 0;
4334
Arif Hussain826d9412013-11-12 16:44:54 -08004335 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05304336 len = VOS_MIN(priv_data.total_len, len + 1);
4337 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4339 "%s: failed to copy data to user buffer", __func__);
4340 ret = -EFAULT;
4341 goto exit;
4342 }
4343 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004344#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004345#ifdef FEATURE_WLAN_LFR
4346 else if (strncmp(command, "SETFASTROAM", 11) == 0)
4347 {
4348 tANI_U8 *value = command;
4349 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4350
4351 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4352 value = value + 12;
4353 /* Convert the value from ascii to integer */
4354 ret = kstrtou8(value, 10, &lfrMode);
4355 if (ret < 0)
4356 {
4357 /* If the input value is greater than max value of datatype, then also
4358 kstrtou8 fails */
4359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4360 "%s: kstrtou8 failed range [%d - %d]", __func__,
4361 CFG_LFR_FEATURE_ENABLED_MIN,
4362 CFG_LFR_FEATURE_ENABLED_MAX);
4363 ret = -EINVAL;
4364 goto exit;
4365 }
4366
4367 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4368 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
4369 {
4370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4371 "lfr mode value %d is out of range"
4372 " (Min: %d Max: %d)", lfrMode,
4373 CFG_LFR_FEATURE_ENABLED_MIN,
4374 CFG_LFR_FEATURE_ENABLED_MAX);
4375 ret = -EINVAL;
4376 goto exit;
4377 }
4378
4379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4380 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
4381
4382 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
4383 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
4384 }
4385#endif
4386#ifdef WLAN_FEATURE_VOWIFI_11R
4387 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
4388 {
4389 tANI_U8 *value = command;
4390 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
4391
4392 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4393 value = value + 18;
4394 /* Convert the value from ascii to integer */
4395 ret = kstrtou8(value, 10, &ft);
4396 if (ret < 0)
4397 {
4398 /* If the input value is greater than max value of datatype, then also
4399 kstrtou8 fails */
4400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4401 "%s: kstrtou8 failed range [%d - %d]", __func__,
4402 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4403 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4404 ret = -EINVAL;
4405 goto exit;
4406 }
4407
4408 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
4409 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
4410 {
4411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4412 "ft mode value %d is out of range"
4413 " (Min: %d Max: %d)", ft,
4414 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4415 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4416 ret = -EINVAL;
4417 goto exit;
4418 }
4419
4420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4421 "%s: Received Command to change ft mode = %d", __func__, ft);
4422
4423 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
4424 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
4425 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304426 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
4427 {
4428 tANI_U8 *value = command;
4429 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304430
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304431 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
4432 value = value + 15;
4433 /* Convert the value from ascii to integer */
4434 ret = kstrtou8(value, 10, &dfsScanMode);
4435 if (ret < 0)
4436 {
4437 /* If the input value is greater than max value of
4438 datatype, then also kstrtou8 fails
4439 */
4440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4441 "%s: kstrtou8 failed range [%d - %d]", __func__,
4442 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4443 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4444 ret = -EINVAL;
4445 goto exit;
4446 }
4447
4448 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
4449 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
4450 {
4451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4452 "dfsScanMode value %d is out of range"
4453 " (Min: %d Max: %d)", dfsScanMode,
4454 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4455 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4456 ret = -EINVAL;
4457 goto exit;
4458 }
4459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4460 "%s: Received Command to Set DFS Scan Mode = %d",
4461 __func__, dfsScanMode);
4462
4463 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
4464 }
4465 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
4466 {
4467 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
4468 char extra[32];
4469 tANI_U8 len = 0;
4470
4471 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05304472 len = VOS_MIN(priv_data.total_len, len + 1);
4473 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304474 {
4475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4476 "%s: failed to copy data to user buffer", __func__);
4477 ret = -EFAULT;
4478 goto exit;
4479 }
4480 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304481 else if (strncmp(command, "FASTREASSOC", 11) == 0)
4482 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05304483 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
4484 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304485 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304486 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004487#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004488#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004489 else if (strncmp(command, "SETCCXMODE", 10) == 0)
4490 {
4491 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004492 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004493
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004494 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004495 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004496 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004497 hdd_is_okc_mode_enabled(pHddCtx) &&
4498 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4499 {
4500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004501 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004502 " hence this operation is not permitted!", __func__);
4503 ret = -EPERM;
4504 goto exit;
4505 }
4506
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004507 /* Move pointer to ahead of SETCCXMODE<delimiter> */
4508 value = value + 11;
4509 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004510 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004511 if (ret < 0)
4512 {
4513 /* If the input value is greater than max value of datatype, then also
4514 kstrtou8 fails */
4515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4516 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004517 CFG_ESE_FEATURE_ENABLED_MIN,
4518 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004519 ret = -EINVAL;
4520 goto exit;
4521 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004522 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
4523 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004524 {
4525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004526 "Ese mode value %d is out of range"
4527 " (Min: %d Max: %d)", eseMode,
4528 CFG_ESE_FEATURE_ENABLED_MIN,
4529 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004530 ret = -EINVAL;
4531 goto exit;
4532 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004534 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004535
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004536 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
4537 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004538 }
4539#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004540 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
4541 {
4542 tANI_U8 *value = command;
4543 tANI_BOOLEAN roamScanControl = 0;
4544
4545 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
4546 value = value + 19;
4547 /* Convert the value from ascii to integer */
4548 ret = kstrtou8(value, 10, &roamScanControl);
4549 if (ret < 0)
4550 {
4551 /* If the input value is greater than max value of datatype, then also
4552 kstrtou8 fails */
4553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4554 "%s: kstrtou8 failed ", __func__);
4555 ret = -EINVAL;
4556 goto exit;
4557 }
4558
4559 if (0 != roamScanControl)
4560 {
4561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4562 "roam scan control invalid value = %d",
4563 roamScanControl);
4564 ret = -EINVAL;
4565 goto exit;
4566 }
4567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4568 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
4569
4570 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
4571 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004572#ifdef FEATURE_WLAN_OKC
4573 else if (strncmp(command, "SETOKCMODE", 10) == 0)
4574 {
4575 tANI_U8 *value = command;
4576 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
4577
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004578 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004579 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004580 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004581 hdd_is_okc_mode_enabled(pHddCtx) &&
4582 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4583 {
4584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004585 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004586 " hence this operation is not permitted!", __func__);
4587 ret = -EPERM;
4588 goto exit;
4589 }
4590
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004591 /* Move pointer to ahead of SETOKCMODE<delimiter> */
4592 value = value + 11;
4593 /* Convert the value from ascii to integer */
4594 ret = kstrtou8(value, 10, &okcMode);
4595 if (ret < 0)
4596 {
4597 /* If the input value is greater than max value of datatype, then also
4598 kstrtou8 fails */
4599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4600 "%s: kstrtou8 failed range [%d - %d]", __func__,
4601 CFG_OKC_FEATURE_ENABLED_MIN,
4602 CFG_OKC_FEATURE_ENABLED_MAX);
4603 ret = -EINVAL;
4604 goto exit;
4605 }
4606
4607 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
4608 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
4609 {
4610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4611 "Okc mode value %d is out of range"
4612 " (Min: %d Max: %d)", okcMode,
4613 CFG_OKC_FEATURE_ENABLED_MIN,
4614 CFG_OKC_FEATURE_ENABLED_MAX);
4615 ret = -EINVAL;
4616 goto exit;
4617 }
4618
4619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4620 "%s: Received Command to change okc mode = %d", __func__, okcMode);
4621
4622 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
4623 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004624#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304625 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004626 {
4627 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
4628 char extra[32];
4629 tANI_U8 len = 0;
4630
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004631 len = scnprintf(extra, sizeof(extra), "%s %d",
4632 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05304633 len = VOS_MIN(priv_data.total_len, len + 1);
4634 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4636 "%s: failed to copy data to user buffer", __func__);
4637 ret = -EFAULT;
4638 goto exit;
4639 }
4640 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05304641#ifdef WLAN_FEATURE_PACKET_FILTERING
4642 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
4643 {
4644 tANI_U8 filterType = 0;
4645 tANI_U8 *value = command;
4646
4647 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
4648 value = value + 22;
4649
4650 /* Convert the value from ascii to integer */
4651 ret = kstrtou8(value, 10, &filterType);
4652 if (ret < 0)
4653 {
4654 /* If the input value is greater than max value of datatype,
4655 * then also kstrtou8 fails
4656 */
4657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4658 "%s: kstrtou8 failed range ", __func__);
4659 ret = -EINVAL;
4660 goto exit;
4661 }
4662
4663 if (filterType != 0 && filterType != 1)
4664 {
4665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4666 "%s: Accepted Values are 0 and 1 ", __func__);
4667 ret = -EINVAL;
4668 goto exit;
4669 }
4670 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
4671 pAdapter->sessionId);
4672 }
4673#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304674 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
4675 {
Kiet Lamad161252014-07-22 11:23:32 -07004676 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304677 int ret;
4678
Kiet Lamad161252014-07-22 11:23:32 -07004679 dhcpPhase = command + 11;
4680 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304681 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004683 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304684
4685 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07004686
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304687 ret = wlan_hdd_scan_abort(pAdapter);
4688 if (ret < 0)
4689 {
4690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4691 FL("failed to abort existing scan %d"), ret);
4692 }
4693
Kiet Lamad161252014-07-22 11:23:32 -07004694 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
4695 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304696 }
Kiet Lamad161252014-07-22 11:23:32 -07004697 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304698 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004700 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304701
4702 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07004703
4704 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
4705 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304706 }
4707 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004708 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
4709 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304710 hddLog(LOG1,
4711 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304712 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004713 }
4714 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
4715 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304716 hddLog(LOG1,
4717 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304718 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004719 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304720 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
4721 {
4722 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4723 char extra[32];
4724 tANI_U8 len = 0;
4725
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304726 memset(extra, 0, sizeof(extra));
4727 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05304728 len = VOS_MIN(priv_data.total_len, len + 1);
4729 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4731 "%s: failed to copy data to user buffer", __func__);
4732 ret = -EFAULT;
4733 goto exit;
4734 }
4735 ret = len;
4736 }
4737 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4738 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304739 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304740 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004741 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4742 {
4743 tANI_U8 filterType = 0;
4744 tANI_U8 *value;
4745 value = command + 9;
4746
4747 /* Convert the value from ascii to integer */
4748 ret = kstrtou8(value, 10, &filterType);
4749 if (ret < 0)
4750 {
4751 /* If the input value is greater than max value of datatype,
4752 * then also kstrtou8 fails
4753 */
4754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4755 "%s: kstrtou8 failed range ", __func__);
4756 ret = -EINVAL;
4757 goto exit;
4758 }
4759 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4760 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4761 {
4762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4763 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4764 " 2-Sink ", __func__);
4765 ret = -EINVAL;
4766 goto exit;
4767 }
4768 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4769 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304770 pScanInfo = &pHddCtx->scan_info;
4771 if (filterType && pScanInfo != NULL &&
4772 pHddCtx->scan_info.mScanPending)
4773 {
4774 /*Miracast Session started. Abort Scan */
4775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4776 "%s, Aborting Scan For Miracast",__func__);
4777 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4778 eCSR_SCAN_ABORT_DEFAULT);
4779 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004780 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304781 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004782 }
Leo Chang614d2072013-08-22 14:59:44 -07004783 else if (strncmp(command, "SETMCRATE", 9) == 0)
4784 {
Leo Chang614d2072013-08-22 14:59:44 -07004785 tANI_U8 *value = command;
4786 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004787 tSirRateUpdateInd *rateUpdate;
4788 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004789
4790 /* Only valid for SAP mode */
4791 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4792 {
4793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4794 "%s: SAP mode is not running", __func__);
4795 ret = -EFAULT;
4796 goto exit;
4797 }
4798
4799 /* Move pointer to ahead of SETMCRATE<delimiter> */
4800 /* input value is in units of hundred kbps */
4801 value = value + 10;
4802 /* Convert the value from ascii to integer, decimal base */
4803 ret = kstrtouint(value, 10, &targetRate);
4804
Leo Chang1f98cbd2013-10-17 15:03:52 -07004805 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4806 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004807 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004808 hddLog(VOS_TRACE_LEVEL_ERROR,
4809 "%s: SETMCRATE indication alloc fail", __func__);
4810 ret = -EFAULT;
4811 goto exit;
4812 }
4813 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4814
4815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4816 "MC Target rate %d", targetRate);
4817 /* Ignore unicast */
4818 rateUpdate->ucastDataRate = -1;
4819 rateUpdate->mcastDataRate24GHz = targetRate;
4820 rateUpdate->mcastDataRate5GHz = targetRate;
4821 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4822 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4823 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4824 if (eHAL_STATUS_SUCCESS != status)
4825 {
4826 hddLog(VOS_TRACE_LEVEL_ERROR,
4827 "%s: SET_MC_RATE failed", __func__);
4828 vos_mem_free(rateUpdate);
4829 ret = -EFAULT;
4830 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004831 }
4832 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304833#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004834 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304835 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004836 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304837 }
4838#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05304839#ifdef WLAN_FEATURE_RMC
4840 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
4841 (WLAN_HDD_IBSS == pAdapter->device_mode))
4842 {
4843 int i = 0;
4844 tANI_U8 *ibss_ie;
4845 tANI_U32 command_len;
4846 tANI_U8 *value = command;
4847 tHalHandle hHal = pHddCtx->hHal;
4848 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4849 tANI_U32 ibss_ie_length;
4850 tANI_U32 len, present;
4851 tANI_U8 *addIE;
4852 tANI_U8 *addIEData;
4853
4854 hddLog(LOG1,
4855 FL(" received command %s"),((char *) value));
4856 /* validate argument of command */
4857 if (strlen(value) <= 21)
4858 {
4859 hddLog(LOGE,
4860 FL("No arguements in command length %zu"), strlen(value));
4861 ret = -EFAULT;
4862 goto exit;
4863 }
4864
4865 /* moving to arguments of commands */
4866 value = value + 21;
4867 command_len = strlen(value);
4868
4869 /* oui_data can't be less than 3 bytes */
4870 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
4871 {
4872 hddLog(LOGE,
4873 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
4874 command_len);
4875 ret = -EFAULT;
4876 goto exit;
4877 }
4878 ibss_ie = vos_mem_malloc(command_len);
4879 if (!ibss_ie) {
4880 hddLog(LOGE,
4881 FL("Could not allocate memory for command length %d"),
4882 command_len);
4883 ret = -ENOMEM;
4884 goto exit;
4885 }
4886 vos_mem_zero(ibss_ie, command_len);
4887
4888 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
4889 command_len);
4890 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
4891 hddLog(LOGE, FL("Could not parse command %s return length %d"),
4892 value, ibss_ie_length);
4893 ret = -EFAULT;
4894 vos_mem_free(ibss_ie);
4895 goto exit;
4896 }
4897
4898 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
4899 while (i < ibss_ie_length)
4900 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
4901
4902 /* Populate Vendor IE in Beacon */
4903 if ((ccmCfgGetInt(hHal,
4904 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
4905 &present)) != eHAL_STATUS_SUCCESS)
4906 {
4907 hddLog(LOGE,
4908 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
4909 ret = -EFAULT;
4910 vos_mem_free(ibss_ie);
4911 goto exit;
4912 }
4913
4914 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4915 if (!addIE) {
4916 hddLog(LOGE,
4917 FL("Could not allocate memory for command length %d"),
4918 command_len);
4919 vos_mem_free(ibss_ie);
4920 ret = -ENOMEM;
4921 goto exit;
4922 }
4923 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4924
4925 if (present)
4926 {
4927 if ((wlan_cfgGetStrLen(pMac,
4928 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
4929 {
4930 hddLog(LOGE,
4931 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
4932 ret = -EFAULT;
4933 vos_mem_free(ibss_ie);
4934 vos_mem_free(addIE);
4935 goto exit;
4936 }
4937
4938 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
4939 ((len + ibss_ie_length) <=
4940 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
4941 {
4942 if ((ccmCfgGetStr(hHal,
4943 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
4944 != eHAL_STATUS_SUCCESS)
4945 {
4946 hddLog(LOGE,
4947 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
4948 ret = -EFAULT;
4949 vos_mem_free(ibss_ie);
4950 vos_mem_free(addIE);
4951 goto exit;
4952 }
4953 else
4954 {
4955 /* Curruntly only WPA IE is added before Vendor IE
4956 * so we can blindly place the Vendor IE after WPA
4957 * IE. If no WPA IE found replace all with Vendor IE.
4958 */
4959 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
4960 }
4961 }
4962 else
4963 {
4964 hddLog(LOGE,
4965 FL("IE len exceed limit len %d,ibss_ie_length %d "),
4966 len, ibss_ie_length);
4967 ret = -EFAULT;
4968 vos_mem_free(addIE);
4969 vos_mem_free(ibss_ie);
4970 goto exit;
4971 }
4972 }
4973 else {
4974 len = 0;
4975 }
4976
4977 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
4978 len += ibss_ie_length;
4979
4980 if (ccmCfgSetStr(hHal,
4981 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
4982 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4983 {
4984 hddLog(LOGE,
4985 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
4986 ret = -EFAULT;
4987 vos_mem_free(ibss_ie);
4988 vos_mem_free(addIE);
4989 goto exit;
4990 }
4991 vos_mem_free(addIE);
4992 if (ccmCfgSetInt(hHal,
4993 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4994 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4995 {
4996 hddLog(LOGE,
4997 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
4998 ret = -EFAULT;
4999 vos_mem_free(ibss_ie);
5000 goto exit;
5001 }
5002
5003 /* Populate Vendor IE in probe resp */
5004 if ((ccmCfgGetInt(hHal,
5005 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
5006 &present)) != eHAL_STATUS_SUCCESS)
5007 {
5008 hddLog(LOGE,
5009 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5010 ret = -EFAULT;
5011 vos_mem_free(ibss_ie);
5012 goto exit;
5013 }
5014
5015 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5016 if (!addIEData) {
5017 hddLog(LOGE,
5018 FL("Could not allocate memory for command length %d"),
5019 command_len);
5020 vos_mem_free(ibss_ie);
5021 ret = -ENOMEM;
5022 goto exit;
5023 }
5024 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5025
5026 if (present) {
5027 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
5028 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
5029 hddLog(LOGE,
5030 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5031 ret = -EFAULT;
5032 vos_mem_free(ibss_ie);
5033 vos_mem_free(addIEData);
5034 goto exit;
5035 }
5036 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
5037 (ibss_ie_length + len) <=
5038 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
5039
5040 if ((ccmCfgGetStr(hHal,
5041 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
5042 != eHAL_STATUS_SUCCESS) {
5043 hddLog(LOGE,
5044 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5045 ret = -EFAULT;
5046 vos_mem_free(ibss_ie);
5047 vos_mem_free(addIEData);
5048 goto exit;
5049 }
5050 else {
5051 /* Curruntly only WPA IE is added before Vendor IE
5052 * so we can blindly place the Vendor IE after WPA
5053 * IE. If no WPA IE found replace all with Vendor IE.
5054 */
5055 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
5056 }
5057 }
5058 else
5059 {
5060 hddLog(LOGE,
5061 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5062 len, ibss_ie_length);
5063 ret = -EFAULT;
5064 vos_mem_free(addIEData);
5065 vos_mem_free(ibss_ie);
5066 goto exit;
5067 }
5068 } /* probe rsp ADD IE present */
5069 else {
5070 /* probe rsp add IE is not present */
5071 len = 0;
5072 }
5073
5074 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
5075 len += ibss_ie_length;
5076
5077 vos_mem_free(ibss_ie);
5078
5079 if (ccmCfgSetStr(hHal,
5080 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5081 (tANI_U8*)(addIEData),
5082 len, NULL,
5083 eANI_BOOLEAN_FALSE)
5084 == eHAL_STATUS_FAILURE) {
5085 hddLog(LOGE,
5086 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5087 ret = -EFAULT;
5088 vos_mem_free(addIEData);
5089 goto exit;
5090 }
5091 vos_mem_free(addIEData);
5092 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5093 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5094 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5095 {
5096 hddLog(LOGE,
5097 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5098 ret = -EFAULT;
5099 goto exit;
5100 }
5101 }
5102 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
5103 {
5104 tANI_U8 *value = command;
5105 tANI_U8 ucRmcEnable = 0;
5106 int status;
5107
5108 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5109 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5110 {
5111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5112 "Received SETRMCENABLE command in invalid mode %d "
5113 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
5114 pAdapter->device_mode);
5115 ret = -EINVAL;
5116 goto exit;
5117 }
5118
5119 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
5120 if (status)
5121 {
5122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5123 "Invalid SETRMCENABLE command ");
5124 ret = -EINVAL;
5125 goto exit;
5126 }
5127
5128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5129 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
5130
5131 if (TRUE == ucRmcEnable)
5132 {
5133 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
5134 pAdapter->sessionId );
5135 }
5136 else if(FALSE == ucRmcEnable)
5137 {
5138 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
5139 pAdapter->sessionId );
5140 }
5141 else
5142 {
5143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5144 "Invalid SETRMCENABLE command %d", ucRmcEnable);
5145 ret = -EINVAL;
5146 goto exit;
5147 }
5148
5149 if (VOS_STATUS_SUCCESS != status)
5150 {
5151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5152 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
5153 status);
5154 ret = -EINVAL;
5155 goto exit;
5156 }
5157 }
5158 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
5159 {
5160 tANI_U8 *value = command;
5161 tANI_U32 uActionPeriod = 0;
5162 int status;
5163
5164 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5165 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5166 {
5167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5168 "Received SETRMC command in invalid mode %d "
5169 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5170 pAdapter->device_mode);
5171 ret = -EINVAL;
5172 goto exit;
5173 }
5174
5175 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
5176 if (status)
5177 {
5178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5179 "Invalid SETRMCACTIONPERIOD command ");
5180 ret = -EINVAL;
5181 goto exit;
5182 }
5183
5184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5185 "%s: uActionPeriod %d ", __func__, uActionPeriod);
5186
5187 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
5188 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
5189 {
5190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5191 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
5192 ret = -EINVAL;
5193 goto exit;
5194 }
5195
5196 }
5197 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
5198 {
5199 /* Peer Info All Command */
5200 int status = eHAL_STATUS_SUCCESS;
5201 hdd_station_ctx_t *pHddStaCtx = NULL;
5202 char *extra = NULL;
5203 int idx = 0, length = 0;
5204 v_MACADDR_t *macAddr;
5205 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
5206
5207 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5208 {
5209 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5210 }
5211 else
5212 {
5213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5214 "%s: pAdapter is not valid for this device mode",
5215 __func__);
5216 ret = -EINVAL;
5217 goto exit;
5218 }
5219
5220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5221 "%s: Received GETIBSSPEERINFOALL Command", __func__);
5222
5223
5224 /* Handle the command */
5225 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
5226 if (VOS_STATUS_SUCCESS == status)
5227 {
5228 /* The variable extra needed to be allocated on the heap since
5229 * amount of memory required to copy the data for 32 devices
5230 * exceeds the size of 1024 bytes of default stack size. On
5231 * 64 bit devices, the default max stack size of 2048 bytes
5232 */
5233 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
5234
5235 if (NULL == extra)
5236 {
5237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5238 "%s:kmalloc failed", __func__);
5239 ret = -EINVAL;
5240 goto exit;
5241 }
5242
5243 /* Copy number of stations */
5244 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
5245 pHddStaCtx->ibss_peer_info.numIBSSPeers);
5246 numOfBytestoPrint = length;
5247 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
5248 {
5249 macAddr =
5250 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
5251 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5252 if (NULL != macAddr)
5253 {
5254 txRateMbps =
5255 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
5256
5257 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
5258 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
5259 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
5260 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
5261 (int)txRateMbps,
5262 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
5263 }
5264 else
5265 {
5266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5267 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
5268 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5269 }
5270
5271 /*
5272 * VOS_TRACE() macro has limitation of 512 bytes for the print
5273 * buffer. Hence printing the data in two chunks. The first chunk
5274 * will have the data for 16 devices and the second chunk will
5275 * have the rest.
5276 */
5277 if (idx < NUM_OF_STA_DATA_TO_PRINT)
5278 {
5279 numOfBytestoPrint = length;
5280 }
5281 }
5282
5283 /*
5284 * Copy the data back into buffer, if the data to copy is
5285 * morethan 512 bytes than we will split the data and do
5286 * it in two shots
5287 */
5288 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
5289 {
5290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5291 "%s: Copy into user data buffer failed ", __func__);
5292 ret = -EFAULT;
5293 kfree(extra);
5294 goto exit;
5295 }
5296 priv_data.buf[numOfBytestoPrint] = '\0';
5297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5298 "%s", priv_data.buf);
5299
5300 if (length > numOfBytestoPrint)
5301 {
5302 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
5303 extra + numOfBytestoPrint,
5304 length - numOfBytestoPrint + 1))
5305 {
5306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5307 "%s: Copy into user data buffer failed ", __func__);
5308 ret = -EFAULT;
5309 kfree(extra);
5310 goto exit;
5311 }
5312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5313 "%s", &priv_data.buf[numOfBytestoPrint]);
5314 }
5315
5316 /* Free temporary buffer */
5317 kfree(extra);
5318 }
5319
5320 else
5321 {
5322 /* Command failed, log error */
5323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5324 "%s: GETIBSSPEERINFOALL command failed with status code %d",
5325 __func__, status);
5326 ret = -EINVAL;
5327 goto exit;
5328 }
5329 ret = 0;
5330 }
5331 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
5332 {
5333 /* Peer Info <Peer Addr> command */
5334 tANI_U8 *value = command;
5335 VOS_STATUS status;
5336 hdd_station_ctx_t *pHddStaCtx = NULL;
5337 char extra[128] = { 0 };
5338 v_U32_t length = 0;
5339 v_U8_t staIdx = 0;
5340 v_U32_t txRateMbps = 0;
5341 v_MACADDR_t peerMacAddr;
5342
5343 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5344 {
5345 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5346 }
5347 else
5348 {
5349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5350 "%s: pAdapter is not valid for this device mode",
5351 __func__);
5352 ret = -EINVAL;
5353 goto exit;
5354 }
5355
5356 /* if there are no peers, no need to continue with the command */
5357 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5358 "%s: Received GETIBSSPEERINFO Command", __func__);
5359
5360 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
5361 {
5362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5363 "%s:No IBSS Peers coalesced", __func__);
5364 ret = -EINVAL;
5365 goto exit;
5366 }
5367
5368 /* Parse the incoming command buffer */
5369 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
5370 if (VOS_STATUS_SUCCESS != status)
5371 {
5372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5373 "%s: Invalid GETIBSSPEERINFO command", __func__);
5374 ret = -EINVAL;
5375 goto exit;
5376 }
5377
5378 /* Get station index for the peer mac address */
5379 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
5380
5381 if (staIdx > HDD_MAX_NUM_IBSS_STA)
5382 {
5383 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5384 "%s: Invalid StaIdx %d returned", __func__, staIdx);
5385 ret = -EINVAL;
5386 goto exit;
5387 }
5388
5389 /* Handle the command */
5390 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
5391 if (VOS_STATUS_SUCCESS == status)
5392 {
5393 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
5394 txRateMbps = (txRate * 500 * 1000)/1000000;
5395
5396 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
5397 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
5398
5399 /* Copy the data back into buffer */
5400 if (copy_to_user(priv_data.buf, &extra, length+ 1))
5401 {
5402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5403 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
5404 __func__);
5405 ret = -EFAULT;
5406 goto exit;
5407 }
5408 }
5409 else
5410 {
5411 /* Command failed, log error */
5412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5413 "%s: GETIBSSPEERINFO command failed with status code %d",
5414 __func__, status);
5415 ret = -EINVAL;
5416 goto exit;
5417 }
5418
5419 /* Success ! */
5420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5421 "%s", priv_data.buf);
5422 ret = 0;
5423 }
5424 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
5425 {
5426 tANI_U8 *value = command;
5427 tANI_U32 uRate = 0;
5428 tTxrateinfoflags txFlags = 0;
5429 tSirRateUpdateInd *rateUpdateParams;
5430 int status;
5431
5432 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5433 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5434 {
5435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5436 "Received SETRMCTXRATE command in invalid mode %d "
5437 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5438 pAdapter->device_mode);
5439 ret = -EINVAL;
5440 goto exit;
5441 }
5442
5443 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
5444 if (status)
5445 {
5446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5447 "Invalid SETRMCTXRATE command ");
5448 ret = -EINVAL;
5449 goto exit;
5450 }
5451
5452 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
5453 if (NULL == rateUpdateParams)
5454 {
5455 ret = -EINVAL;
5456 goto exit;
5457 }
5458
5459 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5460 "%s: uRate %d ", __func__, uRate);
5461
5462 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
5463
5464 /* -1 implies ignore this param */
5465 rateUpdateParams->ucastDataRate = -1;
5466
5467 /*
5468 * Fill the user specifieed RMC rate param
5469 * and the derived tx flags.
5470 */
5471 rateUpdateParams->rmcDataRate = uRate;
5472 rateUpdateParams->rmcDataRateTxFlag = txFlags;
5473
5474 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
5475 }
5476 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
5477 {
5478 char *value;
5479 tANI_U8 tx_fail_count = 0;
5480 tANI_U16 pid = 0;
5481
5482 value = command;
5483
5484 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
5485
5486 if (0 != ret)
5487 {
5488 hddLog(VOS_TRACE_LEVEL_INFO,
5489 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
5490 __func__);
5491 goto exit;
5492 }
5493
5494 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
5495 __func__, tx_fail_count, pid);
5496
5497 if (0 == tx_fail_count)
5498 {
5499 // Disable TX Fail Indication
5500 if (eHAL_STATUS_SUCCESS ==
5501 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5502 tx_fail_count,
5503 NULL))
5504 {
5505 cesium_pid = 0;
5506 }
5507 else
5508 {
5509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5510 "%s: failed to disable TX Fail Event ", __func__);
5511 ret = -EINVAL;
5512 }
5513 }
5514 else
5515 {
5516 if (eHAL_STATUS_SUCCESS ==
5517 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5518 tx_fail_count,
5519 (void*)hdd_tx_fail_ind_callback))
5520 {
5521 cesium_pid = pid;
5522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5523 "%s: Registered Cesium pid %u", __func__,
5524 cesium_pid);
5525 }
5526 else
5527 {
5528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5529 "%s: Failed to enable TX Fail Monitoring", __func__);
5530 ret = -EINVAL;
5531 }
5532 }
5533 }
5534
5535#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005536#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005537 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
5538 {
5539 tANI_U8 *value = command;
5540 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
5541 tANI_U8 numChannels = 0;
5542 eHalStatus status = eHAL_STATUS_SUCCESS;
5543
5544 status = hdd_parse_channellist(value, ChannelList, &numChannels);
5545 if (eHAL_STATUS_SUCCESS != status)
5546 {
5547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5548 "%s: Failed to parse channel list information", __func__);
5549 ret = -EINVAL;
5550 goto exit;
5551 }
5552
5553 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
5554 {
5555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5556 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
5557 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
5558 ret = -EINVAL;
5559 goto exit;
5560 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005561 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005562 ChannelList,
5563 numChannels);
5564 if (eHAL_STATUS_SUCCESS != status)
5565 {
5566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5567 "%s: Failed to update channel list information", __func__);
5568 ret = -EINVAL;
5569 goto exit;
5570 }
5571 }
5572 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
5573 {
5574 tANI_U8 *value = command;
5575 char extra[128] = {0};
5576 int len = 0;
5577 tANI_U8 tid = 0;
5578 hdd_station_ctx_t *pHddStaCtx = NULL;
5579 tAniTrafStrmMetrics tsmMetrics;
5580 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5581
5582 /* if not associated, return error */
5583 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5584 {
5585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
5586 ret = -EINVAL;
5587 goto exit;
5588 }
5589
5590 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
5591 value = value + 12;
5592 /* Convert the value from ascii to integer */
5593 ret = kstrtou8(value, 10, &tid);
5594 if (ret < 0)
5595 {
5596 /* If the input value is greater than max value of datatype, then also
5597 kstrtou8 fails */
5598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5599 "%s: kstrtou8 failed range [%d - %d]", __func__,
5600 TID_MIN_VALUE,
5601 TID_MAX_VALUE);
5602 ret = -EINVAL;
5603 goto exit;
5604 }
5605
5606 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
5607 {
5608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5609 "tid value %d is out of range"
5610 " (Min: %d Max: %d)", tid,
5611 TID_MIN_VALUE,
5612 TID_MAX_VALUE);
5613 ret = -EINVAL;
5614 goto exit;
5615 }
5616
5617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5618 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
5619
5620 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
5621 {
5622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5623 "%s: failed to get tsm stats", __func__);
5624 ret = -EFAULT;
5625 goto exit;
5626 }
5627
5628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5629 "UplinkPktQueueDly(%d)\n"
5630 "UplinkPktQueueDlyHist[0](%d)\n"
5631 "UplinkPktQueueDlyHist[1](%d)\n"
5632 "UplinkPktQueueDlyHist[2](%d)\n"
5633 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05305634 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005635 "UplinkPktLoss(%d)\n"
5636 "UplinkPktCount(%d)\n"
5637 "RoamingCount(%d)\n"
5638 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
5639 tsmMetrics.UplinkPktQueueDlyHist[0],
5640 tsmMetrics.UplinkPktQueueDlyHist[1],
5641 tsmMetrics.UplinkPktQueueDlyHist[2],
5642 tsmMetrics.UplinkPktQueueDlyHist[3],
5643 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
5644 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
5645
5646 /* Output TSM stats is of the format
5647 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
5648 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005649 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005650 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
5651 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
5652 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
5653 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
5654 tsmMetrics.RoamingDly);
5655
Ratnam Rachurid53009c2015-08-07 13:59:00 +05305656 len = VOS_MIN(priv_data.total_len, len + 1);
5657 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5659 "%s: failed to copy data to user buffer", __func__);
5660 ret = -EFAULT;
5661 goto exit;
5662 }
5663 }
5664 else if (strncmp(command, "SETCCKMIE", 9) == 0)
5665 {
5666 tANI_U8 *value = command;
5667 tANI_U8 *cckmIe = NULL;
5668 tANI_U8 cckmIeLen = 0;
5669 eHalStatus status = eHAL_STATUS_SUCCESS;
5670
5671 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
5672 if (eHAL_STATUS_SUCCESS != status)
5673 {
5674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5675 "%s: Failed to parse cckm ie data", __func__);
5676 ret = -EINVAL;
5677 goto exit;
5678 }
5679
5680 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
5681 {
5682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5683 "%s: CCKM Ie input length is more than max[%d]", __func__,
5684 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005685 vos_mem_free(cckmIe);
5686 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005687 ret = -EINVAL;
5688 goto exit;
5689 }
5690 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005691 vos_mem_free(cckmIe);
5692 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005693 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005694 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
5695 {
5696 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005697 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005698 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005699
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005700 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005701 if (eHAL_STATUS_SUCCESS != status)
5702 {
5703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005704 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005705 ret = -EINVAL;
5706 goto exit;
5707 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005708 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
5709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
5710 hdd_indicateEseBcnReportNoResults (pAdapter,
5711 eseBcnReq.bcnReq[0].measurementToken,
5712 0x02, //BIT(1) set for measurement done
5713 0); // no BSS
5714 goto exit;
5715 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005716
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005717 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
5718 if (eHAL_STATUS_SUCCESS != status)
5719 {
5720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5721 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
5722 ret = -EINVAL;
5723 goto exit;
5724 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005725 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005726#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05305727 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
5728 {
5729 eHalStatus status;
5730 char buf[32], len;
5731 long waitRet;
5732 bcnMissRateContext_t getBcnMissRateCtx;
5733
5734 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5735
5736 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5737 {
5738 hddLog(VOS_TRACE_LEVEL_WARN,
5739 FL("GETBCNMISSRATE: STA is not in connected state"));
5740 ret = -1;
5741 goto exit;
5742 }
5743
5744 init_completion(&(getBcnMissRateCtx.completion));
5745 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
5746
5747 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
5748 pAdapter->sessionId,
5749 (void *)getBcnMissRateCB,
5750 (void *)(&getBcnMissRateCtx));
5751 if( eHAL_STATUS_SUCCESS != status)
5752 {
5753 hddLog(VOS_TRACE_LEVEL_INFO,
5754 FL("GETBCNMISSRATE: fail to post WDA cmd"));
5755 ret = -EINVAL;
5756 goto exit;
5757 }
5758
5759 waitRet = wait_for_completion_interruptible_timeout
5760 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
5761 if(waitRet <= 0)
5762 {
5763 hddLog(VOS_TRACE_LEVEL_ERROR,
5764 FL("failed to wait on bcnMissRateComp %d"), ret);
5765
5766 //Make magic number to zero so that callback is not called.
5767 spin_lock(&hdd_context_lock);
5768 getBcnMissRateCtx.magic = 0x0;
5769 spin_unlock(&hdd_context_lock);
5770 ret = -EINVAL;
5771 goto exit;
5772 }
5773
5774 hddLog(VOS_TRACE_LEVEL_INFO,
5775 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
5776
5777 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
5778 if (copy_to_user(priv_data.buf, &buf, len + 1))
5779 {
5780 hddLog(VOS_TRACE_LEVEL_ERROR,
5781 "%s: failed to copy data to user buffer", __func__);
5782 ret = -EFAULT;
5783 goto exit;
5784 }
5785 ret = len;
5786 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305787#ifdef FEATURE_WLAN_TDLS
5788 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
5789 tANI_U8 *value = command;
5790 int set_value;
5791 /* Move pointer to ahead of TDLSOFFCH*/
5792 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05305793 if (!(sscanf(value, "%d", &set_value))) {
5794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5795 FL("No input identified"));
5796 ret = -EINVAL;
5797 goto exit;
5798 }
5799
Atul Mittal87ec2422014-09-24 13:12:50 +05305800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5801 "%s: Tdls offchannel offset:%d",
5802 __func__, set_value);
5803 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
5804 if (ret < 0)
5805 {
5806 ret = -EINVAL;
5807 goto exit;
5808 }
5809
5810 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
5811 tANI_U8 *value = command;
5812 int set_value;
5813 /* Move pointer to ahead of tdlsoffchnmode*/
5814 value += 18;
c_manjee82323892015-12-08 12:40:34 +05305815 ret = sscanf(value, "%d", &set_value);
5816 if (ret != 1) {
5817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5818 FL("No input identified"));
5819 ret = -EINVAL;
5820 goto exit;
5821 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5823 "%s: Tdls offchannel mode:%d",
5824 __func__, set_value);
5825 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
5826 if (ret < 0)
5827 {
5828 ret = -EINVAL;
5829 goto exit;
5830 }
5831 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
5832 tANI_U8 *value = command;
5833 int set_value;
5834 /* Move pointer to ahead of TDLSOFFCH*/
5835 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05305836 ret = sscanf(value, "%d", &set_value);
5837 if (ret != 1) {
5838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5839 "Wrong value is given for hdd_set_tdls_offchannel");
5840 ret = -EINVAL;
5841 goto exit;
5842 }
5843
Atul Mittal87ec2422014-09-24 13:12:50 +05305844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5845 "%s: Tdls offchannel num: %d",
5846 __func__, set_value);
5847 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
5848 if (ret < 0)
5849 {
5850 ret = -EINVAL;
5851 goto exit;
5852 }
5853 }
5854#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05305855 else if (strncmp(command, "GETFWSTATS", 10) == 0)
5856 {
5857 eHalStatus status;
5858 char *buf = NULL;
5859 char len;
5860 long waitRet;
5861 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05305862 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305863 tANI_U8 *ptr = command;
5864 int stats = *(ptr + 11) - '0';
5865
5866 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
5867 if (!IS_FEATURE_FW_STATS_ENABLE)
5868 {
5869 hddLog(VOS_TRACE_LEVEL_INFO,
5870 FL("Get Firmware stats feature not supported"));
5871 ret = -EINVAL;
5872 goto exit;
5873 }
5874
5875 if (FW_STATS_MAX <= stats || 0 >= stats)
5876 {
5877 hddLog(VOS_TRACE_LEVEL_INFO,
5878 FL(" stats %d not supported"),stats);
5879 ret = -EINVAL;
5880 goto exit;
5881 }
5882
5883 init_completion(&(fwStatsCtx.completion));
5884 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
5885 fwStatsCtx.pAdapter = pAdapter;
5886 fwStatsRsp->type = 0;
5887 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05305888 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305889 if (eHAL_STATUS_SUCCESS != status)
5890 {
5891 hddLog(VOS_TRACE_LEVEL_ERROR,
5892 FL(" fail to post WDA cmd status = %d"), status);
5893 ret = -EINVAL;
5894 goto exit;
5895 }
5896 waitRet = wait_for_completion_timeout
5897 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
5898 if (waitRet <= 0)
5899 {
5900 hddLog(VOS_TRACE_LEVEL_ERROR,
5901 FL("failed to wait on GwtFwstats"));
5902 //Make magic number to zero so that callback is not executed.
5903 spin_lock(&hdd_context_lock);
5904 fwStatsCtx.magic = 0x0;
5905 spin_unlock(&hdd_context_lock);
5906 ret = -EINVAL;
5907 goto exit;
5908 }
5909 if (fwStatsRsp->type)
5910 {
5911 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
5912 if (!buf)
5913 {
5914 hddLog(VOS_TRACE_LEVEL_ERROR,
5915 FL(" failed to allocate memory"));
5916 ret = -ENOMEM;
5917 goto exit;
5918 }
5919 switch( fwStatsRsp->type )
5920 {
5921 case FW_UBSP_STATS:
5922 {
5923 len = snprintf(buf, FW_STATE_RSP_LEN,
5924 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05305925 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
5926 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305927 }
5928 break;
5929 default:
5930 {
5931 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
5932 ret = -EFAULT;
5933 kfree(buf);
5934 goto exit;
5935 }
5936 }
5937 if (copy_to_user(priv_data.buf, buf, len + 1))
5938 {
5939 hddLog(VOS_TRACE_LEVEL_ERROR,
5940 FL(" failed to copy data to user buffer"));
5941 ret = -EFAULT;
5942 kfree(buf);
5943 goto exit;
5944 }
5945 ret = len;
5946 kfree(buf);
5947 }
5948 else
5949 {
5950 hddLog(VOS_TRACE_LEVEL_ERROR,
5951 FL("failed to fetch the stats"));
5952 ret = -EFAULT;
5953 goto exit;
5954 }
5955
5956 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05305957 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
5958 {
5959 /*
5960 * this command wld be called by user-space when it detects WLAN
5961 * ON after airplane mode is set. When APM is set, WLAN turns off.
5962 * But it can be turned back on. Otherwise; when APM is turned back
5963 * off, WLAN wld turn back on. So at that point the command is
5964 * expected to come down. 0 means disable, 1 means enable. The
5965 * constraint is removed when parameter 1 is set or different
5966 * country code is set
5967 */
5968 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
5969 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05305970 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
5971 {
5972 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
5973 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005974 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305975 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5976 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
5977 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05305978 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
5979 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005980 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005981 }
5982exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305983 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005984 if (command)
5985 {
5986 kfree(command);
5987 }
5988 return ret;
5989}
5990
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005991#ifdef CONFIG_COMPAT
5992static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
5993{
5994 struct {
5995 compat_uptr_t buf;
5996 int used_len;
5997 int total_len;
5998 } compat_priv_data;
5999 hdd_priv_data_t priv_data;
6000 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006001
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006002 /*
6003 * Note that pAdapter and ifr have already been verified by caller,
6004 * and HDD context has also been validated
6005 */
6006 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
6007 sizeof(compat_priv_data))) {
6008 ret = -EFAULT;
6009 goto exit;
6010 }
6011 priv_data.buf = compat_ptr(compat_priv_data.buf);
6012 priv_data.used_len = compat_priv_data.used_len;
6013 priv_data.total_len = compat_priv_data.total_len;
6014 ret = hdd_driver_command(pAdapter, &priv_data);
6015 exit:
6016 return ret;
6017}
6018#else /* CONFIG_COMPAT */
6019static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6020{
6021 /* will never be invoked */
6022 return 0;
6023}
6024#endif /* CONFIG_COMPAT */
6025
6026static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6027{
6028 hdd_priv_data_t priv_data;
6029 int ret = 0;
6030
6031 /*
6032 * Note that pAdapter and ifr have already been verified by caller,
6033 * and HDD context has also been validated
6034 */
6035 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
6036 ret = -EFAULT;
6037 } else {
6038 ret = hdd_driver_command(pAdapter, &priv_data);
6039 }
6040 return ret;
6041}
6042
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306043int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006044{
6045 hdd_adapter_t *pAdapter;
6046 hdd_context_t *pHddCtx;
6047 int ret;
6048
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306049 ENTER();
6050
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006051 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6052 if (NULL == pAdapter) {
6053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6054 "%s: HDD adapter context is Null", __func__);
6055 ret = -ENODEV;
6056 goto exit;
6057 }
6058 if (dev != pAdapter->dev) {
6059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6060 "%s: HDD adapter/dev inconsistency", __func__);
6061 ret = -ENODEV;
6062 goto exit;
6063 }
6064
6065 if ((!ifr) || (!ifr->ifr_data)) {
6066 ret = -EINVAL;
6067 goto exit;
6068 }
6069
6070 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6071 ret = wlan_hdd_validate_context(pHddCtx);
6072 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006073 ret = -EBUSY;
6074 goto exit;
6075 }
6076
6077 switch (cmd) {
6078 case (SIOCDEVPRIVATE + 1):
6079 if (is_compat_task())
6080 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
6081 else
6082 ret = hdd_driver_ioctl(pAdapter, ifr);
6083 break;
6084 default:
6085 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
6086 __func__, cmd);
6087 ret = -EINVAL;
6088 break;
6089 }
6090 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306091 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006092 return ret;
6093}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006094
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306095int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6096{
6097 int ret;
6098
6099 vos_ssr_protect(__func__);
6100 ret = __hdd_ioctl(dev, ifr, cmd);
6101 vos_ssr_unprotect(__func__);
6102
6103 return ret;
6104}
6105
Katya Nigame7b69a82015-04-28 15:24:06 +05306106int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6107{
6108 return 0;
6109}
6110
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006111#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006112/**---------------------------------------------------------------------------
6113
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006114 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006115
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006116 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006117 CCXBEACONREQ<space><Number of fields><space><Measurement token>
6118 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
6119 <space>Scan Mode N<space>Meas Duration N
6120 if the Number of bcn req fields (N) does not match with the actual number of fields passed
6121 then take N.
6122 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
6123 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
6124 This function does not take care of removing duplicate channels from the list
6125
6126 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006127 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006128
6129 \return - 0 for success non-zero for failure
6130
6131 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006132static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
6133 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006134{
6135 tANI_U8 *inPtr = pValue;
6136 int tempInt = 0;
6137 int j = 0, i = 0, v = 0;
6138 char buf[32];
6139
6140 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6141 /*no argument after the command*/
6142 if (NULL == inPtr)
6143 {
6144 return -EINVAL;
6145 }
6146 /*no space after the command*/
6147 else if (SPACE_ASCII_VALUE != *inPtr)
6148 {
6149 return -EINVAL;
6150 }
6151
6152 /*removing empty spaces*/
6153 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6154
6155 /*no argument followed by spaces*/
6156 if ('\0' == *inPtr) return -EINVAL;
6157
6158 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006159 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006160 if (1 != v) return -EINVAL;
6161
6162 v = kstrtos32(buf, 10, &tempInt);
6163 if ( v < 0) return -EINVAL;
6164
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05306165 tempInt = VOS_MIN(tempInt, SIR_ESE_MAX_MEAS_IE_REQS);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006166 pEseBcnReq->numBcnReqIe = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006167
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05306168 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
6169
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006170
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006171 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006172 {
6173 for (i = 0; i < 4; i++)
6174 {
6175 /*inPtr pointing to the beginning of first space after number of ie fields*/
6176 inPtr = strpbrk( inPtr, " " );
6177 /*no ie data after the number of ie fields argument*/
6178 if (NULL == inPtr) return -EINVAL;
6179
6180 /*removing empty space*/
6181 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6182
6183 /*no ie data after the number of ie fields argument and spaces*/
6184 if ( '\0' == *inPtr ) return -EINVAL;
6185
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006186 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006187 if (1 != v) return -EINVAL;
6188
6189 v = kstrtos32(buf, 10, &tempInt);
6190 if (v < 0) return -EINVAL;
6191
6192 switch (i)
6193 {
6194 case 0: /* Measurement token */
6195 if (tempInt <= 0)
6196 {
6197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6198 "Invalid Measurement Token(%d)", tempInt);
6199 return -EINVAL;
6200 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006201 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006202 break;
6203
6204 case 1: /* Channel number */
6205 if ((tempInt <= 0) ||
6206 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6207 {
6208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6209 "Invalid Channel Number(%d)", tempInt);
6210 return -EINVAL;
6211 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006212 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006213 break;
6214
6215 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08006216 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006217 {
6218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6219 "Invalid Scan Mode(%d) Expected{0|1|2}", tempInt);
6220 return -EINVAL;
6221 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006222 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006223 break;
6224
6225 case 3: /* Measurement duration */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006226 if (((tempInt <= 0) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
6227 ((tempInt < 0) && (pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006228 {
6229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6230 "Invalid Measurement Duration(%d)", tempInt);
6231 return -EINVAL;
6232 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006233 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006234 break;
6235 }
6236 }
6237 }
6238
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006239 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006240 {
6241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306242 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006243 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006244 pEseBcnReq->bcnReq[j].measurementToken,
6245 pEseBcnReq->bcnReq[j].channel,
6246 pEseBcnReq->bcnReq[j].scanMode,
6247 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006248 }
6249
6250 return VOS_STATUS_SUCCESS;
6251}
6252
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006253static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
6254{
6255 struct statsContext *pStatsContext = NULL;
6256 hdd_adapter_t *pAdapter = NULL;
6257
6258 if (NULL == pContext)
6259 {
6260 hddLog(VOS_TRACE_LEVEL_ERROR,
6261 "%s: Bad param, pContext [%p]",
6262 __func__, pContext);
6263 return;
6264 }
6265
Jeff Johnson72a40512013-12-19 10:14:15 -08006266 /* there is a race condition that exists between this callback
6267 function and the caller since the caller could time out either
6268 before or while this code is executing. we use a spinlock to
6269 serialize these actions */
6270 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006271
6272 pStatsContext = pContext;
6273 pAdapter = pStatsContext->pAdapter;
6274 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
6275 {
6276 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08006277 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006278 hddLog(VOS_TRACE_LEVEL_WARN,
6279 "%s: Invalid context, pAdapter [%p] magic [%08x]",
6280 __func__, pAdapter, pStatsContext->magic);
6281 return;
6282 }
6283
Jeff Johnson72a40512013-12-19 10:14:15 -08006284 /* context is valid so caller is still waiting */
6285
6286 /* paranoia: invalidate the magic */
6287 pStatsContext->magic = 0;
6288
6289 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006290 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
6291 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
6292 tsmMetrics.UplinkPktQueueDlyHist,
6293 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6294 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6295 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
6296 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
6297 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
6298 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
6299 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
6300
Jeff Johnson72a40512013-12-19 10:14:15 -08006301 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006302 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08006303
6304 /* serialization is complete */
6305 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006306}
6307
6308
6309
6310static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
6311 tAniTrafStrmMetrics* pTsmMetrics)
6312{
6313 hdd_station_ctx_t *pHddStaCtx = NULL;
6314 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08006315 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006316 long lrc;
6317 struct statsContext context;
6318 hdd_context_t *pHddCtx = NULL;
6319
6320 if (NULL == pAdapter)
6321 {
6322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
6323 return VOS_STATUS_E_FAULT;
6324 }
6325
6326 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6327 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6328
6329 /* we are connected prepare our callback context */
6330 init_completion(&context.completion);
6331 context.pAdapter = pAdapter;
6332 context.magic = STATS_CONTEXT_MAGIC;
6333
6334 /* query tsm stats */
6335 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
6336 pHddStaCtx->conn_info.staId[ 0 ],
6337 pHddStaCtx->conn_info.bssId,
6338 &context, pHddCtx->pvosContext, tid);
6339
6340 if (eHAL_STATUS_SUCCESS != hstatus)
6341 {
Jeff Johnson72a40512013-12-19 10:14:15 -08006342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
6343 __func__);
6344 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006345 }
6346 else
6347 {
6348 /* request was sent -- wait for the response */
6349 lrc = wait_for_completion_interruptible_timeout(&context.completion,
6350 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006351 if (lrc <= 0)
6352 {
6353 hddLog(VOS_TRACE_LEVEL_ERROR,
6354 "%s: SME %s while retrieving statistics",
6355 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08006356 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006357 }
6358 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006359
Jeff Johnson72a40512013-12-19 10:14:15 -08006360 /* either we never sent a request, we sent a request and received a
6361 response or we sent a request and timed out. if we never sent a
6362 request or if we sent a request and got a response, we want to
6363 clear the magic out of paranoia. if we timed out there is a
6364 race condition such that the callback function could be
6365 executing at the same time we are. of primary concern is if the
6366 callback function had already verified the "magic" but had not
6367 yet set the completion variable when a timeout occurred. we
6368 serialize these activities by invalidating the magic while
6369 holding a shared spinlock which will cause us to block if the
6370 callback is currently executing */
6371 spin_lock(&hdd_context_lock);
6372 context.magic = 0;
6373 spin_unlock(&hdd_context_lock);
6374
6375 if (VOS_STATUS_SUCCESS == vstatus)
6376 {
6377 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
6378 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
6379 pAdapter->tsmStats.UplinkPktQueueDlyHist,
6380 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6381 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6382 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
6383 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
6384 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
6385 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
6386 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
6387 }
6388 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006389}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006390#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006391
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006392#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08006393void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
6394{
6395 eCsrBand band = -1;
6396 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
6397 switch (band)
6398 {
6399 case eCSR_BAND_ALL:
6400 *pBand = WLAN_HDD_UI_BAND_AUTO;
6401 break;
6402
6403 case eCSR_BAND_24:
6404 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
6405 break;
6406
6407 case eCSR_BAND_5G:
6408 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
6409 break;
6410
6411 default:
6412 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
6413 *pBand = -1;
6414 break;
6415 }
6416}
6417
6418/**---------------------------------------------------------------------------
6419
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006420 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
6421
6422 This function parses the send action frame data passed in the format
6423 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
6424
Srinivas Girigowda56076852013-08-20 14:00:50 -07006425 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006426 \param - pTargetApBssid Pointer to target Ap bssid
6427 \param - pChannel Pointer to the Target AP channel
6428 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
6429 \param - pBuf Pointer to data
6430 \param - pBufLen Pointer to data length
6431
6432 \return - 0 for success non-zero for failure
6433
6434 --------------------------------------------------------------------------*/
6435VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
6436 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
6437{
6438 tANI_U8 *inPtr = pValue;
6439 tANI_U8 *dataEnd;
6440 int tempInt;
6441 int j = 0;
6442 int i = 0;
6443 int v = 0;
6444 tANI_U8 tempBuf[32];
6445 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006446 /* 12 hexa decimal digits, 5 ':' and '\0' */
6447 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006448
6449 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6450 /*no argument after the command*/
6451 if (NULL == inPtr)
6452 {
6453 return -EINVAL;
6454 }
6455
6456 /*no space after the command*/
6457 else if (SPACE_ASCII_VALUE != *inPtr)
6458 {
6459 return -EINVAL;
6460 }
6461
6462 /*removing empty spaces*/
6463 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6464
6465 /*no argument followed by spaces*/
6466 if ('\0' == *inPtr)
6467 {
6468 return -EINVAL;
6469 }
6470
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006471 v = sscanf(inPtr, "%17s", macAddress);
6472 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006473 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6475 "Invalid MAC address or All hex inputs are not read (%d)", v);
6476 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006477 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006478
6479 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6480 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6481 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6482 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6483 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6484 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006485
6486 /* point to the next argument */
6487 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6488 /*no argument after the command*/
6489 if (NULL == inPtr) return -EINVAL;
6490
6491 /*removing empty spaces*/
6492 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6493
6494 /*no argument followed by spaces*/
6495 if ('\0' == *inPtr)
6496 {
6497 return -EINVAL;
6498 }
6499
6500 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006501 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006502 if (1 != v) return -EINVAL;
6503
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006504 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05306505 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05306506 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006507
6508 *pChannel = tempInt;
6509
6510 /* point to the next argument */
6511 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6512 /*no argument after the command*/
6513 if (NULL == inPtr) return -EINVAL;
6514 /*removing empty spaces*/
6515 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6516
6517 /*no argument followed by spaces*/
6518 if ('\0' == *inPtr)
6519 {
6520 return -EINVAL;
6521 }
6522
6523 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006524 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006525 if (1 != v) return -EINVAL;
6526
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006527 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08006528 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006529
6530 *pDwellTime = tempInt;
6531
6532 /* point to the next argument */
6533 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6534 /*no argument after the command*/
6535 if (NULL == inPtr) return -EINVAL;
6536 /*removing empty spaces*/
6537 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6538
6539 /*no argument followed by spaces*/
6540 if ('\0' == *inPtr)
6541 {
6542 return -EINVAL;
6543 }
6544
6545 /* find the length of data */
6546 dataEnd = inPtr;
6547 while(('\0' != *dataEnd) )
6548 {
6549 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006550 }
Kiet Lambe150c22013-11-21 16:30:32 +05306551 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006552 if ( *pBufLen <= 0) return -EINVAL;
6553
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07006554 /* Allocate the number of bytes based on the number of input characters
6555 whether it is even or odd.
6556 if the number of input characters are even, then we need N/2 byte.
6557 if the number of input characters are odd, then we need do (N+1)/2 to
6558 compensate rounding off.
6559 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6560 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6561 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006562 if (NULL == *pBuf)
6563 {
6564 hddLog(VOS_TRACE_LEVEL_FATAL,
6565 "%s: vos_mem_alloc failed ", __func__);
6566 return -EINVAL;
6567 }
6568
6569 /* the buffer received from the upper layer is character buffer,
6570 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6571 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6572 and f0 in 3rd location */
6573 for (i = 0, j = 0; j < *pBufLen; j += 2)
6574 {
Kiet Lambe150c22013-11-21 16:30:32 +05306575 if( j+1 == *pBufLen)
6576 {
6577 tempByte = hdd_parse_hex(inPtr[j]);
6578 }
6579 else
6580 {
6581 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6582 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006583 (*pBuf)[i++] = tempByte;
6584 }
6585 *pBufLen = i;
6586 return VOS_STATUS_SUCCESS;
6587}
6588
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006589/**---------------------------------------------------------------------------
6590
Srinivas Girigowdade697412013-02-14 16:31:48 -08006591 \brief hdd_parse_channellist() - HDD Parse channel list
6592
6593 This function parses the channel list passed in the format
6594 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006595 if the Number of channels (N) does not match with the actual number of channels passed
6596 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
6597 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
6598 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
6599 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08006600
6601 \param - pValue Pointer to input channel list
6602 \param - ChannelList Pointer to local output array to record channel list
6603 \param - pNumChannels Pointer to number of roam scan channels
6604
6605 \return - 0 for success non-zero for failure
6606
6607 --------------------------------------------------------------------------*/
6608VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
6609{
6610 tANI_U8 *inPtr = pValue;
6611 int tempInt;
6612 int j = 0;
6613 int v = 0;
6614 char buf[32];
6615
6616 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6617 /*no argument after the command*/
6618 if (NULL == inPtr)
6619 {
6620 return -EINVAL;
6621 }
6622
6623 /*no space after the command*/
6624 else if (SPACE_ASCII_VALUE != *inPtr)
6625 {
6626 return -EINVAL;
6627 }
6628
6629 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006630 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006631
6632 /*no argument followed by spaces*/
6633 if ('\0' == *inPtr)
6634 {
6635 return -EINVAL;
6636 }
6637
6638 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006639 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006640 if (1 != v) return -EINVAL;
6641
Srinivas Girigowdade697412013-02-14 16:31:48 -08006642 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006643 if ((v < 0) ||
6644 (tempInt <= 0) ||
6645 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
6646 {
6647 return -EINVAL;
6648 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006649
6650 *pNumChannels = tempInt;
6651
6652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6653 "Number of channels are: %d", *pNumChannels);
6654
6655 for (j = 0; j < (*pNumChannels); j++)
6656 {
6657 /*inPtr pointing to the beginning of first space after number of channels*/
6658 inPtr = strpbrk( inPtr, " " );
6659 /*no channel list after the number of channels argument*/
6660 if (NULL == inPtr)
6661 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006662 if (0 != j)
6663 {
6664 *pNumChannels = j;
6665 return VOS_STATUS_SUCCESS;
6666 }
6667 else
6668 {
6669 return -EINVAL;
6670 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006671 }
6672
6673 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006674 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006675
6676 /*no channel list after the number of channels argument and spaces*/
6677 if ( '\0' == *inPtr )
6678 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006679 if (0 != j)
6680 {
6681 *pNumChannels = j;
6682 return VOS_STATUS_SUCCESS;
6683 }
6684 else
6685 {
6686 return -EINVAL;
6687 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006688 }
6689
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006690 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006691 if (1 != v) return -EINVAL;
6692
Srinivas Girigowdade697412013-02-14 16:31:48 -08006693 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006694 if ((v < 0) ||
6695 (tempInt <= 0) ||
6696 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6697 {
6698 return -EINVAL;
6699 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006700 pChannelList[j] = tempInt;
6701
6702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6703 "Channel %d added to preferred channel list",
6704 pChannelList[j] );
6705 }
6706
Srinivas Girigowdade697412013-02-14 16:31:48 -08006707 return VOS_STATUS_SUCCESS;
6708}
6709
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006710
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05306711/**
6712 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
6713 * This function parses the reasoc command data passed in the format
6714 * REASSOC<space><bssid><space><channel>
6715 *
6716 * @pValue: Pointer to input data (its a NUL terminated string)
6717 * @pTargetApBssid: Pointer to target Ap bssid
6718 * @pChannel: Pointer to the Target AP channel
6719 *
6720 * Return: 0 for success non-zero for failure
6721 */
6722static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
6723 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006724{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05306725 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006726 int tempInt;
6727 int v = 0;
6728 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006729 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006730 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006731
6732 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6733 /*no argument after the command*/
6734 if (NULL == inPtr)
6735 {
6736 return -EINVAL;
6737 }
6738
6739 /*no space after the command*/
6740 else if (SPACE_ASCII_VALUE != *inPtr)
6741 {
6742 return -EINVAL;
6743 }
6744
6745 /*removing empty spaces*/
6746 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6747
6748 /*no argument followed by spaces*/
6749 if ('\0' == *inPtr)
6750 {
6751 return -EINVAL;
6752 }
6753
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006754 v = sscanf(inPtr, "%17s", macAddress);
6755 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006756 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6758 "Invalid MAC address or All hex inputs are not read (%d)", v);
6759 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006760 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006761
6762 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6763 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6764 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6765 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6766 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6767 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006768
6769 /* point to the next argument */
6770 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6771 /*no argument after the command*/
6772 if (NULL == inPtr) return -EINVAL;
6773
6774 /*removing empty spaces*/
6775 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6776
6777 /*no argument followed by spaces*/
6778 if ('\0' == *inPtr)
6779 {
6780 return -EINVAL;
6781 }
6782
6783 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006784 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006785 if (1 != v) return -EINVAL;
6786
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006787 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006788 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05306789 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006790 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6791 {
6792 return -EINVAL;
6793 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006794
6795 *pChannel = tempInt;
6796 return VOS_STATUS_SUCCESS;
6797}
6798
6799#endif
6800
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006801#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006802/**---------------------------------------------------------------------------
6803
6804 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
6805
6806 This function parses the SETCCKM IE command
6807 SETCCKMIE<space><ie data>
6808
6809 \param - pValue Pointer to input data
6810 \param - pCckmIe Pointer to output cckm Ie
6811 \param - pCckmIeLen Pointer to output cckm ie length
6812
6813 \return - 0 for success non-zero for failure
6814
6815 --------------------------------------------------------------------------*/
6816VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
6817 tANI_U8 *pCckmIeLen)
6818{
6819 tANI_U8 *inPtr = pValue;
6820 tANI_U8 *dataEnd;
6821 int j = 0;
6822 int i = 0;
6823 tANI_U8 tempByte = 0;
6824
6825 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6826 /*no argument after the command*/
6827 if (NULL == inPtr)
6828 {
6829 return -EINVAL;
6830 }
6831
6832 /*no space after the command*/
6833 else if (SPACE_ASCII_VALUE != *inPtr)
6834 {
6835 return -EINVAL;
6836 }
6837
6838 /*removing empty spaces*/
6839 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6840
6841 /*no argument followed by spaces*/
6842 if ('\0' == *inPtr)
6843 {
6844 return -EINVAL;
6845 }
6846
6847 /* find the length of data */
6848 dataEnd = inPtr;
6849 while(('\0' != *dataEnd) )
6850 {
6851 dataEnd++;
6852 ++(*pCckmIeLen);
6853 }
6854 if ( *pCckmIeLen <= 0) return -EINVAL;
6855
6856 /* Allocate the number of bytes based on the number of input characters
6857 whether it is even or odd.
6858 if the number of input characters are even, then we need N/2 byte.
6859 if the number of input characters are odd, then we need do (N+1)/2 to
6860 compensate rounding off.
6861 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6862 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6863 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
6864 if (NULL == *pCckmIe)
6865 {
6866 hddLog(VOS_TRACE_LEVEL_FATAL,
6867 "%s: vos_mem_alloc failed ", __func__);
6868 return -EINVAL;
6869 }
6870 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
6871 /* the buffer received from the upper layer is character buffer,
6872 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6873 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6874 and f0 in 3rd location */
6875 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
6876 {
6877 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6878 (*pCckmIe)[i++] = tempByte;
6879 }
6880 *pCckmIeLen = i;
6881
6882 return VOS_STATUS_SUCCESS;
6883}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006884#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006885
Jeff Johnson295189b2012-06-20 16:38:30 -07006886/**---------------------------------------------------------------------------
6887
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006888 \brief hdd_is_valid_mac_address() - Validate MAC address
6889
6890 This function validates whether the given MAC address is valid or not
6891 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
6892 where X is the hexa decimal digit character and separated by ':'
6893 This algorithm works even if MAC address is not separated by ':'
6894
6895 This code checks given input string mac contains exactly 12 hexadecimal digits.
6896 and a separator colon : appears in the input string only after
6897 an even number of hex digits.
6898
6899 \param - pMacAddr pointer to the input MAC address
6900 \return - 1 for valid and 0 for invalid
6901
6902 --------------------------------------------------------------------------*/
6903
6904v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
6905{
6906 int xdigit = 0;
6907 int separator = 0;
6908 while (*pMacAddr)
6909 {
6910 if (isxdigit(*pMacAddr))
6911 {
6912 xdigit++;
6913 }
6914 else if (':' == *pMacAddr)
6915 {
6916 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
6917 break;
6918
6919 ++separator;
6920 }
6921 else
6922 {
6923 separator = -1;
6924 /* Invalid MAC found */
6925 return 0;
6926 }
6927 ++pMacAddr;
6928 }
6929 return (xdigit == 12 && (separator == 5 || separator == 0));
6930}
6931
6932/**---------------------------------------------------------------------------
6933
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306934 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07006935
6936 \param - dev Pointer to net_device structure
6937
6938 \return - 0 for success non-zero for failure
6939
6940 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306941int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07006942{
6943 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6944 hdd_context_t *pHddCtx;
6945 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6946 VOS_STATUS status;
6947 v_BOOL_t in_standby = TRUE;
6948
6949 if (NULL == pAdapter)
6950 {
6951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05306952 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 return -ENODEV;
6954 }
6955
6956 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306957 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
6958 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 if (NULL == pHddCtx)
6960 {
6961 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006962 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 return -ENODEV;
6964 }
6965
6966 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6967 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
6968 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006969 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
6970 {
6971 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306972 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006973 in_standby = FALSE;
6974 break;
6975 }
6976 else
6977 {
6978 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6979 pAdapterNode = pNext;
6980 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 }
6982
6983 if (TRUE == in_standby)
6984 {
6985 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
6986 {
6987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
6988 "wlan out of power save", __func__);
6989 return -EINVAL;
6990 }
6991 }
6992
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006993 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006994 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6995 {
6996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006997 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006998 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05306999 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 netif_tx_start_all_queues(dev);
7001 }
7002
7003 return 0;
7004}
7005
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307006/**---------------------------------------------------------------------------
7007
7008 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
7009
7010 This is called in response to ifconfig up
7011
7012 \param - dev Pointer to net_device structure
7013
7014 \return - 0 for success non-zero for failure
7015
7016 --------------------------------------------------------------------------*/
7017int hdd_open(struct net_device *dev)
7018{
7019 int ret;
7020
7021 vos_ssr_protect(__func__);
7022 ret = __hdd_open(dev);
7023 vos_ssr_unprotect(__func__);
7024
7025 return ret;
7026}
7027
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307028int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007029{
7030 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7031
7032 if(pAdapter == NULL) {
7033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007034 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007035 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007036 }
7037
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 return 0;
7039}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307040
7041int hdd_mon_open (struct net_device *dev)
7042{
7043 int ret;
7044
7045 vos_ssr_protect(__func__);
7046 ret = __hdd_mon_open(dev);
7047 vos_ssr_unprotect(__func__);
7048
7049 return ret;
7050}
7051
Katya Nigame7b69a82015-04-28 15:24:06 +05307052int hdd_mon_stop(struct net_device *dev)
7053{
7054 return 0;
7055}
7056
Jeff Johnson295189b2012-06-20 16:38:30 -07007057/**---------------------------------------------------------------------------
7058
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307059 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07007060
7061 \param - dev Pointer to net_device structure
7062
7063 \return - 0 for success non-zero for failure
7064
7065 --------------------------------------------------------------------------*/
7066
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307067int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007068{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307069 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007070 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7071 hdd_context_t *pHddCtx;
7072 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7073 VOS_STATUS status;
7074 v_BOOL_t enter_standby = TRUE;
7075
7076 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 if (NULL == pAdapter)
7078 {
7079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05307080 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007081 return -ENODEV;
7082 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05307083 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307084 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307085
7086 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7087 ret = wlan_hdd_validate_context(pHddCtx);
7088 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307090 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007091 }
7092
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307093 /* Nothing to be done if the interface is not opened */
7094 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
7095 {
7096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7097 "%s: NETDEV Interface is not OPENED", __func__);
7098 return -ENODEV;
7099 }
7100
7101 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007102 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07007103 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307104
7105 /* Disable TX on the interface, after this hard_start_xmit() will not
7106 * be called on that interface
7107 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307108 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007109 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307110
7111 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 netif_carrier_off(pAdapter->dev);
7113
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307114 /* The interface is marked as down for outside world (aka kernel)
7115 * But the driver is pretty much alive inside. The driver needs to
7116 * tear down the existing connection on the netdev (session)
7117 * cleanup the data pipes and wait until the control plane is stabilized
7118 * for this interface. The call also needs to wait until the above
7119 * mentioned actions are completed before returning to the caller.
7120 * Notice that the hdd_stop_adapter is requested not to close the session
7121 * That is intentional to be able to scan if it is a STA/P2P interface
7122 */
7123 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307124#ifdef FEATURE_WLAN_TDLS
7125 mutex_lock(&pHddCtx->tdls_lock);
7126#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307127 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05307128 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307129#ifdef FEATURE_WLAN_TDLS
7130 mutex_unlock(&pHddCtx->tdls_lock);
7131#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007132 /* SoftAP ifaces should never go in power save mode
7133 making sure same here. */
7134 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
7135 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007136 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 )
7138 {
7139 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7141 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 EXIT();
7143 return 0;
7144 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307145 /* Find if any iface is up. If any iface is up then can't put device to
7146 * sleep/power save mode
7147 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007148 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7149 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
7150 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007151 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
7152 {
7153 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307154 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007155 enter_standby = FALSE;
7156 break;
7157 }
7158 else
7159 {
7160 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7161 pAdapterNode = pNext;
7162 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007163 }
7164
7165 if (TRUE == enter_standby)
7166 {
7167 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
7168 "entering standby", __func__);
7169 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
7170 {
7171 /*log and return success*/
7172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
7173 "wlan in power save", __func__);
7174 }
7175 }
7176
7177 EXIT();
7178 return 0;
7179}
7180
7181/**---------------------------------------------------------------------------
7182
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307183 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07007184
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307185 This is called in response to ifconfig down
7186
7187 \param - dev Pointer to net_device structure
7188
7189 \return - 0 for success non-zero for failure
7190-----------------------------------------------------------------------------*/
7191int hdd_stop (struct net_device *dev)
7192{
7193 int ret;
7194
7195 vos_ssr_protect(__func__);
7196 ret = __hdd_stop(dev);
7197 vos_ssr_unprotect(__func__);
7198
7199 return ret;
7200}
7201
7202/**---------------------------------------------------------------------------
7203
7204 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07007205
7206 \param - dev Pointer to net_device structure
7207
7208 \return - void
7209
7210 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307211static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007212{
7213 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307214 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007215 ENTER();
7216
7217 do
7218 {
7219 if (NULL == pAdapter)
7220 {
7221 hddLog(VOS_TRACE_LEVEL_FATAL,
7222 "%s: NULL pAdapter", __func__);
7223 break;
7224 }
7225
7226 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7227 {
7228 hddLog(VOS_TRACE_LEVEL_FATAL,
7229 "%s: Invalid magic", __func__);
7230 break;
7231 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7233 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 {
7235 hddLog(VOS_TRACE_LEVEL_FATAL,
7236 "%s: NULL pHddCtx", __func__);
7237 break;
7238 }
7239
7240 if (dev != pAdapter->dev)
7241 {
7242 hddLog(VOS_TRACE_LEVEL_FATAL,
7243 "%s: Invalid device reference", __func__);
7244 /* we haven't validated all cases so let this go for now */
7245 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307246#ifdef FEATURE_WLAN_TDLS
7247 mutex_lock(&pHddCtx->tdls_lock);
7248#endif
c_hpothu002231a2015-02-05 14:58:51 +05307249 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307250#ifdef FEATURE_WLAN_TDLS
7251 mutex_unlock(&pHddCtx->tdls_lock);
7252#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007253
7254 /* after uninit our adapter structure will no longer be valid */
7255 pAdapter->dev = NULL;
7256 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05307257 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 } while (0);
7259
7260 EXIT();
7261}
7262
7263/**---------------------------------------------------------------------------
7264
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307265 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
7266
7267 This is called during the netdev unregister to uninitialize all data
7268associated with the device
7269
7270 \param - dev Pointer to net_device structure
7271
7272 \return - void
7273
7274 --------------------------------------------------------------------------*/
7275static void hdd_uninit (struct net_device *dev)
7276{
7277 vos_ssr_protect(__func__);
7278 __hdd_uninit(dev);
7279 vos_ssr_unprotect(__func__);
7280}
7281
7282/**---------------------------------------------------------------------------
7283
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 \brief hdd_release_firmware() -
7285
7286 This function calls the release firmware API to free the firmware buffer.
7287
7288 \param - pFileName Pointer to the File Name.
7289 pCtx - Pointer to the adapter .
7290
7291
7292 \return - 0 for success, non zero for failure
7293
7294 --------------------------------------------------------------------------*/
7295
7296VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
7297{
7298 VOS_STATUS status = VOS_STATUS_SUCCESS;
7299 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7300 ENTER();
7301
7302
7303 if (!strcmp(WLAN_FW_FILE, pFileName)) {
7304
7305 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
7306
7307 if(pHddCtx->fw) {
7308 release_firmware(pHddCtx->fw);
7309 pHddCtx->fw = NULL;
7310 }
7311 else
7312 status = VOS_STATUS_E_FAILURE;
7313 }
7314 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
7315 if(pHddCtx->nv) {
7316 release_firmware(pHddCtx->nv);
7317 pHddCtx->nv = NULL;
7318 }
7319 else
7320 status = VOS_STATUS_E_FAILURE;
7321
7322 }
7323
7324 EXIT();
7325 return status;
7326}
7327
7328/**---------------------------------------------------------------------------
7329
7330 \brief hdd_request_firmware() -
7331
7332 This function reads the firmware file using the request firmware
7333 API and returns the the firmware data and the firmware file size.
7334
7335 \param - pfileName - Pointer to the file name.
7336 - pCtx - Pointer to the adapter .
7337 - ppfw_data - Pointer to the pointer of the firmware data.
7338 - pSize - Pointer to the file size.
7339
7340 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
7341
7342 --------------------------------------------------------------------------*/
7343
7344
7345VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
7346{
7347 int status;
7348 VOS_STATUS retval = VOS_STATUS_SUCCESS;
7349 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7350 ENTER();
7351
7352 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
7353
7354 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
7355
7356 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7357 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
7358 __func__, pfileName);
7359 retval = VOS_STATUS_E_FAILURE;
7360 }
7361
7362 else {
7363 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
7364 *pSize = pHddCtx->fw->size;
7365 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
7366 __func__, *pSize);
7367 }
7368 }
7369 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
7370
7371 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
7372
7373 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
7374 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
7375 __func__, pfileName);
7376 retval = VOS_STATUS_E_FAILURE;
7377 }
7378
7379 else {
7380 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
7381 *pSize = pHddCtx->nv->size;
7382 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
7383 __func__, *pSize);
7384 }
7385 }
7386
7387 EXIT();
7388 return retval;
7389}
7390/**---------------------------------------------------------------------------
7391 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
7392
7393 This is the function invoked by SME to inform the result of a full power
7394 request issued by HDD
7395
7396 \param - callbackcontext - Pointer to cookie
7397 status - result of request
7398
7399 \return - None
7400
7401--------------------------------------------------------------------------*/
7402void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
7403{
7404 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
7405
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007406 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007407 if(&pHddCtx->full_pwr_comp_var)
7408 {
7409 complete(&pHddCtx->full_pwr_comp_var);
7410 }
7411}
7412
Abhishek Singh00b71972016-01-07 10:51:04 +05307413#ifdef WLAN_FEATURE_RMC
7414static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
7415{
7416 int payload_len;
7417 struct sk_buff *skb;
7418 struct nlmsghdr *nlh;
7419 v_U8_t *data;
7420
7421 payload_len = ETH_ALEN;
7422
7423 if (0 == cesium_pid)
7424 {
7425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
7426 __func__);
7427 return;
7428 }
7429
7430 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
7431 {
7432 hddLog(VOS_TRACE_LEVEL_ERROR,
7433 "%s: nlmsg_new() failed for msg size[%d]",
7434 __func__, NLMSG_SPACE(payload_len));
7435 return;
7436 }
7437
7438 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
7439
7440 if (NULL == nlh)
7441 {
7442 hddLog(VOS_TRACE_LEVEL_ERROR,
7443 "%s: nlmsg_put() failed for msg size[%d]",
7444 __func__, NLMSG_SPACE(payload_len));
7445
7446 kfree_skb(skb);
7447 return;
7448 }
7449
7450 data = nlmsg_data(nlh);
7451 memcpy(data, MacAddr, ETH_ALEN);
7452
7453 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
7454 {
7455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
7456 __func__, NLMSG_SPACE(payload_len));
7457 }
7458
7459 return;
7460}
7461
7462/**---------------------------------------------------------------------------
7463 \brief hdd_ParseuserParams - return a pointer to the next argument
7464
7465 \return - status
7466
7467--------------------------------------------------------------------------*/
7468static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
7469{
7470 tANI_U8 *pVal;
7471
7472 pVal = strchr(pValue, ' ');
7473
7474 if (NULL == pVal)
7475 {
7476 /* no argument remains */
7477 return -EINVAL;
7478 }
7479 else if (SPACE_ASCII_VALUE != *pVal)
7480 {
7481 /* no space after the current argument */
7482 return -EINVAL;
7483 }
7484
7485 pVal++;
7486
7487 /* remove empty spaces */
7488 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
7489 {
7490 pVal++;
7491 }
7492
7493 /* no argument followed by spaces */
7494 if ('\0' == *pVal)
7495 {
7496 return -EINVAL;
7497 }
7498
7499 *ppArg = pVal;
7500
7501 return 0;
7502}
7503
7504/**----------------------------------------------------------------------------
7505 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
7506
7507 \return - status
7508
7509------------------------------------------------------------------------------*/
7510static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
7511 tANI_U8 *tx_fail_count,
7512 tANI_U16 *pid)
7513{
7514 tANI_U8 *param = NULL;
7515 int ret;
7516
7517 ret = hdd_ParseUserParams(pValue, &param);
7518
7519 if (0 == ret && NULL != param)
7520 {
7521 if (1 != sscanf(param, "%hhu", tx_fail_count))
7522 {
7523 ret = -EINVAL;
7524 goto done;
7525 }
7526 }
7527 else
7528 {
7529 goto done;
7530 }
7531
7532 if (0 == *tx_fail_count)
7533 {
7534 *pid = 0;
7535 goto done;
7536 }
7537
7538 pValue = param;
7539 pValue++;
7540
7541 ret = hdd_ParseUserParams(pValue, &param);
7542
7543 if (0 == ret)
7544 {
7545 if (1 != sscanf(param, "%hu", pid))
7546 {
7547 ret = -EINVAL;
7548 goto done;
7549 }
7550 }
7551 else
7552 {
7553 goto done;
7554 }
7555
7556done:
7557 return ret;
7558}
7559
7560static int hdd_open_cesium_nl_sock()
7561{
7562#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7563 struct netlink_kernel_cfg cfg = {
7564 .groups = WLAN_NLINK_MCAST_GRP_ID,
7565 .input = NULL
7566 };
7567#endif
7568 int ret = 0;
7569
7570#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7571 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7572#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
7573 THIS_MODULE,
7574#endif
7575 &cfg);
7576#else
7577 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7578 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
7579#endif
7580
7581 if (cesium_nl_srv_sock == NULL)
7582 {
7583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7584 "NLINK: cesium netlink_kernel_create failed");
7585 ret = -ECONNREFUSED;
7586 }
7587
7588 return ret;
7589}
7590
7591static void hdd_close_cesium_nl_sock()
7592{
7593 if (NULL != cesium_nl_srv_sock)
7594 {
7595 netlink_kernel_release(cesium_nl_srv_sock);
7596 cesium_nl_srv_sock = NULL;
7597 }
7598}
7599#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007600/**---------------------------------------------------------------------------
7601
7602 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
7603
7604 This is the function invoked by SME to inform the result of BMPS
7605 request issued by HDD
7606
7607 \param - callbackcontext - Pointer to cookie
7608 status - result of request
7609
7610 \return - None
7611
7612--------------------------------------------------------------------------*/
7613void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
7614{
7615
7616 struct completion *completion_var = (struct completion*) callbackContext;
7617
Arif Hussain6d2a3322013-11-17 19:50:10 -08007618 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 if(completion_var != NULL)
7620 {
7621 complete(completion_var);
7622 }
7623}
7624
7625/**---------------------------------------------------------------------------
7626
7627 \brief hdd_get_cfg_file_size() -
7628
7629 This function reads the configuration file using the request firmware
7630 API and returns the configuration file size.
7631
7632 \param - pCtx - Pointer to the adapter .
7633 - pFileName - Pointer to the file name.
7634 - pBufSize - Pointer to the buffer size.
7635
7636 \return - 0 for success, non zero for failure
7637
7638 --------------------------------------------------------------------------*/
7639
7640VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
7641{
7642 int status;
7643 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7644
7645 ENTER();
7646
7647 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7648
7649 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7650 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7651 status = VOS_STATUS_E_FAILURE;
7652 }
7653 else {
7654 *pBufSize = pHddCtx->fw->size;
7655 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
7656 release_firmware(pHddCtx->fw);
7657 pHddCtx->fw = NULL;
7658 }
7659
7660 EXIT();
7661 return VOS_STATUS_SUCCESS;
7662}
7663
7664/**---------------------------------------------------------------------------
7665
7666 \brief hdd_read_cfg_file() -
7667
7668 This function reads the configuration file using the request firmware
7669 API and returns the cfg data and the buffer size of the configuration file.
7670
7671 \param - pCtx - Pointer to the adapter .
7672 - pFileName - Pointer to the file name.
7673 - pBuffer - Pointer to the data buffer.
7674 - pBufSize - Pointer to the buffer size.
7675
7676 \return - 0 for success, non zero for failure
7677
7678 --------------------------------------------------------------------------*/
7679
7680VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
7681 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
7682{
7683 int status;
7684 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7685
7686 ENTER();
7687
7688 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7689
7690 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7691 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7692 return VOS_STATUS_E_FAILURE;
7693 }
7694 else {
7695 if(*pBufSize != pHddCtx->fw->size) {
7696 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
7697 "file size", __func__);
7698 release_firmware(pHddCtx->fw);
7699 pHddCtx->fw = NULL;
7700 return VOS_STATUS_E_FAILURE;
7701 }
7702 else {
7703 if(pBuffer) {
7704 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
7705 }
7706 release_firmware(pHddCtx->fw);
7707 pHddCtx->fw = NULL;
7708 }
7709 }
7710
7711 EXIT();
7712
7713 return VOS_STATUS_SUCCESS;
7714}
7715
7716/**---------------------------------------------------------------------------
7717
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307718 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007719
7720 This function sets the user specified mac address using
7721 the command ifconfig wlanX hw ether <mac adress>.
7722
7723 \param - dev - Pointer to the net device.
7724 - addr - Pointer to the sockaddr.
7725 \return - 0 for success, non zero for failure
7726
7727 --------------------------------------------------------------------------*/
7728
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307729static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07007730{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307731 hdd_adapter_t *pAdapter;
7732 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007733 struct sockaddr *psta_mac_addr = addr;
7734 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307735 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007736
7737 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307738 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7739 if (NULL == pAdapter)
7740 {
7741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7742 "%s: Adapter is NULL",__func__);
7743 return -EINVAL;
7744 }
7745 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7746 ret = wlan_hdd_validate_context(pHddCtx);
7747 if (0 != ret)
7748 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307749 return ret;
7750 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007751
7752 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07007753 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
7754
7755 EXIT();
7756 return halStatus;
7757}
7758
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307759/**---------------------------------------------------------------------------
7760
7761 \brief hdd_set_mac_address() -
7762
7763 Wrapper function to protect __hdd_set_mac_address() function from ssr
7764
7765 \param - dev - Pointer to the net device.
7766 - addr - Pointer to the sockaddr.
7767 \return - 0 for success, non zero for failure
7768
7769 --------------------------------------------------------------------------*/
7770static int hdd_set_mac_address(struct net_device *dev, void *addr)
7771{
7772 int ret;
7773
7774 vos_ssr_protect(__func__);
7775 ret = __hdd_set_mac_address(dev, addr);
7776 vos_ssr_unprotect(__func__);
7777
7778 return ret;
7779}
7780
Jeff Johnson295189b2012-06-20 16:38:30 -07007781tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
7782{
7783 int i;
7784 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7785 {
Abhishek Singheb183782014-02-06 13:37:21 +05307786 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 break;
7788 }
7789
7790 if( VOS_MAX_CONCURRENCY_PERSONA == i)
7791 return NULL;
7792
7793 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
7794 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
7795}
7796
7797void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
7798{
7799 int i;
7800 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7801 {
7802 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
7803 {
7804 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
7805 break;
7806 }
7807 }
7808 return;
7809}
7810
7811#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7812 static struct net_device_ops wlan_drv_ops = {
7813 .ndo_open = hdd_open,
7814 .ndo_stop = hdd_stop,
7815 .ndo_uninit = hdd_uninit,
7816 .ndo_start_xmit = hdd_hard_start_xmit,
7817 .ndo_tx_timeout = hdd_tx_timeout,
7818 .ndo_get_stats = hdd_stats,
7819 .ndo_do_ioctl = hdd_ioctl,
7820 .ndo_set_mac_address = hdd_set_mac_address,
7821 .ndo_select_queue = hdd_select_queue,
7822#ifdef WLAN_FEATURE_PACKET_FILTERING
7823#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
7824 .ndo_set_rx_mode = hdd_set_multicast_list,
7825#else
7826 .ndo_set_multicast_list = hdd_set_multicast_list,
7827#endif //LINUX_VERSION_CODE
7828#endif
7829 };
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 static struct net_device_ops wlan_mon_drv_ops = {
7831 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05307832 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07007833 .ndo_uninit = hdd_uninit,
7834 .ndo_start_xmit = hdd_mon_hard_start_xmit,
7835 .ndo_tx_timeout = hdd_tx_timeout,
7836 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05307837 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07007838 .ndo_set_mac_address = hdd_set_mac_address,
7839 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05307840
Jeff Johnson295189b2012-06-20 16:38:30 -07007841#endif
7842
7843void hdd_set_station_ops( struct net_device *pWlanDev )
7844{
7845#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 pWlanDev->netdev_ops = &wlan_drv_ops;
7847#else
7848 pWlanDev->open = hdd_open;
7849 pWlanDev->stop = hdd_stop;
7850 pWlanDev->uninit = hdd_uninit;
7851 pWlanDev->hard_start_xmit = NULL;
7852 pWlanDev->tx_timeout = hdd_tx_timeout;
7853 pWlanDev->get_stats = hdd_stats;
7854 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007855 pWlanDev->set_mac_address = hdd_set_mac_address;
7856#endif
7857}
7858
Katya Nigam1fd24402015-02-16 14:52:19 +05307859void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
7860{
7861 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7862 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
7863 #else
7864 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
7865 #endif
7866}
7867
Jeff Johnsoneed415b2013-01-18 16:11:20 -08007868static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07007869{
7870 struct net_device *pWlanDev = NULL;
7871 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007872 /*
7873 * cfg80211 initialization and registration....
7874 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05307875 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
7876#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
7877 NET_NAME_UNKNOWN,
7878#endif
7879 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 if(pWlanDev != NULL)
7881 {
7882
7883 //Save the pointer to the net_device in the HDD adapter
7884 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
7885
Jeff Johnson295189b2012-06-20 16:38:30 -07007886 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
7887
7888 pAdapter->dev = pWlanDev;
7889 pAdapter->pHddCtx = pHddCtx;
7890 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05307891 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007892
Rajeev79dbe4c2013-10-05 11:03:42 +05307893#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05307894 pAdapter->pBatchScanRsp = NULL;
7895 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07007896 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007897 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05307898 mutex_init(&pAdapter->hdd_batch_scan_lock);
7899#endif
7900
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 pAdapter->isLinkUpSvcNeeded = FALSE;
7902 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
7903 //Init the net_device structure
7904 strlcpy(pWlanDev->name, name, IFNAMSIZ);
7905
7906 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
7907 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
7908 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
7909 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
7910
7911 hdd_set_station_ops( pAdapter->dev );
7912
7913 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007914 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
7915 pAdapter->wdev.wiphy = pHddCtx->wiphy;
7916 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007917 /* set pWlanDev's parent to underlying device */
7918 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07007919
7920 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007921 }
7922
7923 return pAdapter;
7924}
7925
7926VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
7927{
7928 struct net_device *pWlanDev = pAdapter->dev;
7929 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
7930 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
7931 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7932
7933 if( rtnl_lock_held )
7934 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08007935 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07007936 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
7937 {
7938 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
7939 return VOS_STATUS_E_FAILURE;
7940 }
7941 }
7942 if (register_netdevice(pWlanDev))
7943 {
7944 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
7945 return VOS_STATUS_E_FAILURE;
7946 }
7947 }
7948 else
7949 {
7950 if(register_netdev(pWlanDev))
7951 {
7952 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
7953 return VOS_STATUS_E_FAILURE;
7954 }
7955 }
7956 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
7957
7958 return VOS_STATUS_SUCCESS;
7959}
7960
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007961static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07007962{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007963 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007964
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007965 if (NULL == pAdapter)
7966 {
7967 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
7968 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07007969 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007970
7971 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7972 {
7973 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
7974 return eHAL_STATUS_NOT_INITIALIZED;
7975 }
7976
7977 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
7978
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007979#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007980 /* need to make sure all of our scheduled work has completed.
7981 * This callback is called from MC thread context, so it is safe to
7982 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007983 *
7984 * Even though this is called from MC thread context, if there is a faulty
7985 * work item in the system, that can hang this call forever. So flushing
7986 * this global work queue is not safe; and now we make sure that
7987 * individual work queues are stopped correctly. But the cancel work queue
7988 * is a GPL only API, so the proprietary version of the driver would still
7989 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007990 */
7991 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007992#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007993
7994 /* We can be blocked while waiting for scheduled work to be
7995 * flushed, and the adapter structure can potentially be freed, in
7996 * which case the magic will have been reset. So make sure the
7997 * magic is still good, and hence the adapter structure is still
7998 * valid, before signaling completion */
7999 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
8000 {
8001 complete(&pAdapter->session_close_comp_var);
8002 }
8003
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 return eHAL_STATUS_SUCCESS;
8005}
Manjeet Singh47ee8472016-04-11 11:57:18 +05308006/**
8007 * hdd_close_tx_queues() - close tx queues
8008 * @hdd_ctx: hdd global context
8009 *
8010 * Return: None
8011 */
8012static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
8013{
8014 VOS_STATUS status;
8015 hdd_adapter_t *adapter;
8016 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
8017 /* Not validating hdd_ctx as it's already done by the caller */
8018 ENTER();
8019 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
8020 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
8021 adapter = adapter_node->pAdapter;
8022 if (adapter && adapter->dev) {
8023 netif_tx_disable (adapter->dev);
8024 netif_carrier_off(adapter->dev);
8025 }
8026 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
8027 &next_adapter);
8028 adapter_node = next_adapter;
8029 }
8030 EXIT();
8031}
Jeff Johnson295189b2012-06-20 16:38:30 -07008032
8033VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
8034{
8035 struct net_device *pWlanDev = pAdapter->dev;
8036 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
8037 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8038 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8039 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308040 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008041
Nirav Shah7e3c8132015-06-22 23:51:42 +05308042 spin_lock_init( &pAdapter->sta_hash_lock);
8043 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
8044
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008046 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008047 //Open a SME session for future operation
8048 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008049 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8051 {
8052 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008053 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008054 halStatus, halStatus );
8055 status = VOS_STATUS_E_FAILURE;
8056 goto error_sme_open;
8057 }
8058
8059 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05308060 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 &pAdapter->session_open_comp_var,
8062 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308063 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 {
8065 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308066 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 status = VOS_STATUS_E_FAILURE;
8068 goto error_sme_open;
8069 }
8070
8071 // Register wireless extensions
8072 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
8073 {
8074 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008075 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008076 halStatus, halStatus );
8077 status = VOS_STATUS_E_FAILURE;
8078 goto error_register_wext;
8079 }
Katya Nigam1fd24402015-02-16 14:52:19 +05308080
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05308082 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8083 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
8084 #else
8085 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
8086 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008087
8088 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05308089 hddLog(VOS_TRACE_LEVEL_INFO,
8090 "%s: Set HDD connState to eConnectionState_NotConnected",
8091 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008092 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
8093
8094 //Set the default operation channel
8095 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
8096
8097 /* Make the default Auth Type as OPEN*/
8098 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
8099
8100 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
8101 {
8102 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008103 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 status, status );
8105 goto error_init_txrx;
8106 }
8107
8108 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8109
8110 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
8111 {
8112 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008113 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 status, status );
8115 goto error_wmm_init;
8116 }
8117
8118 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8119
8120 return VOS_STATUS_SUCCESS;
8121
8122error_wmm_init:
8123 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8124 hdd_deinit_tx_rx(pAdapter);
8125error_init_txrx:
8126 hdd_UnregisterWext(pWlanDev);
8127error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008128 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 {
8130 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008131 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05308132 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008133 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308135 unsigned long rc;
8136
Jeff Johnson295189b2012-06-20 16:38:30 -07008137 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308138 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008139 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008140 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308141 if (rc <= 0)
8142 hddLog(VOS_TRACE_LEVEL_ERROR,
8143 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008144 }
8145}
8146error_sme_open:
8147 return status;
8148}
8149
Jeff Johnson295189b2012-06-20 16:38:30 -07008150void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
8151{
8152 hdd_cfg80211_state_t *cfgState;
8153
8154 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
8155
8156 if( NULL != cfgState->buf )
8157 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308158 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07008159 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
8160 rc = wait_for_completion_interruptible_timeout(
8161 &pAdapter->tx_action_cnf_event,
8162 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308163 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05308165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8166 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
8167 , __func__, rc);
8168
8169 // Inform tx status as FAILURE to upper layer and free cfgState->buf
8170 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008171 }
8172 }
8173 return;
8174}
Jeff Johnson295189b2012-06-20 16:38:30 -07008175
c_hpothu002231a2015-02-05 14:58:51 +05308176void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07008177{
8178 ENTER();
8179 switch ( pAdapter->device_mode )
8180 {
Katya Nigam1fd24402015-02-16 14:52:19 +05308181 case WLAN_HDD_IBSS:
8182 {
8183 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8184 {
8185 hdd_ibss_deinit_tx_rx( pAdapter );
8186 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8187 }
8188 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 case WLAN_HDD_INFRA_STATION:
8190 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008191 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008192 {
8193 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8194 {
8195 hdd_deinit_tx_rx( pAdapter );
8196 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8197 }
8198
8199 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8200 {
8201 hdd_wmm_adapter_close( pAdapter );
8202 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8203 }
8204
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008206 break;
8207 }
8208
8209 case WLAN_HDD_SOFTAP:
8210 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008211 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05308212
8213 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8214 {
8215 hdd_wmm_adapter_close( pAdapter );
8216 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8217 }
8218
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008220
c_hpothu002231a2015-02-05 14:58:51 +05308221 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008222 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07008223 break;
8224 }
8225
8226 case WLAN_HDD_MONITOR:
8227 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008228 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8229 {
8230 hdd_deinit_tx_rx( pAdapter );
8231 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8232 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 break;
8234 }
8235
8236
8237 default:
8238 break;
8239 }
8240
8241 EXIT();
8242}
8243
8244void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
8245{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008246 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308247
8248 ENTER();
8249 if (NULL == pAdapter)
8250 {
8251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8252 "%s: HDD adapter is Null", __func__);
8253 return;
8254 }
8255
8256 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008257
Rajeev79dbe4c2013-10-05 11:03:42 +05308258#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308259 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8260 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08008261 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308262 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
8263 )
8264 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008265 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05308266 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008267 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
8268 {
8269 hdd_deinit_batch_scan(pAdapter);
8270 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308271 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08008272 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308273#endif
8274
Jeff Johnson295189b2012-06-20 16:38:30 -07008275 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
8276 if( rtnl_held )
8277 {
8278 unregister_netdevice(pWlanDev);
8279 }
8280 else
8281 {
8282 unregister_netdev(pWlanDev);
8283 }
8284 // note that the pAdapter is no longer valid at this point
8285 // since the memory has been reclaimed
8286 }
8287
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308288 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008289}
8290
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008291void hdd_set_pwrparams(hdd_context_t *pHddCtx)
8292{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308293 VOS_STATUS status;
8294 hdd_adapter_t *pAdapter = NULL;
8295 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008296
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308297 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008298
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308299 /*loop through all adapters.*/
8300 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008301 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308302 pAdapter = pAdapterNode->pAdapter;
8303 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
8304 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008305
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308306 { // we skip this registration for modes other than STA and P2P client modes.
8307 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8308 pAdapterNode = pNext;
8309 continue;
8310 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008311
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308312 //Apply Dynamic DTIM For P2P
8313 //Only if ignoreDynamicDtimInP2pMode is not set in ini
8314 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
8315 pHddCtx->cfg_ini->enableModulatedDTIM) &&
8316 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8317 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
8318 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
8319 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
8320 (eConnectionState_Associated ==
8321 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
8322 (pHddCtx->cfg_ini->fIsBmpsEnabled))
8323 {
8324 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008325
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308326 powerRequest.uIgnoreDTIM = 1;
8327 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
8328
8329 if (pHddCtx->cfg_ini->enableModulatedDTIM)
8330 {
8331 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
8332 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
8333 }
8334 else
8335 {
8336 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
8337 }
8338
8339 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
8340 * specified during Enter/Exit BMPS when LCD off*/
8341 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8342 NULL, eANI_BOOLEAN_FALSE);
8343 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8344 NULL, eANI_BOOLEAN_FALSE);
8345
8346 /* switch to the DTIM specified in cfg.ini */
8347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05308348 "Switch to DTIM %d Listen interval %d",
8349 powerRequest.uDTIMPeriod,
8350 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308351 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8352 break;
8353
8354 }
8355
8356 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8357 pAdapterNode = pNext;
8358 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008359}
8360
8361void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
8362{
8363 /*Switch back to DTIM 1*/
8364 tSirSetPowerParamsReq powerRequest = { 0 };
8365
8366 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
8367 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07008368 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008369
8370 /* Update ignoreDTIM and ListedInterval in CFG with default values */
8371 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8372 NULL, eANI_BOOLEAN_FALSE);
8373 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8374 NULL, eANI_BOOLEAN_FALSE);
8375
8376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8377 "Switch to DTIM%d",powerRequest.uListenInterval);
8378 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8379
8380}
8381
Jeff Johnson295189b2012-06-20 16:38:30 -07008382VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
8383{
8384 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05308385 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
8386 {
8387 hddLog( LOGE, FL("Wlan Unload in progress"));
8388 return VOS_STATUS_E_PERM;
8389 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008390 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8391 {
8392 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8393 }
8394
8395 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8396 {
8397 sme_StartAutoBmpsTimer(pHddCtx->hHal);
8398 }
8399
8400 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8401 {
8402 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8403 }
8404
8405 return status;
8406}
8407
8408VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
8409{
8410 hdd_adapter_t *pAdapter = NULL;
8411 eHalStatus halStatus;
8412 VOS_STATUS status = VOS_STATUS_E_INVAL;
8413 v_BOOL_t disableBmps = FALSE;
8414 v_BOOL_t disableImps = FALSE;
8415
8416 switch(session_type)
8417 {
8418 case WLAN_HDD_INFRA_STATION:
8419 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008420 case WLAN_HDD_P2P_CLIENT:
8421 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008422 //Exit BMPS -> Is Sta/P2P Client is already connected
8423 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
8424 if((NULL != pAdapter)&&
8425 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8426 {
8427 disableBmps = TRUE;
8428 }
8429
8430 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
8431 if((NULL != pAdapter)&&
8432 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8433 {
8434 disableBmps = TRUE;
8435 }
8436
8437 //Exit both Bmps and Imps incase of Go/SAP Mode
8438 if((WLAN_HDD_SOFTAP == session_type) ||
8439 (WLAN_HDD_P2P_GO == session_type))
8440 {
8441 disableBmps = TRUE;
8442 disableImps = TRUE;
8443 }
8444
8445 if(TRUE == disableImps)
8446 {
8447 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8448 {
8449 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8450 }
8451 }
8452
8453 if(TRUE == disableBmps)
8454 {
8455 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8456 {
8457 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8458
8459 if(eHAL_STATUS_SUCCESS != halStatus)
8460 {
8461 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008462 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 VOS_ASSERT(0);
8464 return status;
8465 }
8466 }
8467
8468 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8469 {
8470 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
8471
8472 if(eHAL_STATUS_SUCCESS != halStatus)
8473 {
8474 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008475 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008476 VOS_ASSERT(0);
8477 return status;
8478 }
8479 }
8480 }
8481
8482 if((TRUE == disableBmps) ||
8483 (TRUE == disableImps))
8484 {
8485 /* Now, get the chip into Full Power now */
8486 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
8487 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
8488 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
8489
8490 if(halStatus != eHAL_STATUS_SUCCESS)
8491 {
8492 if(halStatus == eHAL_STATUS_PMC_PENDING)
8493 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308494 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008495 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308496 ret = wait_for_completion_interruptible_timeout(
8497 &pHddCtx->full_pwr_comp_var,
8498 msecs_to_jiffies(1000));
8499 if (ret <= 0)
8500 {
8501 hddLog(VOS_TRACE_LEVEL_ERROR,
8502 "%s: wait on full_pwr_comp_var failed %ld",
8503 __func__, ret);
8504 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008505 }
8506 else
8507 {
8508 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008509 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008510 VOS_ASSERT(0);
8511 return status;
8512 }
8513 }
8514
8515 status = VOS_STATUS_SUCCESS;
8516 }
8517
8518 break;
8519 }
8520 return status;
8521}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308522
8523void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
8524{
8525 if (magic == NULL || cmpVar == NULL) {
8526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8527 FL("invalid arguments %p %p"), magic, cmpVar);
8528 return;
8529 }
8530 if (*magic != MON_MODE_MSG_MAGIC) {
8531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8532 FL("maic: %x"), *magic);
8533 return;
8534 }
8535
8536 complete(cmpVar);
8537 return;
8538}
8539
Katya Nigame7b69a82015-04-28 15:24:06 +05308540void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
8541 {
8542 hdd_mon_ctx_t *pMonCtx = NULL;
8543 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8544
8545 pMonCtx->state = 0;
8546 pMonCtx->ChannelNo = 1;
8547 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05308548 pMonCtx->crcCheckEnabled = 1;
8549 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
8550 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05308551 pMonCtx->numOfMacFilters = 0;
8552 }
8553
Jeff Johnson295189b2012-06-20 16:38:30 -07008554
8555hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008556 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07008557 tANI_U8 rtnl_held )
8558{
8559 hdd_adapter_t *pAdapter = NULL;
8560 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
8561 VOS_STATUS status = VOS_STATUS_E_FAILURE;
8562 VOS_STATUS exitbmpsStatus;
8563
Arif Hussain6d2a3322013-11-17 19:50:10 -08008564 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008565
Nirav Shah436658f2014-02-28 17:05:45 +05308566 if(macAddr == NULL)
8567 {
8568 /* Not received valid macAddr */
8569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8570 "%s:Unable to add virtual intf: Not able to get"
8571 "valid mac address",__func__);
8572 return NULL;
8573 }
8574
Jeff Johnson295189b2012-06-20 16:38:30 -07008575 //Disable BMPS incase of Concurrency
8576 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
8577
8578 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
8579 {
8580 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308581 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 VOS_ASSERT(0);
8583 return NULL;
8584 }
8585
8586 switch(session_type)
8587 {
8588 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008589 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008590 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 {
8592 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8593
8594 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308595 {
8596 hddLog(VOS_TRACE_LEVEL_FATAL,
8597 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008598 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308599 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008600
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308601#ifdef FEATURE_WLAN_TDLS
8602 /* A Mutex Lock is introduced while changing/initializing the mode to
8603 * protect the concurrent access for the Adapters by TDLS module.
8604 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308605 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308606#endif
8607
Jeff Johnsone7245742012-09-05 17:12:55 -07008608 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
8609 NL80211_IFTYPE_P2P_CLIENT:
8610 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07008611
Jeff Johnson295189b2012-06-20 16:38:30 -07008612 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308613#ifdef FEATURE_WLAN_TDLS
8614 mutex_unlock(&pHddCtx->tdls_lock);
8615#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308616
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308617 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05308618 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008619 if( VOS_STATUS_SUCCESS != status )
8620 goto err_free_netdev;
8621
8622 status = hdd_register_interface( pAdapter, rtnl_held );
8623 if( VOS_STATUS_SUCCESS != status )
8624 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308625#ifdef FEATURE_WLAN_TDLS
8626 mutex_lock(&pHddCtx->tdls_lock);
8627#endif
c_hpothu002231a2015-02-05 14:58:51 +05308628 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308629#ifdef FEATURE_WLAN_TDLS
8630 mutex_unlock(&pHddCtx->tdls_lock);
8631#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008632 goto err_free_netdev;
8633 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308634
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308635 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308636 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308637
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308638#ifdef WLAN_NS_OFFLOAD
8639 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308640 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308641#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008642 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308643 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008644 netif_tx_disable(pAdapter->dev);
8645 //netif_tx_disable(pWlanDev);
8646 netif_carrier_off(pAdapter->dev);
8647
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308648 if (WLAN_HDD_P2P_CLIENT == session_type ||
8649 WLAN_HDD_P2P_DEVICE == session_type)
8650 {
8651 /* Initialize the work queue to defer the
8652 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308653 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308654 hdd_p2p_roc_work_queue);
8655 }
8656
Jeff Johnson295189b2012-06-20 16:38:30 -07008657 break;
8658 }
8659
Jeff Johnson295189b2012-06-20 16:38:30 -07008660 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008661 case WLAN_HDD_SOFTAP:
8662 {
8663 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
8664 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308665 {
8666 hddLog(VOS_TRACE_LEVEL_FATAL,
8667 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008668 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008670
Jeff Johnson295189b2012-06-20 16:38:30 -07008671 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
8672 NL80211_IFTYPE_AP:
8673 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008674 pAdapter->device_mode = session_type;
8675
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308676 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 status = hdd_init_ap_mode(pAdapter);
8678 if( VOS_STATUS_SUCCESS != status )
8679 goto err_free_netdev;
8680
Nirav Shah7e3c8132015-06-22 23:51:42 +05308681 status = hdd_sta_id_hash_attach(pAdapter);
8682 if (VOS_STATUS_SUCCESS != status)
8683 {
8684 hddLog(VOS_TRACE_LEVEL_FATAL,
8685 FL("failed to attach hash for session %d"), session_type);
8686 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
8687 goto err_free_netdev;
8688 }
8689
Jeff Johnson295189b2012-06-20 16:38:30 -07008690 status = hdd_register_hostapd( pAdapter, rtnl_held );
8691 if( VOS_STATUS_SUCCESS != status )
8692 {
c_hpothu002231a2015-02-05 14:58:51 +05308693 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008694 goto err_free_netdev;
8695 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308696 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008697 netif_tx_disable(pAdapter->dev);
8698 netif_carrier_off(pAdapter->dev);
8699
8700 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308701
8702 if (WLAN_HDD_P2P_GO == session_type)
8703 {
8704 /* Initialize the work queue to
8705 * defer the back to back RoC request */
8706 INIT_DELAYED_WORK(&pAdapter->roc_work,
8707 hdd_p2p_roc_work_queue);
8708 }
Bhargav Shahd0715912015-10-01 18:17:37 +05308709
Jeff Johnson295189b2012-06-20 16:38:30 -07008710 break;
8711 }
8712 case WLAN_HDD_MONITOR:
8713 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8715 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308716 {
8717 hddLog(VOS_TRACE_LEVEL_FATAL,
8718 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008719 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308720 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008721
Katya Nigame7b69a82015-04-28 15:24:06 +05308722 // Register wireless extensions
8723 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
8724 {
8725 hddLog(VOS_TRACE_LEVEL_FATAL,
8726 "hdd_register_wext() failed with status code %08d [x%08x]",
8727 status, status );
8728 status = VOS_STATUS_E_FAILURE;
8729 }
8730
Jeff Johnson295189b2012-06-20 16:38:30 -07008731 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
8732 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008733#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
8734 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
8735#else
8736 pAdapter->dev->open = hdd_mon_open;
8737 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05308738 pAdapter->dev->stop = hdd_mon_stop;
8739 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008740#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05308741 status = hdd_register_interface( pAdapter, rtnl_held );
8742 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308743 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008744 hdd_init_tx_rx( pAdapter );
8745 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05308746 //Stop the Interface TX queue.
8747 netif_tx_disable(pAdapter->dev);
8748 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008749 }
8750 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 case WLAN_HDD_FTM:
8752 {
8753 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8754
8755 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308756 {
8757 hddLog(VOS_TRACE_LEVEL_FATAL,
8758 FL("failed to allocate adapter for session %d"), session_type);
8759 return NULL;
8760 }
8761
Jeff Johnson295189b2012-06-20 16:38:30 -07008762 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
8763 * message while loading driver in FTM mode. */
8764 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
8765 pAdapter->device_mode = session_type;
8766 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308767
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308768 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308769 hdd_init_tx_rx( pAdapter );
8770
8771 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308773 netif_tx_disable(pAdapter->dev);
8774 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 }
8776 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008777 default:
8778 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308779 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
8780 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008781 VOS_ASSERT(0);
8782 return NULL;
8783 }
8784 }
8785
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 if( VOS_STATUS_SUCCESS == status )
8787 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308788 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
8790 if( NULL == pHddAdapterNode )
8791 {
8792 status = VOS_STATUS_E_NOMEM;
8793 }
8794 else
8795 {
8796 pHddAdapterNode->pAdapter = pAdapter;
8797 status = hdd_add_adapter_back ( pHddCtx,
8798 pHddAdapterNode );
8799 }
8800 }
8801
8802 if( VOS_STATUS_SUCCESS != status )
8803 {
8804 if( NULL != pAdapter )
8805 {
8806 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
8807 pAdapter = NULL;
8808 }
8809 if( NULL != pHddAdapterNode )
8810 {
8811 vos_mem_free( pHddAdapterNode );
8812 }
8813
8814 goto resume_bmps;
8815 }
8816
8817 if(VOS_STATUS_SUCCESS == status)
8818 {
8819 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
8820
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07008821 //Initialize the WoWL service
8822 if(!hdd_init_wowl(pAdapter))
8823 {
8824 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
8825 goto err_free_netdev;
8826 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 return pAdapter;
8829
8830err_free_netdev:
8831 free_netdev(pAdapter->dev);
8832 wlan_hdd_release_intf_addr( pHddCtx,
8833 pAdapter->macAddressCurrent.bytes );
8834
8835resume_bmps:
8836 //If bmps disabled enable it
8837 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
8838 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308839 if (pHddCtx->hdd_wlan_suspended)
8840 {
8841 hdd_set_pwrparams(pHddCtx);
8842 }
8843 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008844 }
8845 return NULL;
8846}
8847
8848VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8849 tANI_U8 rtnl_held )
8850{
8851 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
8852 VOS_STATUS status;
8853
8854 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
8855 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308856 {
8857 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
8858 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008859 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308860 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008861
8862 while ( pCurrent->pAdapter != pAdapter )
8863 {
8864 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
8865 if( VOS_STATUS_SUCCESS != status )
8866 break;
8867
8868 pCurrent = pNext;
8869 }
8870 pAdapterNode = pCurrent;
8871 if( VOS_STATUS_SUCCESS == status )
8872 {
8873 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8874 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308875
8876#ifdef FEATURE_WLAN_TDLS
8877
8878 /* A Mutex Lock is introduced while changing/initializing the mode to
8879 * protect the concurrent access for the Adapters by TDLS module.
8880 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308881 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308882#endif
8883
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 hdd_remove_adapter( pHddCtx, pAdapterNode );
8885 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008886 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008887
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308888#ifdef FEATURE_WLAN_TDLS
8889 mutex_unlock(&pHddCtx->tdls_lock);
8890#endif
8891
Jeff Johnson295189b2012-06-20 16:38:30 -07008892
8893 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05308894 if ((!vos_concurrent_open_sessions_running()) &&
8895 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
8896 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008897 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308898 if (pHddCtx->hdd_wlan_suspended)
8899 {
8900 hdd_set_pwrparams(pHddCtx);
8901 }
8902 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 }
8904
8905 return VOS_STATUS_SUCCESS;
8906 }
8907
8908 return VOS_STATUS_E_FAILURE;
8909}
8910
8911VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
8912{
8913 hdd_adapter_list_node_t *pHddAdapterNode;
8914 VOS_STATUS status;
8915
8916 ENTER();
8917
8918 do
8919 {
8920 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
8921 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
8922 {
8923 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
8924 vos_mem_free( pHddAdapterNode );
8925 }
8926 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
8927
8928 EXIT();
8929
8930 return VOS_STATUS_SUCCESS;
8931}
8932
8933void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
8934{
8935 v_U8_t addIE[1] = {0};
8936
8937 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8938 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
8939 eANI_BOOLEAN_FALSE) )
8940 {
8941 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008942 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008943 }
8944
8945 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8946 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8947 eANI_BOOLEAN_FALSE) )
8948 {
8949 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008950 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008951 }
8952
8953 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8954 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8955 eANI_BOOLEAN_FALSE) )
8956 {
8957 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008958 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008959 }
8960}
8961
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308962VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8963 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07008964{
8965 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8966 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308967 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008968 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308969 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308970 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05308971 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008972
Anand N Sunkad26d71b92014-12-24 18:08:22 +05308973 if (pHddCtx->isLogpInProgress) {
8974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8975 "%s:LOGP in Progress. Ignore!!!",__func__);
8976 return VOS_STATUS_E_FAILURE;
8977 }
8978
Jeff Johnson295189b2012-06-20 16:38:30 -07008979 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308980
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308981 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 switch(pAdapter->device_mode)
8983 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05308984 case WLAN_HDD_IBSS:
8985 if ( VOS_TRUE == bCloseSession )
8986 {
8987 status = hdd_sta_id_hash_detach(pAdapter);
8988 if (status != VOS_STATUS_SUCCESS)
8989 hddLog(VOS_TRACE_LEVEL_ERROR,
8990 FL("sta id hash detach failed"));
8991 }
8992
Jeff Johnson295189b2012-06-20 16:38:30 -07008993 case WLAN_HDD_INFRA_STATION:
8994 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008995 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308996 {
8997 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05308998#ifdef FEATURE_WLAN_TDLS
8999 mutex_lock(&pHddCtx->tdls_lock);
9000 wlan_hdd_tdls_exit(pAdapter, TRUE);
9001 mutex_unlock(&pHddCtx->tdls_lock);
9002#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309003 if( hdd_connIsConnected(pstation) ||
9004 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 {
9006 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
9007 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9008 pAdapter->sessionId,
9009 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
9010 else
9011 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9012 pAdapter->sessionId,
9013 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309014 /* Success implies disconnect command got queued up successfully
9015 * Or cmd not queued as scan for SSID is in progress
9016 */
9017 if((eHAL_STATUS_SUCCESS == halStatus) ||
9018 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07009019 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309020 ret = wait_for_completion_interruptible_timeout(
9021 &pAdapter->disconnect_comp_var,
9022 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309023 if (ret <= 0 &&
9024 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309025 {
9026 hddLog(VOS_TRACE_LEVEL_ERROR,
9027 "%s: wait on disconnect_comp_var failed %ld",
9028 __func__, ret);
9029 }
9030 }
9031 else
9032 {
9033 hddLog(LOGE, "%s: failed to post disconnect event to SME",
9034 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 }
9036 memset(&wrqu, '\0', sizeof(wrqu));
9037 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9038 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9039 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
9040 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309041 else if(pstation->conn_info.connState ==
9042 eConnectionState_Disconnecting)
9043 {
9044 ret = wait_for_completion_interruptible_timeout(
9045 &pAdapter->disconnect_comp_var,
9046 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9047 if (ret <= 0)
9048 {
9049 hddLog(VOS_TRACE_LEVEL_ERROR,
9050 FL("wait on disconnect_comp_var failed %ld"), ret);
9051 }
9052 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309053 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07009054 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05309055 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009056 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05309057 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
9058 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309059 {
9060 while (pAdapter->is_roc_inprogress)
9061 {
9062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9063 "%s: ROC in progress for session %d!!!",
9064 __func__, pAdapter->sessionId);
9065 // waiting for ROC to expire
9066 msleep(500);
9067 /* In GO present case , if retry exceeds 3,
9068 it means something went wrong. */
9069 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
9070 {
9071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9072 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05309073 if (eHAL_STATUS_SUCCESS !=
9074 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
9075 pAdapter->sessionId ))
9076 {
9077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9078 FL("Failed to Cancel Remain on Channel"));
9079 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309080 wait_for_completion_interruptible_timeout(
9081 &pAdapter->cancel_rem_on_chan_var,
9082 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9083 break;
9084 }
9085 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309086 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309087 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309088#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309089 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309090#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309091
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309092 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309093
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309094 /* It is possible that the caller of this function does not
9095 * wish to close the session
9096 */
9097 if (VOS_TRUE == bCloseSession &&
9098 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009099 {
9100 INIT_COMPLETION(pAdapter->session_close_comp_var);
9101 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309102 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
9103 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309105 unsigned long ret;
9106
Jeff Johnson295189b2012-06-20 16:38:30 -07009107 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309108 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309109 &pAdapter->session_close_comp_var,
9110 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309111 if ( 0 >= ret)
9112 {
9113 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309114 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309115 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 }
9117 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009119 break;
9120
9121 case WLAN_HDD_SOFTAP:
9122 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05309123 if ( VOS_TRUE == bCloseSession )
9124 {
9125 status = hdd_sta_id_hash_detach(pAdapter);
9126 if (status != VOS_STATUS_SUCCESS)
9127 hddLog(VOS_TRACE_LEVEL_ERROR,
9128 FL("sta id hash detach failed"));
9129 }
9130
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309132 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
9133 while (pAdapter->is_roc_inprogress) {
9134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9135 "%s: ROC in progress for session %d!!!",
9136 __func__, pAdapter->sessionId);
9137 msleep(500);
9138 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
9139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9140 "%s: ROC completion is not received.!!!", __func__);
9141 WLANSAP_CancelRemainOnChannel(
9142 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
9143 wait_for_completion_interruptible_timeout(
9144 &pAdapter->cancel_rem_on_chan_var,
9145 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9146 break;
9147 }
9148 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309149
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309150 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309151 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009152 mutex_lock(&pHddCtx->sap_lock);
9153 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9154 {
9155 VOS_STATUS status;
9156 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9157
9158 //Stop Bss.
9159 status = WLANSAP_StopBss(pHddCtx->pvosContext);
9160 if (VOS_IS_STATUS_SUCCESS(status))
9161 {
9162 hdd_hostapd_state_t *pHostapdState =
9163 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9164
9165 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9166
9167 if (!VOS_IS_STATUS_SUCCESS(status))
9168 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309169 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
9170 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 }
9172 }
9173 else
9174 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009175 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009176 }
9177 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309178 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009179
9180 if (eHAL_STATUS_FAILURE ==
9181 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
9182 0, NULL, eANI_BOOLEAN_FALSE))
9183 {
9184 hddLog(LOGE,
9185 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009186 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009187 }
9188
9189 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
9190 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9191 eANI_BOOLEAN_FALSE) )
9192 {
9193 hddLog(LOGE,
9194 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
9195 }
9196
9197 // Reset WNI_CFG_PROBE_RSP Flags
9198 wlan_hdd_reset_prob_rspies(pAdapter);
9199 kfree(pAdapter->sessionCtx.ap.beacon);
9200 pAdapter->sessionCtx.ap.beacon = NULL;
9201 }
9202 mutex_unlock(&pHddCtx->sap_lock);
9203 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009204
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 case WLAN_HDD_MONITOR:
9206 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009207
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 default:
9209 break;
9210 }
9211
9212 EXIT();
9213 return VOS_STATUS_SUCCESS;
9214}
9215
9216VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
9217{
9218 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9219 VOS_STATUS status;
9220 hdd_adapter_t *pAdapter;
9221
9222 ENTER();
9223
9224 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9225
9226 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9227 {
9228 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009229
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309230 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009231
9232 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9233 pAdapterNode = pNext;
9234 }
9235
9236 EXIT();
9237
9238 return VOS_STATUS_SUCCESS;
9239}
9240
Rajeev Kumarf999e582014-01-09 17:33:29 -08009241
9242#ifdef FEATURE_WLAN_BATCH_SCAN
9243/**---------------------------------------------------------------------------
9244
9245 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
9246 structures
9247
9248 \param - pAdapter Pointer to HDD adapter
9249
9250 \return - None
9251
9252 --------------------------------------------------------------------------*/
9253void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
9254{
9255 tHddBatchScanRsp *pNode;
9256 tHddBatchScanRsp *pPrev;
9257
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309258 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009259 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309260 hddLog(VOS_TRACE_LEVEL_ERROR,
9261 "%s: Adapter context is Null", __func__);
9262 return;
9263 }
9264
9265 pNode = pAdapter->pBatchScanRsp;
9266 while (pNode)
9267 {
9268 pPrev = pNode;
9269 pNode = pNode->pNext;
9270 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08009271 }
9272
9273 pAdapter->pBatchScanRsp = NULL;
9274 pAdapter->numScanList = 0;
9275 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
9276 pAdapter->prev_batch_id = 0;
9277
9278 return;
9279}
9280#endif
9281
9282
Jeff Johnson295189b2012-06-20 16:38:30 -07009283VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
9284{
9285 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9286 VOS_STATUS status;
9287 hdd_adapter_t *pAdapter;
9288
9289 ENTER();
9290
9291 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9292
9293 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9294 {
9295 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309296 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009297 netif_tx_disable(pAdapter->dev);
9298 netif_carrier_off(pAdapter->dev);
9299
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009300 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
9301
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309303
Katya Nigam1fd24402015-02-16 14:52:19 +05309304 if(pAdapter->device_mode == WLAN_HDD_IBSS )
9305 hdd_ibss_deinit_tx_rx(pAdapter);
9306
Nirav Shah7e3c8132015-06-22 23:51:42 +05309307 status = hdd_sta_id_hash_detach(pAdapter);
9308 if (status != VOS_STATUS_SUCCESS)
9309 hddLog(VOS_TRACE_LEVEL_ERROR,
9310 FL("sta id hash detach failed for session id %d"),
9311 pAdapter->sessionId);
9312
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309313 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9314
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309315 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9316 {
9317 hdd_wmm_adapter_close( pAdapter );
9318 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9319 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009320
Siddharth Bhal2db319d2014-12-03 12:37:18 +05309321 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9322 {
9323 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
9324 }
9325
Rajeev Kumarf999e582014-01-09 17:33:29 -08009326#ifdef FEATURE_WLAN_BATCH_SCAN
9327 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9328 {
9329 hdd_deinit_batch_scan(pAdapter);
9330 }
9331#endif
9332
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309333#ifdef FEATURE_WLAN_TDLS
9334 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05309335 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309336 mutex_unlock(&pHddCtx->tdls_lock);
9337#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9339 pAdapterNode = pNext;
9340 }
9341
9342 EXIT();
9343
9344 return VOS_STATUS_SUCCESS;
9345}
9346
9347VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
9348{
9349 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9350 VOS_STATUS status;
9351 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309352 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009353
9354 ENTER();
9355
9356 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9357
9358 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9359 {
9360 pAdapter = pAdapterNode->pAdapter;
9361
Kumar Anand82c009f2014-05-29 00:29:42 -07009362 hdd_wmm_init( pAdapter );
9363
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 switch(pAdapter->device_mode)
9365 {
9366 case WLAN_HDD_INFRA_STATION:
9367 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009368 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309369
9370 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
9371
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 hdd_init_station_mode(pAdapter);
9373 /* Open the gates for HDD to receive Wext commands */
9374 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009375 pHddCtx->scan_info.mScanPending = FALSE;
9376 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009377
9378 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05309379 if (!pHddCtx->isLogpInProgress)
9380 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009381
9382 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309383 if (eConnectionState_Associated == connState ||
9384 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 {
9386 union iwreq_data wrqu;
9387 memset(&wrqu, '\0', sizeof(wrqu));
9388 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9389 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9390 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009391 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009392
Jeff Johnson295189b2012-06-20 16:38:30 -07009393 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +05309394 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +05309395 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309397 else if (eConnectionState_Connecting == connState)
9398 {
9399 /*
9400 * Indicate connect failure to supplicant if we were in the
9401 * process of connecting
9402 */
9403 cfg80211_connect_result(pAdapter->dev, NULL,
9404 NULL, 0, NULL, 0,
9405 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
9406 GFP_KERNEL);
9407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 break;
9409
9410 case WLAN_HDD_SOFTAP:
9411 /* softAP can handle SSR */
9412 break;
9413
9414 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009415 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009417 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 break;
9419
9420 case WLAN_HDD_MONITOR:
9421 /* monitor interface start */
9422 break;
9423 default:
9424 break;
9425 }
9426
9427 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9428 pAdapterNode = pNext;
9429 }
9430
9431 EXIT();
9432
9433 return VOS_STATUS_SUCCESS;
9434}
9435
9436VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
9437{
9438 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9439 hdd_adapter_t *pAdapter;
9440 VOS_STATUS status;
9441 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309442 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009443
9444 ENTER();
9445
9446 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9447
9448 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9449 {
9450 pAdapter = pAdapterNode->pAdapter;
9451
9452 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9453 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9454 {
9455 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9456 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9457
Abhishek Singhf4669da2014-05-26 15:07:49 +05309458 hddLog(VOS_TRACE_LEVEL_INFO,
9459 "%s: Set HDD connState to eConnectionState_NotConnected",
9460 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309461 spin_lock_bh(&pAdapter->lock_for_active_session);
9462 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
9463 {
9464 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9465 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309467 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 init_completion(&pAdapter->disconnect_comp_var);
9469 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
9470 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9471
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309472 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009473 &pAdapter->disconnect_comp_var,
9474 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309475 if (0 >= ret)
9476 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
9477 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07009478
9479 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
9480 pHddCtx->isAmpAllowed = VOS_FALSE;
9481 sme_RoamConnect(pHddCtx->hHal,
9482 pAdapter->sessionId, &(pWextState->roamProfile),
9483 &roamId);
9484 }
9485
9486 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9487 pAdapterNode = pNext;
9488 }
9489
9490 EXIT();
9491
9492 return VOS_STATUS_SUCCESS;
9493}
9494
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009495void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
9496{
9497 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9498 VOS_STATUS status;
9499 hdd_adapter_t *pAdapter;
9500 hdd_station_ctx_t *pHddStaCtx;
9501 hdd_ap_ctx_t *pHddApCtx;
9502 hdd_hostapd_state_t * pHostapdState;
9503 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
9504 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
9505 const char *p2pMode = "DEV";
9506 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009507
9508 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9509 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9510 {
9511 pAdapter = pAdapterNode->pAdapter;
9512 switch (pAdapter->device_mode) {
9513 case WLAN_HDD_INFRA_STATION:
9514 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9515 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9516 staChannel = pHddStaCtx->conn_info.operationChannel;
9517 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
9518 }
9519 break;
9520 case WLAN_HDD_P2P_CLIENT:
9521 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9522 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9523 p2pChannel = pHddStaCtx->conn_info.operationChannel;
9524 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
9525 p2pMode = "CLI";
9526 }
9527 break;
9528 case WLAN_HDD_P2P_GO:
9529 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9530 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9531 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9532 p2pChannel = pHddApCtx->operatingChannel;
9533 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
9534 }
9535 p2pMode = "GO";
9536 break;
9537 case WLAN_HDD_SOFTAP:
9538 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9539 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9540 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9541 apChannel = pHddApCtx->operatingChannel;
9542 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
9543 }
9544 break;
9545 default:
9546 break;
9547 }
9548 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9549 pAdapterNode = pNext;
9550 }
9551 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
9552 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
9553 }
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309554 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009555 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
9556 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309557 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009558 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
9559 }
9560 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309561 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009562 apChannel, MAC_ADDR_ARRAY(apBssid));
9563 }
9564
9565 if (p2pChannel > 0 && apChannel > 0) {
9566 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
9567 }
9568}
9569
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009570bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009571{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009572 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009573}
9574
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009575/* Once SSR is disabled then it cannot be set. */
9576void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07009577{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009578 if (HDD_SSR_DISABLED == isSsrRequired)
9579 return;
9580
Jeff Johnson295189b2012-06-20 16:38:30 -07009581 isSsrRequired = value;
9582}
9583
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05309584void hdd_set_pre_close( hdd_context_t *pHddCtx)
9585{
9586 sme_PreClose(pHddCtx->hHal);
9587}
9588
Jeff Johnson295189b2012-06-20 16:38:30 -07009589VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
9590 hdd_adapter_list_node_t** ppAdapterNode)
9591{
9592 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309593 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
9595 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309596 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 return status;
9598}
9599
9600VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
9601 hdd_adapter_list_node_t* pAdapterNode,
9602 hdd_adapter_list_node_t** pNextAdapterNode)
9603{
9604 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309605 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
9607 (hdd_list_node_t*) pAdapterNode,
9608 (hdd_list_node_t**)pNextAdapterNode );
9609
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309610 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009611 return status;
9612}
9613
9614VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
9615 hdd_adapter_list_node_t* pAdapterNode)
9616{
9617 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309618 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
9620 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309621 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 return status;
9623}
9624
9625VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
9626 hdd_adapter_list_node_t** ppAdapterNode)
9627{
9628 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309629 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009630 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
9631 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309632 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009633 return status;
9634}
9635
9636VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
9637 hdd_adapter_list_node_t* pAdapterNode)
9638{
9639 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309640 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
9642 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309643 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 return status;
9645}
9646
9647VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
9648 hdd_adapter_list_node_t* pAdapterNode)
9649{
9650 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309651 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009652 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
9653 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309654 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 return status;
9656}
9657
9658hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
9659 tSirMacAddr macAddr )
9660{
9661 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9662 hdd_adapter_t *pAdapter;
9663 VOS_STATUS status;
9664
9665 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9666
9667 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9668 {
9669 pAdapter = pAdapterNode->pAdapter;
9670
9671 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
9672 macAddr, sizeof(tSirMacAddr) ) )
9673 {
9674 return pAdapter;
9675 }
9676 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9677 pAdapterNode = pNext;
9678 }
9679
9680 return NULL;
9681
9682}
9683
9684hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
9685{
9686 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9687 hdd_adapter_t *pAdapter;
9688 VOS_STATUS status;
9689
9690 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9691
9692 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9693 {
9694 pAdapter = pAdapterNode->pAdapter;
9695
9696 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
9697 IFNAMSIZ ) )
9698 {
9699 return pAdapter;
9700 }
9701 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9702 pAdapterNode = pNext;
9703 }
9704
9705 return NULL;
9706
9707}
9708
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05309709hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
9710 tANI_U32 sme_session_id )
9711{
9712 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9713 hdd_adapter_t *pAdapter;
9714 VOS_STATUS vos_status;
9715
9716
9717 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
9718
9719 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
9720 {
9721 pAdapter = pAdapterNode->pAdapter;
9722
9723 if (pAdapter->sessionId == sme_session_id)
9724 return pAdapter;
9725
9726 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9727 pAdapterNode = pNext;
9728 }
9729
9730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9731 "%s: sme_session_id %d does not exist with host",
9732 __func__, sme_session_id);
9733
9734 return NULL;
9735}
9736
Jeff Johnson295189b2012-06-20 16:38:30 -07009737hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
9738{
9739 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9740 hdd_adapter_t *pAdapter;
9741 VOS_STATUS status;
9742
9743 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9744
9745 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9746 {
9747 pAdapter = pAdapterNode->pAdapter;
9748
9749 if( pAdapter && (mode == pAdapter->device_mode) )
9750 {
9751 return pAdapter;
9752 }
9753 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9754 pAdapterNode = pNext;
9755 }
9756
9757 return NULL;
9758
9759}
9760
9761//Remove this function later
9762hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
9763{
9764 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9765 hdd_adapter_t *pAdapter;
9766 VOS_STATUS status;
9767
9768 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9769
9770 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9771 {
9772 pAdapter = pAdapterNode->pAdapter;
9773
9774 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
9775 {
9776 return pAdapter;
9777 }
9778
9779 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9780 pAdapterNode = pNext;
9781 }
9782
9783 return NULL;
9784
9785}
9786
Jeff Johnson295189b2012-06-20 16:38:30 -07009787/**---------------------------------------------------------------------------
9788
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05309789 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009790
9791 This API returns the operating channel of the requested device mode
9792
9793 \param - pHddCtx - Pointer to the HDD context.
9794 - mode - Device mode for which operating channel is required
9795 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
9796 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
9797 \return - channel number. "0" id the requested device is not found OR it is not connected.
9798 --------------------------------------------------------------------------*/
9799v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
9800{
9801 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9802 VOS_STATUS status;
9803 hdd_adapter_t *pAdapter;
9804 v_U8_t operatingChannel = 0;
9805
9806 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9807
9808 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9809 {
9810 pAdapter = pAdapterNode->pAdapter;
9811
9812 if( mode == pAdapter->device_mode )
9813 {
9814 switch(pAdapter->device_mode)
9815 {
9816 case WLAN_HDD_INFRA_STATION:
9817 case WLAN_HDD_P2P_CLIENT:
9818 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
9819 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
9820 break;
9821 case WLAN_HDD_SOFTAP:
9822 case WLAN_HDD_P2P_GO:
9823 /*softap connection info */
9824 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9825 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
9826 break;
9827 default:
9828 break;
9829 }
9830
9831 break; //Found the device of interest. break the loop
9832 }
9833
9834 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9835 pAdapterNode = pNext;
9836 }
9837 return operatingChannel;
9838}
9839
9840#ifdef WLAN_FEATURE_PACKET_FILTERING
9841/**---------------------------------------------------------------------------
9842
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309843 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009844
9845 This used to set the multicast address list.
9846
9847 \param - dev - Pointer to the WLAN device.
9848 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309849 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07009850
9851 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309852static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07009853{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309854 hdd_adapter_t *pAdapter;
9855 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009856 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309857 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309859
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309860 ENTER();
9861
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309862 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309863 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009864 {
9865 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309866 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009867 return;
9868 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309869 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9870 ret = wlan_hdd_validate_context(pHddCtx);
9871 if (0 != ret)
9872 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309873 return;
9874 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 if (dev->flags & IFF_ALLMULTI)
9876 {
9877 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009878 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309879 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309881 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009882 {
9883 mc_count = netdev_mc_count(dev);
9884 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009885 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07009886 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
9887 {
9888 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009889 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309890 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 return;
9892 }
9893
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309894 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07009895
9896 netdev_for_each_mc_addr(ha, dev) {
9897 if (i == mc_count)
9898 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309899 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
9900 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08009901 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309902 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309903 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07009904 i++;
9905 }
9906 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309907
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05309908 if (pHddCtx->hdd_wlan_suspended)
9909 {
9910 /*
9911 * Configure the Mcast address list to FW
9912 * If wlan is already in suspend mode
9913 */
9914 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
9915 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309916 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 return;
9918}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309919
9920static void hdd_set_multicast_list(struct net_device *dev)
9921{
9922 vos_ssr_protect(__func__);
9923 __hdd_set_multicast_list(dev);
9924 vos_ssr_unprotect(__func__);
9925}
Jeff Johnson295189b2012-06-20 16:38:30 -07009926#endif
9927
9928/**---------------------------------------------------------------------------
9929
9930 \brief hdd_select_queue() -
9931
9932 This function is registered with the Linux OS for network
9933 core to decide which queue to use first.
9934
9935 \param - dev - Pointer to the WLAN device.
9936 - skb - Pointer to OS packet (sk_buff).
9937 \return - ac, Queue Index/access category corresponding to UP in IP header
9938
9939 --------------------------------------------------------------------------*/
9940v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309941 struct sk_buff *skb
9942#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
9943 , void *accel_priv
9944#endif
9945#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9946 , select_queue_fallback_t fallback
9947#endif
9948)
Jeff Johnson295189b2012-06-20 16:38:30 -07009949{
9950 return hdd_wmm_select_queue(dev, skb);
9951}
9952
9953
9954/**---------------------------------------------------------------------------
9955
9956 \brief hdd_wlan_initial_scan() -
9957
9958 This function triggers the initial scan
9959
9960 \param - pAdapter - Pointer to the HDD adapter.
9961
9962 --------------------------------------------------------------------------*/
9963void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
9964{
9965 tCsrScanRequest scanReq;
9966 tCsrChannelInfo channelInfo;
9967 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07009968 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9970
9971 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
9972 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
9973 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
9974
9975 if(sme_Is11dSupported(pHddCtx->hHal))
9976 {
9977 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
9978 if ( HAL_STATUS_SUCCESS( halStatus ) )
9979 {
9980 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
9981 if( !scanReq.ChannelInfo.ChannelList )
9982 {
9983 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
9984 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009985 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009986 return;
9987 }
9988 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
9989 channelInfo.numOfChannels);
9990 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
9991 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009992 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009993 }
9994
9995 scanReq.scanType = eSIR_PASSIVE_SCAN;
9996 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
9997 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
9998 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
9999 }
10000 else
10001 {
10002 scanReq.scanType = eSIR_ACTIVE_SCAN;
10003 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10004 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
10005 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
10006 }
10007
10008 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
10009 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10010 {
10011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
10012 __func__, halStatus );
10013 }
10014
10015 if(sme_Is11dSupported(pHddCtx->hHal))
10016 vos_mem_free(scanReq.ChannelInfo.ChannelList);
10017}
10018
Jeff Johnson295189b2012-06-20 16:38:30 -070010019/**---------------------------------------------------------------------------
10020
10021 \brief hdd_full_power_callback() - HDD full power callback function
10022
10023 This is the function invoked by SME to inform the result of a full power
10024 request issued by HDD
10025
10026 \param - callbackcontext - Pointer to cookie
10027 \param - status - result of request
10028
10029 \return - None
10030
10031 --------------------------------------------------------------------------*/
10032static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
10033{
Jeff Johnson72a40512013-12-19 10:14:15 -080010034 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010035
10036 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010037 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010038
10039 if (NULL == callbackContext)
10040 {
10041 hddLog(VOS_TRACE_LEVEL_ERROR,
10042 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010043 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 return;
10045 }
10046
Jeff Johnson72a40512013-12-19 10:14:15 -080010047 /* there is a race condition that exists between this callback
10048 function and the caller since the caller could time out either
10049 before or while this code is executing. we use a spinlock to
10050 serialize these actions */
10051 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010052
10053 if (POWER_CONTEXT_MAGIC != pContext->magic)
10054 {
10055 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080010056 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 hddLog(VOS_TRACE_LEVEL_WARN,
10058 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010059 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070010060 return;
10061 }
10062
Jeff Johnson72a40512013-12-19 10:14:15 -080010063 /* context is valid so caller is still waiting */
10064
10065 /* paranoia: invalidate the magic */
10066 pContext->magic = 0;
10067
10068 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080010070
10071 /* serialization is complete */
10072 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010073}
10074
Katya Nigamf0511f62015-05-05 16:40:57 +053010075void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
10076{
10077 pMonCtx->typeSubtypeBitmap = 0;
10078 if( type%10 ) /* Management Packets */
10079 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
10080 type/=10;
10081 if( type%10 ) /* Control Packets */
10082 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
10083 type/=10;
10084 if( type%10 ) /* Data Packets */
10085 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
10086}
10087
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010088VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
10089 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053010090{
10091 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010092 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010093
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010094 if (MON_MODE_START == pMonCtx->state)
10095 monMsg.type = WDA_MON_START_REQ;
10096 else if (MON_MODE_STOP == pMonCtx->state)
10097 monMsg.type = WDA_MON_STOP_REQ;
10098 else {
10099 hddLog(VOS_TRACE_LEVEL_ERROR,
10100 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053010101 return VOS_STATUS_E_FAILURE;
10102 }
10103
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010104 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
10105 if (pMonModeReq == NULL) {
10106 hddLog(VOS_TRACE_LEVEL_ERROR,
10107 FL("fail to allocate memory for monitor mode req"));
10108 return VOS_STATUS_E_FAILURE;
10109 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010110
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010111 pMonModeReq->magic = magic;
10112 pMonModeReq->cmpVar = cmpVar;
10113 pMonModeReq->data = pMonCtx;
10114 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053010115
Katya Nigamf0511f62015-05-05 16:40:57 +053010116 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010117 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010118 monMsg.bodyval = 0;
10119
10120 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
10121 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
10122 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010123 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053010124 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010125 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053010126}
10127
Katya Nigame7b69a82015-04-28 15:24:06 +053010128void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
10129{
10130 VOS_STATUS vosStatus;
10131 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010132 long ret;
10133 hdd_mon_ctx_t *pMonCtx = NULL;
10134 v_U32_t magic;
10135 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010136
Katya Nigame7b69a82015-04-28 15:24:06 +053010137 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
10138 if(pAdapter == NULL || pVosContext == NULL)
10139 {
10140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
10141 return ;
10142 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010143
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010144 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
10145 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
10146 pMonCtx->state = MON_MODE_STOP;
10147 magic = MON_MODE_MSG_MAGIC;
10148 init_completion(&cmpVar);
10149 if (VOS_STATUS_SUCCESS !=
10150 wlan_hdd_mon_postMsg(&magic, &cmpVar,
10151 pMonCtx, hdd_monPostMsgCb)) {
10152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10153 FL("failed to post MON MODE REQ"));
10154 pMonCtx->state = MON_MODE_START;
10155 magic = 0;
10156 return;
10157 }
10158 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
10159 magic = 0;
10160 if (ret <= 0 ) {
10161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10162 FL("timeout on monitor mode completion %ld"), ret);
10163 }
10164 }
10165
Katya Nigame7b69a82015-04-28 15:24:06 +053010166 hdd_UnregisterWext(pAdapter->dev);
10167
10168 vos_mon_stop( pVosContext );
10169
10170 vosStatus = vos_sched_close( pVosContext );
10171 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10172 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10173 "%s: Failed to close VOSS Scheduler",__func__);
10174 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10175 }
10176
10177 vosStatus = vos_nv_close();
10178 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10179 {
10180 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10181 "%s: Failed to close NV", __func__);
10182 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10183 }
10184
10185 vos_close(pVosContext);
10186
10187 #ifdef WLAN_KD_READY_NOTIFIER
10188 nl_srv_exit(pHddCtx->ptt_pid);
10189 #else
10190 nl_srv_exit();
10191 #endif
10192
Katya Nigame7b69a82015-04-28 15:24:06 +053010193 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053010194}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010195/**
10196 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
10197 * @ wiphy: the wiphy to validate against
10198 *
10199 * Return: void
10200 */
10201void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
10202{
10203 int i =0;
10204 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
10205 {
10206 if (NULL != wiphy->bands[i] &&
10207 (NULL != wiphy->bands[i]->channels))
10208 {
10209 vos_mem_free(wiphy->bands[i]->channels);
10210 wiphy->bands[i]->channels = NULL;
10211 }
10212 }
10213}
Jeff Johnson295189b2012-06-20 16:38:30 -070010214/**---------------------------------------------------------------------------
10215
10216 \brief hdd_wlan_exit() - HDD WLAN exit function
10217
10218 This is the driver exit point (invoked during rmmod)
10219
10220 \param - pHddCtx - Pointer to the HDD Context
10221
10222 \return - None
10223
10224 --------------------------------------------------------------------------*/
10225void hdd_wlan_exit(hdd_context_t *pHddCtx)
10226{
10227 eHalStatus halStatus;
10228 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
10229 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053010230 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010231 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080010232 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053010234 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010235
10236 ENTER();
10237
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010238
Katya Nigame7b69a82015-04-28 15:24:06 +053010239 if (VOS_MONITOR_MODE == hdd_get_conparam())
10240 {
10241 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
10242 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010243 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053010244 }
10245 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080010246 {
10247 // Unloading, restart logic is no more required.
10248 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070010249
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010250#ifdef FEATURE_WLAN_TDLS
10251 /* At the time of driver unloading; if tdls connection is present;
10252 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
10253 * wlan_hdd_tdls_find_peer always checks for valid context;
10254 * as load/unload in progress there can be a race condition.
10255 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
10256 * when tdls state is enabled.
10257 * As soon as driver set load/unload flag; tdls flag also needs
10258 * to be disabled so that hdd_rx_packet_cbk won't call
10259 * wlan_hdd_tdls_find_peer.
10260 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053010261 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
10262 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010263#endif
10264
c_hpothu5ab05e92014-06-13 17:34:05 +053010265 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10266 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 {
c_hpothu5ab05e92014-06-13 17:34:05 +053010268 pAdapter = pAdapterNode->pAdapter;
10269 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010271 /* Disable TX on the interface, after this hard_start_xmit() will
10272 * not be called on that interface
10273 */
10274 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10275 netif_tx_disable(pAdapter->dev);
10276
10277 /* Mark the interface status as "down" for outside world */
10278 netif_carrier_off(pAdapter->dev);
10279
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010280 /* DeInit the adapter. This ensures that all data packets
10281 * are freed.
10282 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010283#ifdef FEATURE_WLAN_TDLS
10284 mutex_lock(&pHddCtx->tdls_lock);
10285#endif
c_hpothu002231a2015-02-05 14:58:51 +053010286 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010287#ifdef FEATURE_WLAN_TDLS
10288 mutex_unlock(&pHddCtx->tdls_lock);
10289#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053010290 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
10291
10292 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010293
c_hpothu5ab05e92014-06-13 17:34:05 +053010294 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10295 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
10296 {
10297 wlan_hdd_cfg80211_deregister_frames(pAdapter);
10298 hdd_UnregisterWext(pAdapter->dev);
10299 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010300
Jeff Johnson295189b2012-06-20 16:38:30 -070010301 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010302 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10303 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 }
mukul sharmabab477d2015-06-11 17:14:55 +053010305
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010306 // Cancel any outstanding scan requests. We are about to close all
10307 // of our adapters, but an adapter structure is what SME passes back
10308 // to our callback function. Hence if there are any outstanding scan
10309 // requests then there is a race condition between when the adapter
10310 // is closed and when the callback is invoked.We try to resolve that
10311 // race condition here by canceling any outstanding scans before we
10312 // close the adapters.
10313 // Note that the scans may be cancelled in an asynchronous manner,
10314 // so ideally there needs to be some kind of synchronization. Rather
10315 // than introduce a new synchronization here, we will utilize the
10316 // fact that we are about to Request Full Power, and since that is
10317 // synchronized, the expectation is that by the time Request Full
10318 // Power has completed all scans will be cancelled.
10319 if (pHddCtx->scan_info.mScanPending)
10320 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053010321 if(NULL != pAdapter)
10322 {
10323 hddLog(VOS_TRACE_LEVEL_INFO,
10324 FL("abort scan mode: %d sessionId: %d"),
10325 pAdapter->device_mode,
10326 pAdapter->sessionId);
10327 }
10328 hdd_abort_mac_scan(pHddCtx,
10329 pHddCtx->scan_info.sessionId,
10330 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010331 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010332 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010333 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080010334 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010335 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053010336 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
10337 {
10338 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
10339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10340 "%s: in middle of FTM START", __func__);
10341 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
10342 msecs_to_jiffies(20000));
10343 if(!lrc)
10344 {
10345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10346 "%s: timedout on ftmStartCmpVar fatal error", __func__);
10347 }
10348 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080010349 wlan_hdd_ftm_close(pHddCtx);
10350 goto free_hdd_ctx;
10351 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010352
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 /* DeRegister with platform driver as client for Suspend/Resume */
10354 vosStatus = hddDeregisterPmOps(pHddCtx);
10355 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10356 {
10357 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
10358 VOS_ASSERT(0);
10359 }
10360
10361 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
10362 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10363 {
10364 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
10365 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010366
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010367 //Stop the traffic monitor timer
10368 if ( VOS_TIMER_STATE_RUNNING ==
10369 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
10370 {
10371 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
10372 }
10373
10374 // Destroy the traffic monitor timer
10375 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10376 &pHddCtx->tx_rx_trafficTmr)))
10377 {
10378 hddLog(VOS_TRACE_LEVEL_ERROR,
10379 "%s: Cannot deallocate Traffic monitor timer", __func__);
10380 }
10381
Bhargav Shahd0715912015-10-01 18:17:37 +053010382 if (VOS_TIMER_STATE_RUNNING ==
10383 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
10384 vos_timer_stop(&pHddCtx->delack_timer);
10385 }
10386
10387 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10388 &pHddCtx->delack_timer))) {
10389 hddLog(VOS_TRACE_LEVEL_ERROR,
10390 "%s: Cannot deallocate Bus bandwidth timer", __func__);
10391 }
10392
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053010393 if (VOS_TIMER_STATE_RUNNING ==
10394 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
10395 vos_timer_stop(&pHddCtx->tdls_source_timer);
10396 }
10397
10398 vos_timer_destroy(&pHddCtx->tdls_source_timer);
10399
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 //Disable IMPS/BMPS as we do not want the device to enter any power
10401 //save mode during shutdown
10402 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
10403 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
10404 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
10405
10406 //Ensure that device is in full power as we will touch H/W during vos_Stop
10407 init_completion(&powerContext.completion);
10408 powerContext.magic = POWER_CONTEXT_MAGIC;
10409
10410 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
10411 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
10412
10413 if (eHAL_STATUS_SUCCESS != halStatus)
10414 {
10415 if (eHAL_STATUS_PMC_PENDING == halStatus)
10416 {
10417 /* request was sent -- wait for the response */
10418 lrc = wait_for_completion_interruptible_timeout(
10419 &powerContext.completion,
10420 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070010421 if (lrc <= 0)
10422 {
10423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010424 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 }
10426 }
10427 else
10428 {
10429 hddLog(VOS_TRACE_LEVEL_ERROR,
10430 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010431 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 /* continue -- need to clean up as much as possible */
10433 }
10434 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053010435 if ((eHAL_STATUS_SUCCESS == halStatus) ||
10436 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
10437 {
10438 /* This will issue a dump command which will clean up
10439 BTQM queues and unblock MC thread */
10440 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
10441 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010442
Jeff Johnson72a40512013-12-19 10:14:15 -080010443 /* either we never sent a request, we sent a request and received a
10444 response or we sent a request and timed out. if we never sent a
10445 request or if we sent a request and got a response, we want to
10446 clear the magic out of paranoia. if we timed out there is a
10447 race condition such that the callback function could be
10448 executing at the same time we are. of primary concern is if the
10449 callback function had already verified the "magic" but had not
10450 yet set the completion variable when a timeout occurred. we
10451 serialize these activities by invalidating the magic while
10452 holding a shared spinlock which will cause us to block if the
10453 callback is currently executing */
10454 spin_lock(&hdd_context_lock);
10455 powerContext.magic = 0;
10456 spin_unlock(&hdd_context_lock);
10457
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053010458 /* If Device is shutdown, no point for SME to wait for responses
10459 from device. Pre Close SME */
10460 if(wcnss_device_is_shutdown())
10461 {
10462 sme_PreClose(pHddCtx->hHal);
10463 }
Yue Ma0d4891e2013-08-06 17:01:45 -070010464 hdd_debugfs_exit(pHddCtx);
10465
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010466#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053010467 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010468 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10469#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053010470 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010471 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10472
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 // Unregister the Net Device Notifier
10474 unregister_netdevice_notifier(&hdd_netdev_notifier);
10475
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 hdd_stop_all_adapters( pHddCtx );
10477
Jeff Johnson295189b2012-06-20 16:38:30 -070010478#ifdef WLAN_BTAMP_FEATURE
10479 vosStatus = WLANBAP_Stop(pVosContext);
10480 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10481 {
10482 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10483 "%s: Failed to stop BAP",__func__);
10484 }
10485#endif //WLAN_BTAMP_FEATURE
10486
10487 //Stop all the modules
10488 vosStatus = vos_stop( pVosContext );
10489 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10490 {
10491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10492 "%s: Failed to stop VOSS",__func__);
10493 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053010494 if (isSsrPanicOnFailure())
10495 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010496 }
10497
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070010499 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010500
10501 //Close the scheduler before calling vos_close to make sure no thread is
10502 // scheduled after the each module close is called i.e after all the data
10503 // structures are freed.
10504 vosStatus = vos_sched_close( pVosContext );
10505 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10506 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10507 "%s: Failed to close VOSS Scheduler",__func__);
10508 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10509 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010510#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10511 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010512 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010513#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010514 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010515 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010516
Mihir Shete7a24b5f2013-12-21 12:18:31 +053010517#ifdef CONFIG_ENABLE_LINUX_REG
10518 vosStatus = vos_nv_close();
10519 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10520 {
10521 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10522 "%s: Failed to close NV", __func__);
10523 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10524 }
10525#endif
10526
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 //Close VOSS
10528 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
10529 vos_close(pVosContext);
10530
Jeff Johnson295189b2012-06-20 16:38:30 -070010531 //Close Watchdog
10532 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10533 vos_watchdog_close(pVosContext);
10534
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010535 //Clean up HDD Nlink Service
10536 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010537
Manjeet Singh47ee8472016-04-11 11:57:18 +053010538 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053010539 wlan_free_fwr_mem_dump_buffer();
10540 memdump_deinit();
10541
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010542#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010543 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010544 {
10545 wlan_logging_sock_deactivate_svc();
10546 }
10547#endif
10548
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010549#ifdef WLAN_KD_READY_NOTIFIER
10550 nl_srv_exit(pHddCtx->ptt_pid);
10551#else
10552 nl_srv_exit();
10553#endif /* WLAN_KD_READY_NOTIFIER */
10554
Abhishek Singh00b71972016-01-07 10:51:04 +053010555#ifdef WLAN_FEATURE_RMC
10556 hdd_close_cesium_nl_sock();
10557#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010558
Jeff Johnson295189b2012-06-20 16:38:30 -070010559 hdd_close_all_adapters( pHddCtx );
10560
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053010561 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
10562
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053010563free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 /* free the power on lock from platform driver */
10565 if (free_riva_power_on_lock("wlan"))
10566 {
10567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
10568 __func__);
10569 }
10570
c_hpothu78c7b602014-05-17 17:35:49 +053010571 //Free up dynamically allocated members inside HDD Adapter
10572 if (pHddCtx->cfg_ini)
10573 {
10574 kfree(pHddCtx->cfg_ini);
10575 pHddCtx->cfg_ini= NULL;
10576 }
10577
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010578 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070010579 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010580 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
10581 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070010582 {
10583 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010584 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070010585 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010586 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 if (hdd_is_ssr_required())
10588 {
10589 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070010590 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 msleep(5000);
10592 }
10593 hdd_set_ssr_required (VOS_FALSE);
10594}
10595
10596
10597/**---------------------------------------------------------------------------
10598
10599 \brief hdd_update_config_from_nv() - Function to update the contents of
10600 the running configuration with parameters taken from NV storage
10601
10602 \param - pHddCtx - Pointer to the HDD global context
10603
10604 \return - VOS_STATUS_SUCCESS if successful
10605
10606 --------------------------------------------------------------------------*/
10607static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
10608{
Jeff Johnson295189b2012-06-20 16:38:30 -070010609 v_BOOL_t itemIsValid = VOS_FALSE;
10610 VOS_STATUS status;
10611 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
10612 v_U8_t macLoop;
10613
10614 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
10615 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
10616 if(status != VOS_STATUS_SUCCESS)
10617 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010618 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010619 return VOS_STATUS_E_FAILURE;
10620 }
10621
10622 if (itemIsValid == VOS_TRUE)
10623 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010624 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070010625 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
10626 VOS_MAX_CONCURRENCY_PERSONA);
10627 if(status != VOS_STATUS_SUCCESS)
10628 {
10629 /* Get MAC from NV fail, not update CFG info
10630 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080010631 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010632 return VOS_STATUS_E_FAILURE;
10633 }
10634
10635 /* If first MAC is not valid, treat all others are not valid
10636 * Then all MACs will be got from ini file */
10637 if(vos_is_macaddr_zero(&macFromNV[0]))
10638 {
10639 /* MAC address in NV file is not configured yet */
10640 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
10641 return VOS_STATUS_E_INVAL;
10642 }
10643
10644 /* Get MAC address from NV, update CFG info */
10645 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
10646 {
10647 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
10648 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010649 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070010650 /* This MAC is not valid, skip it
10651 * This MAC will be got from ini file */
10652 }
10653 else
10654 {
10655 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
10656 (v_U8_t *)&macFromNV[macLoop].bytes[0],
10657 VOS_MAC_ADDR_SIZE);
10658 }
10659 }
10660 }
10661 else
10662 {
10663 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
10664 return VOS_STATUS_E_FAILURE;
10665 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010666
Jeff Johnson295189b2012-06-20 16:38:30 -070010667
10668 return VOS_STATUS_SUCCESS;
10669}
10670
10671/**---------------------------------------------------------------------------
10672
10673 \brief hdd_post_voss_start_config() - HDD post voss start config helper
10674
10675 \param - pAdapter - Pointer to the HDD
10676
10677 \return - None
10678
10679 --------------------------------------------------------------------------*/
10680VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
10681{
10682 eHalStatus halStatus;
10683 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010684 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070010685
Jeff Johnson295189b2012-06-20 16:38:30 -070010686
10687 // Send ready indication to the HDD. This will kick off the MAC
10688 // into a 'running' state and should kick off an initial scan.
10689 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
10690 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10691 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010692 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070010693 "code %08d [x%08x]",__func__, halStatus, halStatus );
10694 return VOS_STATUS_E_FAILURE;
10695 }
10696
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010697 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070010698 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
10699 // And RIVA will crash
10700 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
10701 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010702 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
10703 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
10704
10705
Jeff Johnson295189b2012-06-20 16:38:30 -070010706 return VOS_STATUS_SUCCESS;
10707}
10708
Jeff Johnson295189b2012-06-20 16:38:30 -070010709/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010710void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010711{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010712
10713 vos_wake_lock_acquire(&wlan_wake_lock, reason);
10714
Jeff Johnson295189b2012-06-20 16:38:30 -070010715}
10716
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010717void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010718{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010719
10720 vos_wake_lock_release(&wlan_wake_lock, reason);
10721
Jeff Johnson295189b2012-06-20 16:38:30 -070010722}
10723
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010724void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010725{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010726
10727 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
10728 reason);
10729
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010730}
10731
Jeff Johnson295189b2012-06-20 16:38:30 -070010732/**---------------------------------------------------------------------------
10733
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010734 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
10735 information between Host and Riva
10736
10737 This function gets reported version of FW
10738 It also finds the version of Riva headers used to compile the host
10739 It compares the above two and prints a warning if they are different
10740 It gets the SW and HW version string
10741 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
10742 indicating the features they support through a bitmap
10743
10744 \param - pHddCtx - Pointer to HDD context
10745
10746 \return - void
10747
10748 --------------------------------------------------------------------------*/
10749
10750void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
10751{
10752
10753 tSirVersionType versionCompiled;
10754 tSirVersionType versionReported;
10755 tSirVersionString versionString;
10756 tANI_U8 fwFeatCapsMsgSupported = 0;
10757 VOS_STATUS vstatus;
10758
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010759 memset(&versionCompiled, 0, sizeof(versionCompiled));
10760 memset(&versionReported, 0, sizeof(versionReported));
10761
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010762 /* retrieve and display WCNSS version information */
10763 do {
10764
10765 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
10766 &versionCompiled);
10767 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10768 {
10769 hddLog(VOS_TRACE_LEVEL_FATAL,
10770 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010771 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010772 break;
10773 }
10774
10775 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
10776 &versionReported);
10777 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10778 {
10779 hddLog(VOS_TRACE_LEVEL_FATAL,
10780 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010781 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010782 break;
10783 }
10784
10785 if ((versionCompiled.major != versionReported.major) ||
10786 (versionCompiled.minor != versionReported.minor) ||
10787 (versionCompiled.version != versionReported.version) ||
10788 (versionCompiled.revision != versionReported.revision))
10789 {
10790 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
10791 "Host expected %u.%u.%u.%u\n",
10792 WLAN_MODULE_NAME,
10793 (int)versionReported.major,
10794 (int)versionReported.minor,
10795 (int)versionReported.version,
10796 (int)versionReported.revision,
10797 (int)versionCompiled.major,
10798 (int)versionCompiled.minor,
10799 (int)versionCompiled.version,
10800 (int)versionCompiled.revision);
10801 }
10802 else
10803 {
10804 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
10805 WLAN_MODULE_NAME,
10806 (int)versionReported.major,
10807 (int)versionReported.minor,
10808 (int)versionReported.version,
10809 (int)versionReported.revision);
10810 }
10811
10812 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
10813 versionString,
10814 sizeof(versionString));
10815 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10816 {
10817 hddLog(VOS_TRACE_LEVEL_FATAL,
10818 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010819 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010820 break;
10821 }
10822
10823 pr_info("%s: WCNSS software version %s\n",
10824 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053010825 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010826
10827 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
10828 versionString,
10829 sizeof(versionString));
10830 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10831 {
10832 hddLog(VOS_TRACE_LEVEL_FATAL,
10833 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010834 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010835 break;
10836 }
10837
10838 pr_info("%s: WCNSS hardware version %s\n",
10839 WLAN_MODULE_NAME, versionString);
10840
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010841 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
10842 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010843 send the message only if it the riva is 1.1
10844 minor numbers for different riva branches:
10845 0 -> (1.0)Mainline Build
10846 1 -> (1.1)Mainline Build
10847 2->(1.04) Stability Build
10848 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010849 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010850 ((versionReported.minor>=1) && (versionReported.version>=1)))
10851 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
10852 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010853
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010854 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080010855 {
10856#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
10857 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
10858 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
10859#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070010860 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
10861 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
10862 {
10863 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
10864 }
10865
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010866 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080010867 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010868
10869 } while (0);
10870
10871}
Neelansh Mittaledafed22014-09-04 18:54:39 +053010872void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
10873{
10874 struct sk_buff *skb;
10875 struct nlmsghdr *nlh;
10876 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010877 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053010878 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010879
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010880 if (in_interrupt() || irqs_disabled() || in_atomic())
10881 flags = GFP_ATOMIC;
10882
10883 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053010884
10885 if(skb == NULL) {
10886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10887 "%s: alloc_skb failed", __func__);
10888 return;
10889 }
10890
10891 nlh = (struct nlmsghdr *)skb->data;
10892 nlh->nlmsg_pid = 0; /* from kernel */
10893 nlh->nlmsg_flags = 0;
10894 nlh->nlmsg_seq = 0;
10895 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
10896
10897 ani_hdr = NLMSG_DATA(nlh);
10898 ani_hdr->type = type;
10899
10900 switch(type) {
10901 case WLAN_SVC_SAP_RESTART_IND:
10902 ani_hdr->length = 0;
10903 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
10904 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
10905 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053010906 case WLAN_SVC_WLAN_TP_IND:
10907 ani_hdr->length = len;
10908 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
10909 + len));
10910 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10911 memcpy(nl_data, data, len);
10912 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10913 break;
Bhargav shah23c94942015-10-13 12:48:35 +053010914 case WLAN_MSG_RPS_ENABLE_IND:
10915 ani_hdr->length = len;
10916 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
10917 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10918 memcpy(nl_data, data, len);
10919 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10920 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010921 default:
10922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10923 "Attempt to send unknown nlink message %d", type);
10924 kfree_skb(skb);
10925 return;
10926 }
10927
10928 nl_srv_bcast(skb);
10929
10930 return;
10931}
10932
Bhargav Shahd0715912015-10-01 18:17:37 +053010933/**
10934 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
10935 * @pHddCtx: Valid Global HDD context pointer
10936 * @rx_packets: Number of RX packet in perticular time
10937 *
10938 * Based on the RX packet this function calculate next value of tcp delack.
10939 * This function compare rx packet value to high and low threshold limit.
10940 *
10941 * Return: void
10942 */
10943void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
10944{
10945 /* average of rx_packets and prev_rx is taken so that
10946 bus width doesnot fluctuate much */
10947 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
10948 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010949
Bhargav Shahd0715912015-10-01 18:17:37 +053010950 pHddCtx->prev_rx = rx_packets;
10951 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
10952 next_rx_level = TP_IND_HIGH;
10953 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
10954 next_rx_level = TP_IND_LOW;
10955
10956 hdd_set_delack_value(pHddCtx, next_rx_level);
10957}
10958
10959#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
10960
10961/**
10962 * hdd_tcp_delack_compute_function() - get link status
10963 * @priv: Valid Global HDD context pointer
10964 *
10965 * This function find number of RX packet during timer life span.
10966 * It request tcp delack with number of RX packet and re-configure delack timer
10967 * for tcpDelAckComputeInterval timer interval.
10968 *
10969 * Return: void
10970 */
10971void hdd_tcp_delack_compute_function(void *priv)
10972{
10973 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
10974 hdd_adapter_t *pAdapter = NULL;
10975 v_U32_t rx_packets = 0;
10976 hdd_adapter_list_node_t *pAdapterNode = NULL;
10977 VOS_STATUS status = 0;
10978
10979 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
10980 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
10981 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
10982 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
10983 continue;
10984
10985 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
10986 pAdapter->prev_rx_packets);
10987 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
10988 }
10989
10990 hdd_request_tcp_delack(pHddCtx, rx_packets);
10991
10992 vos_timer_start(&pHddCtx->delack_timer,
10993 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
10994}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010995
10996/**---------------------------------------------------------------------------
10997
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053010998 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
10999
11000 \param - pHddCtx - Pointer to the hdd context
11001
11002 \return - true if hardware supports 5GHz
11003
11004 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053011005boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011006{
11007 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
11008 * then hardware support 5Ghz.
11009 */
11010 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
11011 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011012 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011013 return true;
11014 }
11015 else
11016 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011017 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011018 __func__);
11019 return false;
11020 }
11021}
11022
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011023/**---------------------------------------------------------------------------
11024
11025 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
11026 generate function
11027
11028 This is generate the random mac address for WLAN interface
11029
11030 \param - pHddCtx - Pointer to HDD context
11031 idx - Start interface index to get auto
11032 generated mac addr.
11033 mac_addr - Mac address
11034
11035 \return - 0 for success, < 0 for failure
11036
11037 --------------------------------------------------------------------------*/
11038
11039static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
11040 int idx, v_MACADDR_t mac_addr)
11041{
11042 int i;
11043 unsigned int serialno;
11044 serialno = wcnss_get_serial_number();
11045
11046 if (0 != serialno)
11047 {
11048 /* MAC address has 3 bytes of OUI so we have a maximum of 3
11049 bytes of the serial number that can be used to generate
11050 the other 3 bytes of the MAC address. Mask off all but
11051 the lower 3 bytes (this will also make sure we don't
11052 overflow in the next step) */
11053 serialno &= 0x00FFFFFF;
11054
11055 /* we need a unique address for each session */
11056 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
11057
11058 /* autogen other Mac addresses */
11059 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
11060 {
11061 /* start with the entire default address */
11062 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
11063 /* then replace the lower 3 bytes */
11064 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
11065 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
11066 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
11067
11068 serialno++;
11069 hddLog(VOS_TRACE_LEVEL_ERROR,
11070 "%s: Derived Mac Addr: "
11071 MAC_ADDRESS_STR, __func__,
11072 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
11073 }
11074
11075 }
11076 else
11077 {
11078 hddLog(LOGE, FL("Failed to Get Serial NO"));
11079 return -1;
11080 }
11081 return 0;
11082}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011083
Katya Nigame7b69a82015-04-28 15:24:06 +053011084int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
11085{
11086 VOS_STATUS status;
11087 v_CONTEXT_t pVosContext= NULL;
11088 hdd_adapter_t *pAdapter= NULL;
11089
11090 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11091
11092 if (NULL == pVosContext)
11093 {
11094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11095 "%s: Trying to open VOSS without a PreOpen", __func__);
11096 VOS_ASSERT(0);
11097 return VOS_STATUS_E_FAILURE;
11098 }
11099
11100 status = vos_nv_open();
11101 if (!VOS_IS_STATUS_SUCCESS(status))
11102 {
11103 /* NV module cannot be initialized */
11104 hddLog( VOS_TRACE_LEVEL_FATAL,
11105 "%s: vos_nv_open failed", __func__);
11106 return VOS_STATUS_E_FAILURE;
11107 }
11108
11109 status = vos_init_wiphy_from_nv_bin();
11110 if (!VOS_IS_STATUS_SUCCESS(status))
11111 {
11112 /* NV module cannot be initialized */
11113 hddLog( VOS_TRACE_LEVEL_FATAL,
11114 "%s: vos_init_wiphy failed", __func__);
11115 goto err_vos_nv_close;
11116 }
11117
11118 status = vos_open( &pVosContext, pHddCtx->parent_dev);
11119 if ( !VOS_IS_STATUS_SUCCESS( status ))
11120 {
11121 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
11122 goto err_vos_nv_close;
11123 }
11124
11125 status = vos_mon_start( pVosContext );
11126 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11127 {
11128 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
11129 goto err_vosclose;
11130 }
11131
11132 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
11133 WDA_featureCapsExchange(pVosContext);
11134 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11135
11136 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
11137 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11138 if( pAdapter == NULL )
11139 {
11140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
11141 goto err_close_adapter;
11142 }
11143
11144 //Initialize the nlink service
11145 if(nl_srv_init() != 0)
11146 {
11147 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11148 goto err_close_adapter;
11149 }
11150 return VOS_STATUS_SUCCESS;
11151
11152err_close_adapter:
11153 hdd_close_all_adapters( pHddCtx );
11154 vos_mon_stop( pVosContext );
11155err_vosclose:
11156 status = vos_sched_close( pVosContext );
11157 if (!VOS_IS_STATUS_SUCCESS(status)) {
11158 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11159 "%s: Failed to close VOSS Scheduler", __func__);
11160 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
11161 }
11162 vos_close(pVosContext );
11163
11164err_vos_nv_close:
11165 vos_nv_close();
11166
11167return status;
11168}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011169/**---------------------------------------------------------------------------
11170
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011171 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
11172 completed to flush out the scan results
11173
11174 11d scan is done during driver load and is a passive scan on all
11175 channels supported by the device, 11d scans may find some APs on
11176 frequencies which are forbidden to be used in the regulatory domain
11177 the device is operating in. If these APs are notified to the supplicant
11178 it may try to connect to these APs, thus flush out all the scan results
11179 which are present in SME after 11d scan is done.
11180
11181 \return - eHalStatus
11182
11183 --------------------------------------------------------------------------*/
11184static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
11185 tANI_U32 scanId, eCsrScanStatus status)
11186{
11187 ENTER();
11188
11189 sme_ScanFlushResult(halHandle, 0);
11190
11191 EXIT();
11192
11193 return eHAL_STATUS_SUCCESS;
11194}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011195/**---------------------------------------------------------------------------
11196
11197 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
11198 logging is completed successfully.
11199
11200 \return - None
11201
11202 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053011203void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011204{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011205 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011206
11207 if (NULL == pHddCtx)
11208 {
11209 hddLog(VOS_TRACE_LEVEL_ERROR,
11210 "%s: HDD context is NULL",__func__);
11211 return;
11212 }
11213
c_manjeecfd1efb2015-09-25 19:32:34 +053011214 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053011215 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011216 {
11217 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
11218 pHddCtx->mgmt_frame_logging = TRUE;
11219 }
11220 else
11221 {
11222 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
11223 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053011224 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011225 }
11226
c_manjeecfd1efb2015-09-25 19:32:34 +053011227 /*Check feature supported by FW*/
11228 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
11229 {
11230 //Store fwr mem dump size given by firmware.
11231 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
11232 }
11233 else
11234 {
11235 wlan_store_fwr_mem_dump_size(0);
11236 }
11237
11238
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011239}
11240/**---------------------------------------------------------------------------
11241
11242 \brief hdd_init_frame_logging - function to initialize frame logging.
11243 Currently only Mgmt Frames are logged in both TX
11244 and Rx direction and are sent to userspace
11245 application using logger thread when queried.
11246
11247 \return - None
11248
11249 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011250void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011251{
11252 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011253 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011254
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011255 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
11256 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011257 {
11258 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
11259 return;
11260 }
11261
c_manjeecfd1efb2015-09-25 19:32:34 +053011262 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011263 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
11264 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053011265 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
11266 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011267
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011268 if (pHddCtx->cfg_ini->enableFWLogging ||
11269 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011270 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011271 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011272 }
11273
Sushant Kaushik46804902015-07-08 14:46:03 +053011274 if (pHddCtx->cfg_ini->enableMgmtLogging)
11275 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011276 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053011277 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011278 if (pHddCtx->cfg_ini->enableBMUHWtracing)
11279 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011280 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011281 }
c_manjeecfd1efb2015-09-25 19:32:34 +053011282 if(pHddCtx->cfg_ini->enableFwrMemDump &&
11283 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
11284 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011285 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053011286 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011287 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053011288 {
11289 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
11290 return;
11291 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011292 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
11293 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
11294 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
11295 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011296 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011297
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011298 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011299
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011300 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011301 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011302 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011303 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011304 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
11305 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011306
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011307 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011308
11309 if (eHAL_STATUS_SUCCESS != halStatus)
11310 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011311 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
11312 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011313 }
11314
11315 return;
11316}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011317
Bhargav shah23c94942015-10-13 12:48:35 +053011318static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
11319{
11320 hdd_adapter_t *adapter;
11321 hdd_adapter_list_node_t *adapter_node, *next;
11322 VOS_STATUS status = VOS_STATUS_SUCCESS;
11323 struct wlan_rps_data rps_data;
11324 int count;
11325
11326 if(!hdd_ctxt->cfg_ini->rps_mask)
11327 {
11328 return;
11329 }
11330
11331 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
11332 {
11333 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
11334 }
11335
11336 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
11337
11338 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
11339 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
11340 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
11341
11342 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
11343
11344 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
11345 {
11346 adapter = adapter_node->pAdapter;
11347 if (NULL != adapter) {
11348 strlcpy(rps_data.ifname, adapter->dev->name,
11349 sizeof(rps_data.ifname));
11350 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
11351 (void *)&rps_data,sizeof(rps_data));
11352 }
11353 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
11354 adapter_node = next;
11355 }
11356}
11357
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011358void wlan_hdd_schedule_defer_scan(struct work_struct *work)
11359{
11360 scan_context_t *scan_ctx =
11361 container_of(work, scan_context_t, scan_work.work);
11362
11363 if (NULL == scan_ctx)
11364 {
11365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11366 FL("scan_ctx is NULL"));
11367 return;
11368 }
11369
11370 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
11371 return;
11372
11373 scan_ctx->attempt++;
11374
11375 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
11376#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11377 scan_ctx->dev,
11378#endif
11379 scan_ctx->scan_request);
11380}
11381
11382int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
11383 struct wiphy *wiphy,
11384#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11385 struct net_device *dev,
11386#endif
11387 struct cfg80211_scan_request *request)
11388{
11389 scan_context_t *scan_ctx;
11390
11391 ENTER();
11392 if (0 != (wlan_hdd_validate_context(pHddCtx)))
11393 {
11394 return -1;
11395 }
11396
11397 scan_ctx = &pHddCtx->scan_ctxt;
11398
11399 scan_ctx->wiphy = wiphy;
11400#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11401 scan_ctx->dev = dev;
11402#endif
11403
11404 scan_ctx->scan_request = request;
11405
11406 EXIT();
11407 return 0;
11408}
11409
11410void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
11411 struct wiphy *wiphy,
11412#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11413 struct net_device *dev,
11414#endif
11415 struct cfg80211_scan_request *request,
11416 unsigned long delay)
11417{
11418 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
11419 {
11420#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11421 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
11422#else
11423 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
11424#endif
11425 pHddCtx->scan_ctxt.attempt = 0;
11426 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
11427 }
11428 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
11429}
11430
11431void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
11432{
11433 scan_ctx->magic = 0;
11434 scan_ctx->attempt = 0;
11435 scan_ctx->reject = 0;
11436 scan_ctx->scan_request = NULL;
11437
11438 return;
11439}
11440
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011441/**---------------------------------------------------------------------------
11442
Jeff Johnson295189b2012-06-20 16:38:30 -070011443 \brief hdd_wlan_startup() - HDD init function
11444
11445 This is the driver startup code executed once a WLAN device has been detected
11446
11447 \param - dev - Pointer to the underlying device
11448
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011449 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070011450
11451 --------------------------------------------------------------------------*/
11452
11453int hdd_wlan_startup(struct device *dev )
11454{
11455 VOS_STATUS status;
11456 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011457 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 hdd_context_t *pHddCtx = NULL;
11459 v_CONTEXT_t pVosContext= NULL;
11460#ifdef WLAN_BTAMP_FEATURE
11461 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
11462 WLANBAP_ConfigType btAmpConfig;
11463 hdd_config_t *pConfig;
11464#endif
11465 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011467 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011468
11469 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011470 /*
11471 * cfg80211: wiphy allocation
11472 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011473 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070011474
11475 if(wiphy == NULL)
11476 {
11477 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011478 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011479 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011480 pHddCtx = wiphy_priv(wiphy);
11481
Jeff Johnson295189b2012-06-20 16:38:30 -070011482 //Initialize the adapter context to zeros.
11483 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
11484
Jeff Johnson295189b2012-06-20 16:38:30 -070011485 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011486 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053011487 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011488
11489 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
11490
Siddharth Bhalcd92b782015-06-29 12:25:40 +053011491 /* register for riva power on lock to platform driver
11492 * Locking power early to ensure FW doesn't reset by kernel while
11493 * host driver is busy initializing itself */
11494 if (req_riva_power_on_lock("wlan"))
11495 {
11496 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
11497 __func__);
11498 goto err_free_hdd_context;
11499 }
11500
Jeff Johnson295189b2012-06-20 16:38:30 -070011501 /*Get vos context here bcoz vos_open requires it*/
11502 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11503
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080011504 if(pVosContext == NULL)
11505 {
11506 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
11507 goto err_free_hdd_context;
11508 }
11509
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 //Save the Global VOSS context in adapter context for future.
11511 pHddCtx->pvosContext = pVosContext;
11512
11513 //Save the adapter context in global context for future.
11514 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
11515
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 pHddCtx->parent_dev = dev;
11517
11518 init_completion(&pHddCtx->full_pwr_comp_var);
11519 init_completion(&pHddCtx->standby_comp_var);
11520 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011521 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011522 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053011523 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053011524 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053011525 init_completion(&pHddCtx->mc_sus_event_var);
11526 init_completion(&pHddCtx->tx_sus_event_var);
11527 init_completion(&pHddCtx->rx_sus_event_var);
11528
Amar Singhala49cbc52013-10-08 18:37:44 -070011529
mukul sharma4bd8d2e2015-08-13 20:33:25 +053011530 hdd_init_ll_stats_ctx(pHddCtx);
11531
Amar Singhala49cbc52013-10-08 18:37:44 -070011532#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070011533 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070011534#else
11535 init_completion(&pHddCtx->driver_crda_req);
11536#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011537
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053011538#ifdef WLAN_FEATURE_EXTSCAN
11539 init_completion(&pHddCtx->ext_scan_context.response_event);
11540#endif /* WLAN_FEATURE_EXTSCAN */
11541
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053011542 spin_lock_init(&pHddCtx->schedScan_lock);
11543
Jeff Johnson295189b2012-06-20 16:38:30 -070011544 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
11545
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011546 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
11547 hdd_processSpoofMacAddrRequest);
11548
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011549#ifdef FEATURE_WLAN_TDLS
11550 /* tdls_lock is initialized before an hdd_open_adapter ( which is
11551 * invoked by other instances also) to protect the concurrent
11552 * access for the Adapters by TDLS module.
11553 */
11554 mutex_init(&pHddCtx->tdls_lock);
11555#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053011556 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053011557 mutex_init(&pHddCtx->wmmLock);
11558
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053011559 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053011560 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011561
Agarwal Ashish1f422872014-07-22 00:11:55 +053011562 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011563 // Load all config first as TL config is needed during vos_open
11564 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
11565 if(pHddCtx->cfg_ini == NULL)
11566 {
11567 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
11568 goto err_free_hdd_context;
11569 }
11570
11571 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
11572
11573 // Read and parse the qcom_cfg.ini file
11574 status = hdd_parse_config_ini( pHddCtx );
11575 if ( VOS_STATUS_SUCCESS != status )
11576 {
11577 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
11578 __func__, WLAN_INI_FILE);
11579 goto err_config;
11580 }
Arif Hussaind5218912013-12-05 01:10:55 -080011581#ifdef MEMORY_DEBUG
11582 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
11583 vos_mem_init();
11584
11585 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
11586 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
11587#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011588
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053011589 /* INI has been read, initialise the configuredMcastBcastFilter with
11590 * INI value as this will serve as the default value
11591 */
11592 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
11593 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
11594 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011595
11596 if (false == hdd_is_5g_supported(pHddCtx))
11597 {
11598 //5Ghz is not supported.
11599 if (1 != pHddCtx->cfg_ini->nBandCapability)
11600 {
11601 hddLog(VOS_TRACE_LEVEL_INFO,
11602 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
11603 pHddCtx->cfg_ini->nBandCapability = 1;
11604 }
11605 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053011606
11607 /* If SNR Monitoring is enabled, FW has to parse all beacons
11608 * for calcaluting and storing the average SNR, so set Nth beacon
11609 * filter to 1 to enable FW to parse all the beaocons
11610 */
11611 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
11612 {
11613 /* The log level is deliberately set to WARN as overriding
11614 * nthBeaconFilter to 1 will increase power cosumption and this
11615 * might just prove helpful to detect the power issue.
11616 */
11617 hddLog(VOS_TRACE_LEVEL_WARN,
11618 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
11619 pHddCtx->cfg_ini->nthBeaconFilter = 1;
11620 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011621 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011622 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070011623 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080011624 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070011625 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080011626 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
11627 {
11628 hddLog(VOS_TRACE_LEVEL_FATAL,
11629 "%s: wlan_hdd_cfg80211_init return failure", __func__);
11630 goto err_config;
11631 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011632 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011633
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011634 // Update VOS trace levels based upon the cfg.ini
11635 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
11636 pHddCtx->cfg_ini->vosTraceEnableBAP);
11637 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
11638 pHddCtx->cfg_ini->vosTraceEnableTL);
11639 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
11640 pHddCtx->cfg_ini->vosTraceEnableWDI);
11641 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
11642 pHddCtx->cfg_ini->vosTraceEnableHDD);
11643 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
11644 pHddCtx->cfg_ini->vosTraceEnableSME);
11645 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
11646 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053011647 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
11648 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011649 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
11650 pHddCtx->cfg_ini->vosTraceEnableWDA);
11651 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
11652 pHddCtx->cfg_ini->vosTraceEnableSYS);
11653 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
11654 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011655 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
11656 pHddCtx->cfg_ini->vosTraceEnableSAP);
11657 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
11658 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011659
Jeff Johnson295189b2012-06-20 16:38:30 -070011660 // Update WDI trace levels based upon the cfg.ini
11661 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
11662 pHddCtx->cfg_ini->wdiTraceEnableDAL);
11663 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
11664 pHddCtx->cfg_ini->wdiTraceEnableCTL);
11665 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
11666 pHddCtx->cfg_ini->wdiTraceEnableDAT);
11667 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
11668 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011669
Jeff Johnson88ba7742013-02-27 14:36:02 -080011670 if (VOS_FTM_MODE == hdd_get_conparam())
11671 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
11673 {
11674 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
11675 goto err_free_hdd_context;
11676 }
11677 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053011678 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053011679 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011680 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080011681 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011682
Katya Nigame7b69a82015-04-28 15:24:06 +053011683 if( VOS_MONITOR_MODE == hdd_get_conparam())
11684 {
11685 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
11686 {
11687 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
11688 goto err_free_hdd_context;
11689 }
11690 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
11691 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
11692 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11693 return VOS_STATUS_SUCCESS;
11694 }
11695
Jeff Johnson88ba7742013-02-27 14:36:02 -080011696 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 if(pHddCtx->cfg_ini->fIsLogpEnabled)
11698 {
11699 status = vos_watchdog_open(pVosContext,
11700 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
11701
11702 if(!VOS_IS_STATUS_SUCCESS( status ))
11703 {
11704 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011705 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 }
11707 }
11708
11709 pHddCtx->isLogpInProgress = FALSE;
11710 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11711
Amar Singhala49cbc52013-10-08 18:37:44 -070011712#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070011713 /* initialize the NV module. This is required so that
11714 we can initialize the channel information in wiphy
11715 from the NV.bin data. The channel information in
11716 wiphy needs to be initialized before wiphy registration */
11717
11718 status = vos_nv_open();
11719 if (!VOS_IS_STATUS_SUCCESS(status))
11720 {
11721 /* NV module cannot be initialized */
11722 hddLog( VOS_TRACE_LEVEL_FATAL,
11723 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053011724 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070011725 }
11726
11727 status = vos_init_wiphy_from_nv_bin();
11728 if (!VOS_IS_STATUS_SUCCESS(status))
11729 {
11730 /* NV module cannot be initialized */
11731 hddLog( VOS_TRACE_LEVEL_FATAL,
11732 "%s: vos_init_wiphy failed", __func__);
11733 goto err_vos_nv_close;
11734 }
11735
Amar Singhala49cbc52013-10-08 18:37:44 -070011736#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011737 //Initialize the nlink service
11738 if(nl_srv_init() != 0)
11739 {
11740 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11741 goto err_vos_nv_close;
11742 }
11743
11744#ifdef WLAN_KD_READY_NOTIFIER
11745 pHddCtx->kd_nl_init = 1;
11746#endif /* WLAN_KD_READY_NOTIFIER */
11747
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053011748 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053011749 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070011750 if ( !VOS_IS_STATUS_SUCCESS( status ))
11751 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011752 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011753 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 }
11755
Jeff Johnson295189b2012-06-20 16:38:30 -070011756 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
11757
11758 if ( NULL == pHddCtx->hHal )
11759 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011760 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011761 goto err_vosclose;
11762 }
11763
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011764 status = vos_preStart( pHddCtx->pvosContext );
11765 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11766 {
11767 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011768 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011769 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011770
Arif Hussaineaf68602013-12-30 23:10:44 -080011771 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
11772 {
11773 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
11774 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
11775 __func__, enable_dfs_chan_scan);
11776 }
11777 if (0 == enable_11d || 1 == enable_11d)
11778 {
11779 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
11780 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
11781 __func__, enable_11d);
11782 }
11783
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011784 /* Note that the vos_preStart() sequence triggers the cfg download.
11785 The cfg download must occur before we update the SME config
11786 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 status = hdd_set_sme_config( pHddCtx );
11788
11789 if ( VOS_STATUS_SUCCESS != status )
11790 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011791 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011792 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011793 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011794
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 /* In the integrated architecture we update the configuration from
11796 the INI file and from NV before vOSS has been started so that
11797 the final contents are available to send down to the cCPU */
11798
11799 // Apply the cfg.ini to cfg.dat
11800 if (FALSE == hdd_update_config_dat(pHddCtx))
11801 {
11802 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011803 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011804 }
11805
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011806 // Get mac addr from platform driver
11807 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
11808
11809 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011811 /* Store the mac addr for first interface */
11812 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
11813
11814 hddLog(VOS_TRACE_LEVEL_ERROR,
11815 "%s: WLAN Mac Addr: "
11816 MAC_ADDRESS_STR, __func__,
11817 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11818
11819 /* Here, passing Arg2 as 1 because we do not want to change the
11820 last 3 bytes (means non OUI bytes) of first interface mac
11821 addr.
11822 */
11823 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
11824 {
11825 hddLog(VOS_TRACE_LEVEL_ERROR,
11826 "%s: Failed to generate wlan interface mac addr "
11827 "using MAC from ini file ", __func__);
11828 }
11829 }
11830 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
11831 {
11832 // Apply the NV to cfg.dat
11833 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070011834#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
11835 /* There was not a valid set of MAC Addresses in NV. See if the
11836 default addresses were modified by the cfg.ini settings. If so,
11837 we'll use them, but if not, we'll autogenerate a set of MAC
11838 addresses based upon the device serial number */
11839
11840 static const v_MACADDR_t default_address =
11841 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070011842
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011843 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
11844 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 {
11846 /* cfg.ini has the default address, invoke autogen logic */
11847
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011848 /* Here, passing Arg2 as 0 because we want to change the
11849 last 3 bytes (means non OUI bytes) of all the interfaces
11850 mac addr.
11851 */
11852 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
11853 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070011854 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011855 hddLog(VOS_TRACE_LEVEL_ERROR,
11856 "%s: Failed to generate wlan interface mac addr "
11857 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
11858 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011860 }
11861 else
11862#endif //WLAN_AUTOGEN_MACADDR_FEATURE
11863 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011864 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011865 "%s: Invalid MAC address in NV, using MAC from ini file "
11866 MAC_ADDRESS_STR, __func__,
11867 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11868 }
11869 }
11870 {
11871 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011872
11873 /* Set the MAC Address Currently this is used by HAL to
11874 * add self sta. Remove this once self sta is added as
11875 * part of session open.
11876 */
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
11878 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
11879 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011880
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 if (!HAL_STATUS_SUCCESS( halStatus ))
11882 {
11883 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
11884 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011885 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011886 }
11887 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011888
11889 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
11890 Note: Firmware image will be read and downloaded inside vos_start API */
11891 status = vos_start( pHddCtx->pvosContext );
11892 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11893 {
11894 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053011895 if (isSsrPanicOnFailure())
11896 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011897 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011898 }
11899
Leo Chang6cec3e22014-01-21 15:33:49 -080011900#ifdef FEATURE_WLAN_CH_AVOID
11901 /* Plug in avoid channel notification callback
11902 * This should happen before ADD_SELF_STA
11903 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053011904
11905 /* check the Channel Avoidance is enabled */
11906 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
11907 {
11908 sme_AddChAvoidCallback(pHddCtx->hHal,
11909 hdd_hostapd_ch_avoid_cb);
11910 }
Leo Chang6cec3e22014-01-21 15:33:49 -080011911#endif /* FEATURE_WLAN_CH_AVOID */
11912
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011913 /* Exchange capability info between Host and FW and also get versioning info from FW */
11914 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011915
Agarwal Ashishad9281b2014-06-10 14:57:30 +053011916#ifdef CONFIG_ENABLE_LINUX_REG
11917 status = wlan_hdd_init_channels(pHddCtx);
11918 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11919 {
11920 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
11921 __func__);
11922 goto err_vosstop;
11923 }
11924#endif
11925
Jeff Johnson295189b2012-06-20 16:38:30 -070011926 status = hdd_post_voss_start_config( pHddCtx );
11927 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11928 {
11929 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
11930 __func__);
11931 goto err_vosstop;
11932 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011933
11934#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011935 wlan_hdd_cfg80211_update_reg_info( wiphy );
11936
11937 /* registration of wiphy dev with cfg80211 */
11938 if (0 > wlan_hdd_cfg80211_register(wiphy))
11939 {
11940 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11941 goto err_vosstop;
11942 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011943#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011944
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011945#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011946 /* registration of wiphy dev with cfg80211 */
11947 if (0 > wlan_hdd_cfg80211_register(wiphy))
11948 {
11949 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11950 goto err_vosstop;
11951 }
11952
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011953 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011954 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11955 {
11956 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
11957 __func__);
11958 goto err_unregister_wiphy;
11959 }
11960#endif
11961
c_hpothu4a298be2014-12-22 21:12:51 +053011962 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11963
Jeff Johnson295189b2012-06-20 16:38:30 -070011964 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11965 {
11966 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
11967 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11968 }
11969 else
11970 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011971 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
11972 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11973 if (pAdapter != NULL)
11974 {
Katya Nigama7d81d72014-11-12 12:44:34 +053011975 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070011976 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011977 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
11978 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
11979 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070011980
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011981 /* Generate the P2P Device Address. This consists of the device's
11982 * primary MAC address with the locally administered bit set.
11983 */
11984 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070011985 }
11986 else
11987 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011988 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
11989 if (p2p_dev_addr != NULL)
11990 {
11991 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
11992 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
11993 }
11994 else
11995 {
11996 hddLog(VOS_TRACE_LEVEL_FATAL,
11997 "%s: Failed to allocate mac_address for p2p_device",
11998 __func__);
11999 goto err_close_adapter;
12000 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012001 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012002
12003 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
12004 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
12005 if ( NULL == pP2pAdapter )
12006 {
12007 hddLog(VOS_TRACE_LEVEL_FATAL,
12008 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012009 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012010 goto err_close_adapter;
12011 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012012 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012013 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012014
12015 if( pAdapter == NULL )
12016 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
12018 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012020
Arif Hussain66559122013-11-21 10:11:40 -080012021 if (country_code)
12022 {
12023 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080012024 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080012025 hdd_checkandupdate_dfssetting(pAdapter, country_code);
12026#ifndef CONFIG_ENABLE_LINUX_REG
12027 hdd_checkandupdate_phymode(pAdapter, country_code);
12028#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080012029 ret = sme_ChangeCountryCode(pHddCtx->hHal,
12030 (void *)(tSmeChangeCountryCallback)
12031 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080012032 country_code,
12033 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012034 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080012035 if (eHAL_STATUS_SUCCESS == ret)
12036 {
Arif Hussaincb607082013-12-20 11:57:42 -080012037 ret = wait_for_completion_interruptible_timeout(
12038 &pAdapter->change_country_code,
12039 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
12040
12041 if (0 >= ret)
12042 {
12043 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12044 "%s: SME while setting country code timed out", __func__);
12045 }
Arif Hussain66559122013-11-21 10:11:40 -080012046 }
12047 else
12048 {
Arif Hussaincb607082013-12-20 11:57:42 -080012049 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12050 "%s: SME Change Country code from module param fail ret=%d",
12051 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080012052 }
12053 }
12054
Jeff Johnson295189b2012-06-20 16:38:30 -070012055#ifdef WLAN_BTAMP_FEATURE
12056 vStatus = WLANBAP_Open(pVosContext);
12057 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12058 {
12059 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12060 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012061 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012062 }
12063
12064 vStatus = BSL_Init(pVosContext);
12065 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12066 {
12067 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12068 "%s: Failed to Init BSL",__func__);
12069 goto err_bap_close;
12070 }
12071 vStatus = WLANBAP_Start(pVosContext);
12072 if (!VOS_IS_STATUS_SUCCESS(vStatus))
12073 {
12074 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12075 "%s: Failed to start TL",__func__);
12076 goto err_bap_close;
12077 }
12078
12079 pConfig = pHddCtx->cfg_ini;
12080 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
12081 status = WLANBAP_SetConfig(&btAmpConfig);
12082
12083#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070012084
Mihir Shete9c238772014-10-15 14:35:16 +053012085 /*
12086 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
12087 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
12088 * which is greater than 0xf. So the below check is safe to make
12089 * sure that there is no entry for UapsdMask in the ini
12090 */
12091 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
12092 {
12093 if(IS_DYNAMIC_WMM_PS_ENABLED)
12094 {
12095 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
12096 __func__);
12097 pHddCtx->cfg_ini->UapsdMask =
12098 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
12099 }
12100 else
12101 {
12102 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
12103 __func__);
12104 pHddCtx->cfg_ini->UapsdMask =
12105 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
12106 }
12107 }
12108
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070012109#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
12110 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
12111 {
12112 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
12113 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
12114 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
12115 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
12116 }
12117#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012118
Agarwal Ashish4b87f922014-06-18 03:03:21 +053012119 wlan_hdd_tdls_init(pHddCtx);
12120
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012121 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
12122
12123 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
12124 wlan_hdd_schedule_defer_scan);
12125
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012126 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
12127
Jeff Johnson295189b2012-06-20 16:38:30 -070012128 /* Register with platform driver as client for Suspend/Resume */
12129 status = hddRegisterPmOps(pHddCtx);
12130 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12131 {
12132 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
12133#ifdef WLAN_BTAMP_FEATURE
12134 goto err_bap_stop;
12135#else
Jeff Johnsone7245742012-09-05 17:12:55 -070012136 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012137#endif //WLAN_BTAMP_FEATURE
12138 }
12139
Yue Ma0d4891e2013-08-06 17:01:45 -070012140 /* Open debugfs interface */
12141 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
12142 {
12143 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12144 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070012145 }
12146
Jeff Johnson295189b2012-06-20 16:38:30 -070012147 /* Register TM level change handler function to the platform */
12148 status = hddDevTmRegisterNotifyCallback(pHddCtx);
12149 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12150 {
12151 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
12152 goto err_unregister_pmops;
12153 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012154
Jeff Johnson295189b2012-06-20 16:38:30 -070012155 // register net device notifier for device change notification
12156 ret = register_netdevice_notifier(&hdd_netdev_notifier);
12157
12158 if(ret < 0)
12159 {
12160 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012161 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070012162 }
12163
Jeff Johnson295189b2012-06-20 16:38:30 -070012164 //Initialize the BTC service
12165 if(btc_activate_service(pHddCtx) != 0)
12166 {
12167 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012168 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 }
12170
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012171#ifdef FEATURE_OEM_DATA_SUPPORT
12172 //Initialize the OEM service
12173 if (oem_activate_service(pHddCtx) != 0)
12174 {
12175 hddLog(VOS_TRACE_LEVEL_FATAL,
12176 "%s: oem_activate_service failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012177 goto err_reg_netdev;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012178 }
12179#endif
12180
Jeff Johnson295189b2012-06-20 16:38:30 -070012181#ifdef PTT_SOCK_SVC_ENABLE
12182 //Initialize the PTT service
12183 if(ptt_sock_activate_svc(pHddCtx) != 0)
12184 {
12185 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012186 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 }
12188#endif
12189
Abhishek Singh00b71972016-01-07 10:51:04 +053012190#ifdef WLAN_FEATURE_RMC
12191 if (hdd_open_cesium_nl_sock() < 0)
12192 {
12193 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
12194 goto err_reg_netdev;
12195 }
12196#endif
12197
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012198#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12199 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
12200 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053012201 if(wlan_logging_sock_activate_svc(
12202 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053012203 pHddCtx->cfg_ini->wlanLoggingNumBuf,
12204 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
12205 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053012206 {
12207 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
12208 " failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012209 goto err_reg_netdev;
Deepthi Gowri78083a32014-11-04 12:55:51 +053012210 }
12211 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
12212 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053012213 if (!pHddCtx->cfg_ini->gEnableDebugLog)
12214 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053012215 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
12216 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012217 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012218
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012219 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
12220 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053012221 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053012222 pHddCtx->cfg_ini->enableContFWLogging ||
12223 pHddCtx->cfg_ini->enableFwrMemDump )
12224 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012225 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012226 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012227 }
12228 else
12229 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012230 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012231 }
12232
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012233#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012234
12235
Sushant Kaushik215778f2015-05-21 14:05:36 +053012236 if (vos_is_multicast_logging())
12237 wlan_logging_set_log_level();
12238
Jeff Johnson295189b2012-06-20 16:38:30 -070012239 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012240 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070012241 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070012242 /* Action frame registered in one adapter which will
12243 * applicable to all interfaces
12244 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053012245 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012247
12248 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053012249 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012250
Jeff Johnsone7245742012-09-05 17:12:55 -070012251#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12252 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012253 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070012254 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012255
Jeff Johnsone7245742012-09-05 17:12:55 -070012256#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012257 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012258 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012259 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012260
Jeff Johnsone7245742012-09-05 17:12:55 -070012261
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012262 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
12263 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012264
Katya Nigam5c306ea2014-06-19 15:39:54 +053012265 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012266 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012267 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053012268
12269#ifdef FEATURE_WLAN_SCAN_PNO
12270 /*SME must send channel update configuration to RIVA*/
12271 sme_UpdateChannelConfig(pHddCtx->hHal);
12272#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053012273 /* Send the update default channel list to the FW*/
12274 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053012275
12276 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053012277 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
12278 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053012279 sme_SetDefDot11Mode(pHddCtx->hHal);
12280
Abhishek Singha306a442013-11-07 18:39:01 +053012281#ifndef CONFIG_ENABLE_LINUX_REG
12282 /*updating wiphy so that regulatory user hints can be processed*/
12283 if (wiphy)
12284 {
12285 regulatory_hint(wiphy, "00");
12286 }
12287#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012288 // Initialize the restart logic
12289 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053012290
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012291 //Register the traffic monitor timer now
12292 if ( pHddCtx->cfg_ini->dynSplitscan)
12293 {
12294 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
12295 VOS_TIMER_TYPE_SW,
12296 hdd_tx_rx_pkt_cnt_stat_timer_handler,
12297 (void *)pHddCtx);
12298 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053012299 wlan_hdd_cfg80211_nan_init(pHddCtx);
12300
Bhargav Shahd0715912015-10-01 18:17:37 +053012301 mutex_init(&pHddCtx->cur_rx_level_lock);
12302 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
12303 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012304 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
12305 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053012306
Dino Mycle6fb96c12014-06-10 11:52:40 +053012307#ifdef WLAN_FEATURE_EXTSCAN
12308 sme_EXTScanRegisterCallback(pHddCtx->hHal,
12309 wlan_hdd_cfg80211_extscan_callback,
12310 pHddCtx);
12311#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012312
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053012313#ifdef FEATURE_OEM_DATA_SUPPORT
12314 sme_OemDataRegisterCallback(pHddCtx->hHal,
12315 wlan_hdd_cfg80211_oemdata_callback,
12316 pHddCtx);
12317#endif /* FEATURE_OEM_DATA_SUPPORT */
12318
Gupta, Kapil7c34b322015-09-30 13:12:35 +053012319 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012320#ifdef WLAN_NS_OFFLOAD
12321 // Register IPv6 notifier to notify if any change in IP
12322 // So that we can reconfigure the offload parameters
12323 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
12324 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12325 if (ret)
12326 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012328 }
12329 else
12330 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012331 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012332 }
12333#endif
12334
12335 // Register IPv4 notifier to notify if any change in IP
12336 // So that we can reconfigure the offload parameters
12337 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
12338 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12339 if (ret)
12340 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012341 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012342 }
12343 else
12344 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012345 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012346 }
c_manjeecfd1efb2015-09-25 19:32:34 +053012347 /*Fw mem dump procfs initialization*/
12348 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053012349 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012350
Jeff Johnson295189b2012-06-20 16:38:30 -070012351 goto success;
12352
Jeff Johnson295189b2012-06-20 16:38:30 -070012353err_reg_netdev:
12354 unregister_netdevice_notifier(&hdd_netdev_notifier);
12355
Jeff Johnson295189b2012-06-20 16:38:30 -070012356err_unregister_pmops:
12357 hddDevTmUnregisterNotifyCallback(pHddCtx);
12358 hddDeregisterPmOps(pHddCtx);
12359
Yue Ma0d4891e2013-08-06 17:01:45 -070012360 hdd_debugfs_exit(pHddCtx);
12361
Jeff Johnson295189b2012-06-20 16:38:30 -070012362#ifdef WLAN_BTAMP_FEATURE
12363err_bap_stop:
12364 WLANBAP_Stop(pVosContext);
12365#endif
12366
12367#ifdef WLAN_BTAMP_FEATURE
12368err_bap_close:
12369 WLANBAP_Close(pVosContext);
12370#endif
12371
Jeff Johnson295189b2012-06-20 16:38:30 -070012372err_close_adapter:
12373 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012374#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012375err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012376#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012377 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012378 hdd_wlan_free_wiphy_channels(wiphy);
12379
Jeff Johnson295189b2012-06-20 16:38:30 -070012380err_vosstop:
12381 vos_stop(pVosContext);
12382
Amar Singhala49cbc52013-10-08 18:37:44 -070012383err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070012384 status = vos_sched_close( pVosContext );
12385 if (!VOS_IS_STATUS_SUCCESS(status)) {
12386 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12387 "%s: Failed to close VOSS Scheduler", __func__);
12388 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
12389 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012390 vos_close(pVosContext );
12391
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012392err_nl_srv:
12393#ifdef WLAN_KD_READY_NOTIFIER
12394 nl_srv_exit(pHddCtx->ptt_pid);
12395#else
12396 nl_srv_exit();
12397#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070012398err_vos_nv_close:
12399
c_hpothue6a36282014-03-19 12:27:38 +053012400#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070012401 vos_nv_close();
12402
c_hpothu70f8d812014-03-22 22:59:23 +053012403#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012404
12405err_wdclose:
12406 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12407 vos_watchdog_close(pVosContext);
12408
Jeff Johnson295189b2012-06-20 16:38:30 -070012409err_config:
12410 kfree(pHddCtx->cfg_ini);
12411 pHddCtx->cfg_ini= NULL;
12412
12413err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012414 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012415 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012416 wiphy_free(wiphy) ;
12417 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 VOS_BUG(1);
12419
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080012420 if (hdd_is_ssr_required())
12421 {
12422 /* WDI timeout had happened during load, so SSR is needed here */
12423 subsystem_restart("wcnss");
12424 msleep(5000);
12425 }
12426 hdd_set_ssr_required (VOS_FALSE);
12427
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012428 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012429
12430success:
12431 EXIT();
12432 return 0;
12433}
12434
12435/**---------------------------------------------------------------------------
12436
Jeff Johnson32d95a32012-09-10 13:15:23 -070012437 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070012438
Jeff Johnson32d95a32012-09-10 13:15:23 -070012439 This is the driver entry point - called in different timeline depending
12440 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070012441
12442 \param - None
12443
12444 \return - 0 for success, non zero for failure
12445
12446 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070012447static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012448{
12449 VOS_STATUS status;
12450 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012451 struct device *dev = NULL;
12452 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012453#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12454 int max_retries = 0;
12455#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012456#ifdef HAVE_CBC_DONE
12457 int max_cbc_retries = 0;
12458#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012459
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012460#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12461 wlan_logging_sock_init_svc();
12462#endif
12463
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 ENTER();
12465
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012466 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012467
12468 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
12469 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
12470
Jeff Johnson295189b2012-06-20 16:38:30 -070012471#ifdef ANI_BUS_TYPE_PCI
12472
12473 dev = wcnss_wlan_get_device();
12474
12475#endif // ANI_BUS_TYPE_PCI
12476
12477#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012478
12479#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12480 /* wait until WCNSS driver downloads NV */
12481 while (!wcnss_device_ready() && 5 >= ++max_retries) {
12482 msleep(1000);
12483 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012484
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012485 if (max_retries >= 5) {
12486 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012487 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012488#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12489 wlan_logging_sock_deinit_svc();
12490#endif
12491
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012492 return -ENODEV;
12493 }
12494#endif
12495
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012496#ifdef HAVE_CBC_DONE
12497 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
12498 msleep(1000);
12499 }
12500 if (max_cbc_retries >= 10) {
12501 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
12502 }
12503#endif
12504
Jeff Johnson295189b2012-06-20 16:38:30 -070012505 dev = wcnss_wlan_get_device();
12506#endif // ANI_BUS_TYPE_PLATFORM
12507
12508
12509 do {
12510 if (NULL == dev) {
12511 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
12512 ret_status = -1;
12513 break;
12514 }
12515
Jeff Johnson295189b2012-06-20 16:38:30 -070012516#ifdef TIMER_MANAGER
12517 vos_timer_manager_init();
12518#endif
12519
12520 /* Preopen VOSS so that it is ready to start at least SAL */
12521 status = vos_preOpen(&pVosContext);
12522
12523 if (!VOS_IS_STATUS_SUCCESS(status))
12524 {
12525 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
12526 ret_status = -1;
12527 break;
12528 }
12529
Sushant Kaushik02beb352015-06-04 15:15:01 +053012530 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053012531 hdd_register_debug_callback();
12532
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012533#ifndef MODULE
12534 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
12535 */
12536 hdd_set_conparam((v_UINT_t)con_mode);
12537#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012538
12539 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012540 if (hdd_wlan_startup(dev))
12541 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012543 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 vos_preClose( &pVosContext );
12545 ret_status = -1;
12546 break;
12547 }
12548
Jeff Johnson295189b2012-06-20 16:38:30 -070012549 } while (0);
12550
12551 if (0 != ret_status)
12552 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012553#ifdef TIMER_MANAGER
12554 vos_timer_exit();
12555#endif
12556#ifdef MEMORY_DEBUG
12557 vos_mem_exit();
12558#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012559 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012560#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12561 wlan_logging_sock_deinit_svc();
12562#endif
12563
Jeff Johnson295189b2012-06-20 16:38:30 -070012564 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
12565 }
12566 else
12567 {
12568 //Send WLAN UP indication to Nlink Service
12569 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
12570
12571 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070012572 }
12573
12574 EXIT();
12575
12576 return ret_status;
12577}
12578
Jeff Johnson32d95a32012-09-10 13:15:23 -070012579/**---------------------------------------------------------------------------
12580
12581 \brief hdd_module_init() - Init Function
12582
12583 This is the driver entry point (invoked when module is loaded using insmod)
12584
12585 \param - None
12586
12587 \return - 0 for success, non zero for failure
12588
12589 --------------------------------------------------------------------------*/
12590#ifdef MODULE
12591static int __init hdd_module_init ( void)
12592{
12593 return hdd_driver_init();
12594}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012595#else /* #ifdef MODULE */
12596static int __init hdd_module_init ( void)
12597{
12598 /* Driver initialization is delayed to fwpath_changed_handler */
12599 return 0;
12600}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012601#endif /* #ifdef MODULE */
12602
Jeff Johnson295189b2012-06-20 16:38:30 -070012603
12604/**---------------------------------------------------------------------------
12605
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012606 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070012607
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012608 This is the driver exit point (invoked when module is unloaded using rmmod
12609 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070012610
12611 \param - None
12612
12613 \return - None
12614
12615 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012616static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012617{
12618 hdd_context_t *pHddCtx = NULL;
12619 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053012620 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053012621 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012622
12623 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
12624
12625 //Get the global vos context
12626 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12627
12628 if(!pVosContext)
12629 {
12630 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
12631 goto done;
12632 }
12633
12634 //Get the HDD context.
12635 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
12636
12637 if(!pHddCtx)
12638 {
12639 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
12640 }
Katya Nigame7b69a82015-04-28 15:24:06 +053012641 else if (VOS_MONITOR_MODE == hdd_get_conparam())
12642 {
12643 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
12644 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12645 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
12646 hdd_wlan_exit(pHddCtx);
12647 vos_preClose( &pVosContext );
12648 goto done;
12649 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 else
12651 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053012652 /* We wait for active entry threads to exit from driver
12653 * by waiting until rtnl_lock is available.
12654 */
12655 rtnl_lock();
12656 rtnl_unlock();
12657
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012658 INIT_COMPLETION(pHddCtx->ssr_comp_var);
12659 if ((pHddCtx->isLogpInProgress) && (FALSE ==
12660 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
12661 {
Siddharth Bhala204f572015-01-17 02:03:36 +053012662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012663 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053012664 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
12665 msecs_to_jiffies(30000));
12666 if(!rc)
12667 {
12668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12669 "%s:SSR timedout, fatal error", __func__);
12670 VOS_BUG(0);
12671 }
12672 }
12673
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012674 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12675 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012676
c_hpothu8adb97b2014-12-08 19:38:20 +053012677 /* Driver Need to send country code 00 in below condition
12678 * 1) If gCountryCodePriority is set to 1; and last country
12679 * code set is through 11d. This needs to be done in case
12680 * when NV country code is 00.
12681 * This Needs to be done as when kernel store last country
12682 * code and if stored country code is not through 11d,
12683 * in sme_HandleChangeCountryCodeByUser we will disable 11d
12684 * in next load/unload as soon as we get any country through
12685 * 11d. In sme_HandleChangeCountryCodeByUser
12686 * pMsg->countryCode will be last countryCode and
12687 * pMac->scan.countryCode11d will be country through 11d so
12688 * due to mismatch driver will disable 11d.
12689 *
12690 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053012691
c_hpothu8adb97b2014-12-08 19:38:20 +053012692 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012693 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053012694 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053012695 {
12696 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012697 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053012698 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
12699 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053012700
c_hpothu8adb97b2014-12-08 19:38:20 +053012701 //Do all the cleanup before deregistering the driver
12702 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012703 }
12704
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 vos_preClose( &pVosContext );
12706
12707#ifdef TIMER_MANAGER
12708 vos_timer_exit();
12709#endif
12710#ifdef MEMORY_DEBUG
12711 vos_mem_exit();
12712#endif
12713
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012714#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12715 wlan_logging_sock_deinit_svc();
12716#endif
12717
Jeff Johnson295189b2012-06-20 16:38:30 -070012718done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012719 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012720
Jeff Johnson295189b2012-06-20 16:38:30 -070012721 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
12722}
12723
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012724/**---------------------------------------------------------------------------
12725
12726 \brief hdd_module_exit() - Exit function
12727
12728 This is the driver exit point (invoked when module is unloaded using rmmod)
12729
12730 \param - None
12731
12732 \return - None
12733
12734 --------------------------------------------------------------------------*/
12735static void __exit hdd_module_exit(void)
12736{
12737 hdd_driver_exit();
12738}
12739
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012740#ifdef MODULE
12741static int fwpath_changed_handler(const char *kmessage,
12742 struct kernel_param *kp)
12743{
Jeff Johnson76052702013-04-16 13:55:05 -070012744 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012745}
12746
12747static int con_mode_handler(const char *kmessage,
12748 struct kernel_param *kp)
12749{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070012750 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012751}
12752#else /* #ifdef MODULE */
12753/**---------------------------------------------------------------------------
12754
Jeff Johnson76052702013-04-16 13:55:05 -070012755 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012756
Jeff Johnson76052702013-04-16 13:55:05 -070012757 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012758 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070012759 - invoked when module parameter fwpath is modified from userspace to signal
12760 initializing the WLAN driver or when con_mode is modified from userspace
12761 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012762
12763 \return - 0 for success, non zero for failure
12764
12765 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012766static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012767{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012768 int ret_status;
12769
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012770 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012771 ret_status = hdd_driver_init();
12772 wlan_hdd_inited = ret_status ? 0 : 1;
12773 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012774 }
12775
12776 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070012777
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012778 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070012779
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012780 ret_status = hdd_driver_init();
12781 wlan_hdd_inited = ret_status ? 0 : 1;
12782 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012783}
12784
Jeff Johnson295189b2012-06-20 16:38:30 -070012785/**---------------------------------------------------------------------------
12786
Jeff Johnson76052702013-04-16 13:55:05 -070012787 \brief fwpath_changed_handler() - Handler Function
12788
12789 Handle changes to the fwpath parameter
12790
12791 \return - 0 for success, non zero for failure
12792
12793 --------------------------------------------------------------------------*/
12794static int fwpath_changed_handler(const char *kmessage,
12795 struct kernel_param *kp)
12796{
12797 int ret;
12798
12799 ret = param_set_copystring(kmessage, kp);
12800 if (0 == ret)
12801 ret = kickstart_driver();
12802 return ret;
12803}
12804
12805/**---------------------------------------------------------------------------
12806
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012807 \brief con_mode_handler() -
12808
12809 Handler function for module param con_mode when it is changed by userspace
12810 Dynamically linked - do nothing
12811 Statically linked - exit and init driver, as in rmmod and insmod
12812
Jeff Johnson76052702013-04-16 13:55:05 -070012813 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012814
Jeff Johnson76052702013-04-16 13:55:05 -070012815 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012816
12817 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012818static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012819{
Jeff Johnson76052702013-04-16 13:55:05 -070012820 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012821
Jeff Johnson76052702013-04-16 13:55:05 -070012822 ret = param_set_int(kmessage, kp);
12823 if (0 == ret)
12824 ret = kickstart_driver();
12825 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012826}
12827#endif /* #ifdef MODULE */
12828
12829/**---------------------------------------------------------------------------
12830
Jeff Johnson295189b2012-06-20 16:38:30 -070012831 \brief hdd_get_conparam() -
12832
12833 This is the driver exit point (invoked when module is unloaded using rmmod)
12834
12835 \param - None
12836
12837 \return - tVOS_CON_MODE
12838
12839 --------------------------------------------------------------------------*/
12840tVOS_CON_MODE hdd_get_conparam ( void )
12841{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012842#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070012843 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012844#else
12845 return (tVOS_CON_MODE)curr_con_mode;
12846#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012847}
12848void hdd_set_conparam ( v_UINT_t newParam )
12849{
12850 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012851#ifndef MODULE
12852 curr_con_mode = con_mode;
12853#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012854}
12855/**---------------------------------------------------------------------------
12856
12857 \brief hdd_softap_sta_deauth() - function
12858
12859 This to take counter measure to handle deauth req from HDD
12860
12861 \param - pAdapter - Pointer to the HDD
12862
12863 \param - enable - boolean value
12864
12865 \return - None
12866
12867 --------------------------------------------------------------------------*/
12868
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012869VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
12870 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012871{
Jeff Johnson295189b2012-06-20 16:38:30 -070012872 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012873 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070012874
12875 ENTER();
12876
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012877 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
12878 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012879
12880 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012881 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012882 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012883
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012884 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070012885
12886 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012887 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012888}
12889
12890/**---------------------------------------------------------------------------
12891
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012892 \brief hdd_del_all_sta() - function
12893
12894 This function removes all the stations associated on stopping AP/P2P GO.
12895
12896 \param - pAdapter - Pointer to the HDD
12897
12898 \return - None
12899
12900 --------------------------------------------------------------------------*/
12901
12902int hdd_del_all_sta(hdd_adapter_t *pAdapter)
12903{
12904 v_U16_t i;
12905 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012906 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12907 ptSapContext pSapCtx = NULL;
12908 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12909 if(pSapCtx == NULL){
12910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12911 FL("psapCtx is NULL"));
12912 return 1;
12913 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012914 ENTER();
12915
12916 hddLog(VOS_TRACE_LEVEL_INFO,
12917 "%s: Delete all STAs associated.",__func__);
12918 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12919 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
12920 )
12921 {
12922 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12923 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012924 if ((pSapCtx->aStaInfo[i].isUsed) &&
12925 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012926 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012927 struct tagCsrDelStaParams delStaParams;
12928
12929 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012930 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053012931 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
12932 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012933 &delStaParams);
12934 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012935 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012936 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012937 }
12938 }
12939 }
12940
12941 EXIT();
12942 return 0;
12943}
12944
12945/**---------------------------------------------------------------------------
12946
Jeff Johnson295189b2012-06-20 16:38:30 -070012947 \brief hdd_softap_sta_disassoc() - function
12948
12949 This to take counter measure to handle deauth req from HDD
12950
12951 \param - pAdapter - Pointer to the HDD
12952
12953 \param - enable - boolean value
12954
12955 \return - None
12956
12957 --------------------------------------------------------------------------*/
12958
12959void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
12960{
12961 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12962
12963 ENTER();
12964
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012965 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012966
12967 //Ignore request to disassoc bcmc station
12968 if( pDestMacAddress[0] & 0x1 )
12969 return;
12970
12971 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
12972}
12973
12974void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
12975{
12976 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12977
12978 ENTER();
12979
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012980 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012981
12982 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
12983}
12984
Jeff Johnson295189b2012-06-20 16:38:30 -070012985/**---------------------------------------------------------------------------
12986 *
12987 * \brief hdd_get__concurrency_mode() -
12988 *
12989 *
12990 * \param - None
12991 *
12992 * \return - CONCURRENCY MODE
12993 *
12994 * --------------------------------------------------------------------------*/
12995tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
12996{
12997 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
12998 hdd_context_t *pHddCtx;
12999
13000 if (NULL != pVosContext)
13001 {
13002 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
13003 if (NULL != pHddCtx)
13004 {
13005 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
13006 }
13007 }
13008
13009 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013010 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 return VOS_STA;
13012}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013013v_BOOL_t
13014wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
13015{
13016 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013017
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013018 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
13019 if (pAdapter == NULL)
13020 {
13021 hddLog(VOS_TRACE_LEVEL_INFO,
13022 FL("GO doesn't exist"));
13023 return TRUE;
13024 }
13025 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
13026 {
13027 hddLog(VOS_TRACE_LEVEL_INFO,
13028 FL("GO started"));
13029 return TRUE;
13030 }
13031 else
13032 /* wait till GO changes its interface to p2p device */
13033 hddLog(VOS_TRACE_LEVEL_INFO,
13034 FL("Del_bss called, avoid apps suspend"));
13035 return FALSE;
13036
13037}
Jeff Johnson295189b2012-06-20 16:38:30 -070013038/* Decide whether to allow/not the apps power collapse.
13039 * Allow apps power collapse if we are in connected state.
13040 * if not, allow only if we are in IMPS */
13041v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
13042{
13043 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080013044 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013045 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070013046 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13047 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13048 hdd_adapter_t *pAdapter = NULL;
13049 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080013050 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013051
Jeff Johnson295189b2012-06-20 16:38:30 -070013052 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13053 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013054
Yathish9f22e662012-12-10 14:21:35 -080013055 concurrent_state = hdd_get_concurrency_mode();
13056
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013057 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
13058 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
13059 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080013060#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013061
Yathish9f22e662012-12-10 14:21:35 -080013062 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013063 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080013064 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
13065 return TRUE;
13066#endif
13067
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 /*loop through all adapters. TBD fix for Concurrency */
13069 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13070 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13071 {
13072 pAdapter = pAdapterNode->pAdapter;
13073 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13074 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13075 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080013076 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053013077 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053013078 && pmcState != STOPPED && pmcState != STANDBY &&
13079 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013080 (eANI_BOOLEAN_TRUE == scanRspPending) ||
13081 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 {
Mukul Sharma4be88422015-03-09 20:29:07 +053013083 if(pmcState == FULL_POWER &&
13084 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
13085 {
13086 /*
13087 * When SCO indication comes from Coex module , host will
13088 * enter in to full power mode, but this should not prevent
13089 * apps processor power collapse.
13090 */
13091 hddLog(LOG1,
13092 FL("Allow apps power collapse"
13093 "even when sco indication is set"));
13094 return TRUE;
13095 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080013096 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013097 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
13098 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070013099 return FALSE;
13100 }
13101 }
13102 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13103 pAdapterNode = pNext;
13104 }
13105 return TRUE;
13106}
13107
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080013108/* Decides whether to send suspend notification to Riva
13109 * if any adapter is in BMPS; then it is required */
13110v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
13111{
13112 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
13113 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13114
13115 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
13116 {
13117 return TRUE;
13118 }
13119 return FALSE;
13120}
13121
Jeff Johnson295189b2012-06-20 16:38:30 -070013122void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13123{
13124 switch(mode)
13125 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013126 case VOS_STA_MODE:
13127 case VOS_P2P_CLIENT_MODE:
13128 case VOS_P2P_GO_MODE:
13129 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070013130 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013131 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070013132 break;
13133 default:
13134 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070013135 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013136 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13137 "Number of open sessions for mode %d = %d"),
13138 pHddCtx->concurrency_mode, mode,
13139 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013140}
13141
13142
13143void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13144{
13145 switch(mode)
13146 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013147 case VOS_STA_MODE:
13148 case VOS_P2P_CLIENT_MODE:
13149 case VOS_P2P_GO_MODE:
13150 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053013151 pHddCtx->no_of_open_sessions[mode]--;
13152 if (!(pHddCtx->no_of_open_sessions[mode]))
13153 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013154 break;
13155 default:
13156 break;
13157 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013158 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13159 "Number of open sessions for mode %d = %d"),
13160 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
13161
13162}
13163/**---------------------------------------------------------------------------
13164 *
13165 * \brief wlan_hdd_incr_active_session()
13166 *
13167 * This function increments the number of active sessions
13168 * maintained per device mode
13169 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
13170 * Incase of SAP/P2P GO upon bss start it is incremented
13171 *
13172 * \param pHddCtx - HDD Context
13173 * \param mode - device mode
13174 *
13175 * \return - None
13176 *
13177 * --------------------------------------------------------------------------*/
13178void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13179{
13180 switch (mode) {
13181 case VOS_STA_MODE:
13182 case VOS_P2P_CLIENT_MODE:
13183 case VOS_P2P_GO_MODE:
13184 case VOS_STA_SAP_MODE:
13185 pHddCtx->no_of_active_sessions[mode]++;
13186 break;
13187 default:
13188 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13189 break;
13190 }
13191 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13192 mode,
13193 pHddCtx->no_of_active_sessions[mode]);
13194}
13195
13196/**---------------------------------------------------------------------------
13197 *
13198 * \brief wlan_hdd_decr_active_session()
13199 *
13200 * This function decrements the number of active sessions
13201 * maintained per device mode
13202 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
13203 * Incase of SAP/P2P GO upon bss stop it is decremented
13204 *
13205 * \param pHddCtx - HDD Context
13206 * \param mode - device mode
13207 *
13208 * \return - None
13209 *
13210 * --------------------------------------------------------------------------*/
13211void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13212{
Bhargav Shahd0715912015-10-01 18:17:37 +053013213
Agarwal Ashish51325b52014-06-16 16:50:49 +053013214 switch (mode) {
13215 case VOS_STA_MODE:
13216 case VOS_P2P_CLIENT_MODE:
13217 case VOS_P2P_GO_MODE:
13218 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053013219 if (pHddCtx->no_of_active_sessions[mode] > 0)
13220 pHddCtx->no_of_active_sessions[mode]--;
13221 else
13222 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
13223 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053013224 break;
13225 default:
13226 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13227 break;
13228 }
13229 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13230 mode,
13231 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013232}
13233
Jeff Johnsone7245742012-09-05 17:12:55 -070013234/**---------------------------------------------------------------------------
13235 *
13236 * \brief wlan_hdd_restart_init
13237 *
13238 * This function initalizes restart timer/flag. An internal function.
13239 *
13240 * \param - pHddCtx
13241 *
13242 * \return - None
13243 *
13244 * --------------------------------------------------------------------------*/
13245
13246static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
13247{
13248 /* Initialize */
13249 pHddCtx->hdd_restart_retries = 0;
13250 atomic_set(&pHddCtx->isRestartInProgress, 0);
13251 vos_timer_init(&pHddCtx->hdd_restart_timer,
13252 VOS_TIMER_TYPE_SW,
13253 wlan_hdd_restart_timer_cb,
13254 pHddCtx);
13255}
13256/**---------------------------------------------------------------------------
13257 *
13258 * \brief wlan_hdd_restart_deinit
13259 *
13260 * This function cleans up the resources used. An internal function.
13261 *
13262 * \param - pHddCtx
13263 *
13264 * \return - None
13265 *
13266 * --------------------------------------------------------------------------*/
13267
13268static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
13269{
13270
13271 VOS_STATUS vos_status;
13272 /* Block any further calls */
13273 atomic_set(&pHddCtx->isRestartInProgress, 1);
13274 /* Cleanup */
13275 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
13276 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013277 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013278 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
13279 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013280 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013281
13282}
13283
13284/**---------------------------------------------------------------------------
13285 *
13286 * \brief wlan_hdd_framework_restart
13287 *
13288 * This function uses a cfg80211 API to start a framework initiated WLAN
13289 * driver module unload/load.
13290 *
13291 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
13292 *
13293 *
13294 * \param - pHddCtx
13295 *
13296 * \return - VOS_STATUS_SUCCESS: Success
13297 * VOS_STATUS_E_EMPTY: Adapter is Empty
13298 * VOS_STATUS_E_NOMEM: No memory
13299
13300 * --------------------------------------------------------------------------*/
13301
13302static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
13303{
13304 VOS_STATUS status = VOS_STATUS_SUCCESS;
13305 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013306 int len = (sizeof (struct ieee80211_mgmt));
13307 struct ieee80211_mgmt *mgmt = NULL;
13308
13309 /* Prepare the DEAUTH managment frame with reason code */
13310 mgmt = kzalloc(len, GFP_KERNEL);
13311 if(mgmt == NULL)
13312 {
13313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13314 "%s: memory allocation failed (%d bytes)", __func__, len);
13315 return VOS_STATUS_E_NOMEM;
13316 }
13317 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070013318
13319 /* Iterate over all adapters/devices */
13320 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013321 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
13322 {
13323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13324 FL("fail to get adapter: %p %d"), pAdapterNode, status);
13325 goto end;
13326 }
13327
Jeff Johnsone7245742012-09-05 17:12:55 -070013328 do
13329 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013330 if(pAdapterNode->pAdapter &&
13331 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070013332 {
13333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13334 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
13335 pAdapterNode->pAdapter->dev->name,
13336 pAdapterNode->pAdapter->device_mode,
13337 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013338 /*
13339 * CFG80211 event to restart the driver
13340 *
13341 * 'cfg80211_send_unprot_deauth' sends a
13342 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
13343 * of SME(Linux Kernel) state machine.
13344 *
13345 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
13346 * the driver.
13347 *
13348 */
Abhishek Singh00b71972016-01-07 10:51:04 +053013349
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013350#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
13351 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
13352#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013353 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013354#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013355 }
13356 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13357 pAdapterNode = pNext;
13358 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
13359
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013360 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013361 /* Free the allocated management frame */
13362 kfree(mgmt);
13363
Jeff Johnsone7245742012-09-05 17:12:55 -070013364 /* Retry until we unload or reach max count */
13365 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
13366 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
13367
13368 return status;
13369
13370}
13371/**---------------------------------------------------------------------------
13372 *
13373 * \brief wlan_hdd_restart_timer_cb
13374 *
13375 * Restart timer callback. An internal function.
13376 *
13377 * \param - User data:
13378 *
13379 * \return - None
13380 *
13381 * --------------------------------------------------------------------------*/
13382
13383void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
13384{
13385 hdd_context_t *pHddCtx = usrDataForCallback;
13386 wlan_hdd_framework_restart(pHddCtx);
13387 return;
13388
13389}
13390
13391
13392/**---------------------------------------------------------------------------
13393 *
13394 * \brief wlan_hdd_restart_driver
13395 *
13396 * This function sends an event to supplicant to restart the WLAN driver.
13397 *
13398 * This function is called from vos_wlanRestart.
13399 *
13400 * \param - pHddCtx
13401 *
13402 * \return - VOS_STATUS_SUCCESS: Success
13403 * VOS_STATUS_E_EMPTY: Adapter is Empty
13404 * VOS_STATUS_E_ALREADY: Request already in progress
13405
13406 * --------------------------------------------------------------------------*/
13407VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
13408{
13409 VOS_STATUS status = VOS_STATUS_SUCCESS;
13410
13411 /* A tight check to make sure reentrancy */
13412 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
13413 {
Mihir Shetefd528652014-06-23 19:07:50 +053013414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070013415 "%s: WLAN restart is already in progress", __func__);
13416
13417 return VOS_STATUS_E_ALREADY;
13418 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070013419 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080013420#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053013421 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070013422#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070013423
Jeff Johnsone7245742012-09-05 17:12:55 -070013424 return status;
13425}
13426
Bhargav Shahd0715912015-10-01 18:17:37 +053013427/**
13428 * hdd_get_total_sessions() - provide total number of active sessions
13429 * @pHddCtx: Valid Global HDD context pointer
13430 *
13431 * This function iterates through pAdaptors and find the number of all active
13432 * sessions. This active sessions includes connected sta, p2p client and number
13433 * of client connected to sap/p2p go.
13434 *
13435 * Return: Total number of active sessions.
13436 */
13437v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
13438{
13439 v_U8_t active_session = 0;
13440 hdd_station_ctx_t *pHddStaCtx;
13441 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13442 hdd_adapter_t *pAdapter;
13443 VOS_STATUS status;
13444
13445 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13446 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13447 pAdapter = pAdapterNode->pAdapter;
13448 switch (pAdapter->device_mode) {
13449 case VOS_STA_MODE:
13450 case VOS_P2P_CLIENT_MODE:
13451 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13452 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13453 active_session += 1;
13454 break;
13455 case VOS_STA_SAP_MODE:
13456 case VOS_P2P_GO_MODE:
13457 active_session += hdd_softap_get_connected_sta(pAdapter);
13458 break;
13459 default:
13460 break;
13461 }
13462
13463 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
13464 pAdapterNode = pNext;
13465 }
13466
13467 return active_session;
13468}
13469
13470/**
13471 * hdd_set_delack_value() - Set delack value
13472 * @pHddCtx: Valid Global HDD context pointer
13473 * @next_rx_level: Value to set for delack
13474 *
13475 * This function compare present value and next value of delack. If the both
13476 * are diffrent then it sets next value .
13477 *
13478 * Return: void.
13479 */
13480void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
13481{
13482 if (pHddCtx->cur_rx_level != next_rx_level) {
13483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13484 "%s: TCP DELACK trigger level %d",
13485 __func__, next_rx_level);
13486 mutex_lock(&pHddCtx->cur_rx_level_lock);
13487 pHddCtx->cur_rx_level = next_rx_level;
13488 mutex_unlock(&pHddCtx->cur_rx_level_lock);
13489 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
13490 sizeof(next_rx_level));
13491 }
13492}
13493
13494/**
13495 * hdd_set_default_stop_delack_timer() - Start delack timer
13496 * @pHddCtx: Valid Global HDD context pointer
13497 *
13498 * This function stop delack timer and set delack value to default..
13499 *
13500 * Return: void.
13501 */
13502
13503void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
13504{
13505 if (VOS_TIMER_STATE_RUNNING !=
13506 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13508 "%s: Can not stop timer", __func__);
13509 return;
13510 }
13511
13512 vos_timer_stop(&pHddCtx->delack_timer);
13513 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
13514}
13515
13516/**
13517 * hdd_start_delack_timer() - Start delack timer
13518 * @pHddCtx: Valid Global HDD context pointer
13519 *
13520 * This function starts the delack timer for tcpDelAckComputeInterval time
13521 * interval.The default timer value is 2 second.
13522 *
13523 * Return: void.
13524 */
13525void hdd_start_delack_timer(hdd_context_t *pHddCtx)
13526{
13527 if (VOS_TIMER_STATE_RUNNING ==
13528 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13530 "%s: Timer is already running", __func__);
13531 return;
13532 }
13533
13534 vos_timer_start(&pHddCtx->delack_timer,
13535 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13536}
13537
13538/**
13539 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
13540 * @pHddCtx: Valid Global HDD context pointer
13541 *
13542 * This function updates the prev_rx_packets count from the corresponding
13543 * pAdapter states. This prev_rx_packets will diffed with the packet count
13544 * at the end of delack timer. That can give number of RX packet is spacific
13545 * time.
13546 *
13547 * Return: void.
13548 */
13549void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
13550{
13551 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13552 hdd_adapter_t *pAdapter;
13553 VOS_STATUS status;
13554
13555 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13556 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13557 pAdapter = pAdapterNode->pAdapter;
13558 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
13559 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13560 pAdapterNode = pNext;
13561 }
13562}
13563
13564/**
13565 * hdd_manage_delack_timer() - start\stop delack timer
13566 * @pHddCtx: Valid Global HDD context pointer
13567 *
13568 * This function check the number of concerent session present, it starts the
13569 * delack timer if only one session is present.
13570 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
13571 *
13572 * Return: void.
13573 */
13574void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
13575{
13576 uint8_t sessions;
13577
13578 if (!pHddCtx->cfg_ini->enable_delack) {
13579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13580 "%s: TCP DELACK is not enabled", __func__);
13581 return;
13582 }
13583
13584 /* Blindly stop timer of BTCOEX and TDLS Session is up */
13585 if (pHddCtx->mode != 0) {
13586 hdd_set_default_stop_delack_timer(pHddCtx);
13587 return;
13588 }
13589
13590 sessions = hdd_get_total_sessions(pHddCtx);
13591 if (sessions == 1) {
13592 hdd_update_prev_rx_packet_count(pHddCtx);
13593 hdd_start_delack_timer(pHddCtx);
13594 } else {
13595 hdd_set_default_stop_delack_timer(pHddCtx);
13596 }
13597}
13598
Mihir Shetee1093ba2014-01-21 20:13:32 +053013599/**---------------------------------------------------------------------------
13600 *
13601 * \brief wlan_hdd_init_channels
13602 *
13603 * This function is used to initialize the channel list in CSR
13604 *
13605 * This function is called from hdd_wlan_startup
13606 *
13607 * \param - pHddCtx: HDD context
13608 *
13609 * \return - VOS_STATUS_SUCCESS: Success
13610 * VOS_STATUS_E_FAULT: Failure reported by SME
13611
13612 * --------------------------------------------------------------------------*/
13613static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
13614{
13615 eHalStatus status;
13616
13617 status = sme_InitChannels(pHddCtx->hHal);
13618 if (HAL_STATUS_SUCCESS(status))
13619 {
13620 return VOS_STATUS_SUCCESS;
13621 }
13622 else
13623 {
13624 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
13625 __func__, status);
13626 return VOS_STATUS_E_FAULT;
13627 }
13628}
13629
Mihir Shete04206452014-11-20 17:50:58 +053013630#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013631VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013632{
13633 eHalStatus status;
13634
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013635 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013636 if (HAL_STATUS_SUCCESS(status))
13637 {
13638 return VOS_STATUS_SUCCESS;
13639 }
13640 else
13641 {
13642 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
13643 __func__, status);
13644 return VOS_STATUS_E_FAULT;
13645 }
13646}
Mihir Shete04206452014-11-20 17:50:58 +053013647#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070013648/*
13649 * API to find if there is any STA or P2P-Client is connected
13650 */
13651VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
13652{
13653 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
13654}
Jeff Johnsone7245742012-09-05 17:12:55 -070013655
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013656
13657/*
13658 * API to find if the firmware will send logs using DXE channel
13659 */
13660v_U8_t hdd_is_fw_logging_enabled(void)
13661{
13662 hdd_context_t *pHddCtx;
13663
13664 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13665 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13666
Sachin Ahuja084313e2015-05-21 17:57:10 +053013667 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013668}
13669
Agarwal Ashish57e84372014-12-05 18:26:53 +053013670/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053013671 * API to find if the firmware will send trace logs using DXE channel
13672 */
13673v_U8_t hdd_is_fw_ev_logging_enabled(void)
13674{
13675 hdd_context_t *pHddCtx;
13676
13677 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13678 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13679
13680 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
13681}
13682/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053013683 * API to find if there is any session connected
13684 */
13685VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
13686{
13687 return sme_is_any_session_connected(pHddCtx->hHal);
13688}
13689
13690
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013691int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
13692{
13693 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13694 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053013695 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053013696 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013697
13698 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053013699 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013700 if (pScanInfo->mScanPending)
13701 {
c_hpothua3d45d52015-01-05 14:11:17 +053013702 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
13703 eCSR_SCAN_ABORT_DEFAULT);
13704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13705 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013706
c_hpothua3d45d52015-01-05 14:11:17 +053013707 /* If there is active scan command lets wait for the completion else
13708 * there is no need to wait as scan command might be in the SME pending
13709 * command list.
13710 */
13711 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
13712 {
c_hpothua3d45d52015-01-05 14:11:17 +053013713 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013714 &pScanInfo->abortscan_event_var,
13715 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053013716 if (0 >= status)
13717 {
13718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053013719 "%s: Timeout or Interrupt occurred while waiting for abort"
13720 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053013721 return -ETIMEDOUT;
13722 }
13723 }
13724 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
13725 {
13726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13727 FL("hdd_abort_mac_scan failed"));
13728 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013729 }
13730 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053013731 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013732}
13733
Abhishek Singh7d624e12015-11-30 14:29:27 +053013734/**
13735 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
13736 * user space
13737 * @frame_ind: Management frame data to be informed.
13738 *
13739 * This function is used to indicate management frame to
13740 * user space
13741 *
13742 * Return: None
13743 *
13744 */
13745void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
13746{
13747 hdd_context_t *hdd_ctx = NULL;
13748 hdd_adapter_t *adapter = NULL;
13749 v_CONTEXT_t vos_context = NULL;
13750
13751 /* Get the global VOSS context.*/
13752 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13753 if (!vos_context) {
13754 hddLog(LOGE, FL("Global VOS context is Null"));
13755 return;
13756 }
13757 /* Get the HDD context.*/
13758 hdd_ctx =
13759 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
13760
13761 if (0 != wlan_hdd_validate_context(hdd_ctx))
13762 {
13763 return;
13764 }
13765 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
13766 frame_ind->sessionId);
13767
13768 if ((NULL != adapter) &&
13769 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
13770 __hdd_indicate_mgmt_frame(adapter,
13771 frame_ind->frameLen,
13772 frame_ind->frameBuf,
13773 frame_ind->frameType,
13774 frame_ind->rxChan,
13775 frame_ind->rxRssi);
13776 return;
13777
13778}
13779
c_hpothu225aa7c2014-10-22 17:45:13 +053013780VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
13781{
13782 hdd_adapter_t *pAdapter;
13783 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13784 VOS_STATUS vosStatus;
13785
13786 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13787 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13788 {
13789 pAdapter = pAdapterNode->pAdapter;
13790 if (NULL != pAdapter)
13791 {
13792 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
13793 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
13794 WLAN_HDD_P2P_GO == pAdapter->device_mode)
13795 {
13796 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
13797 pAdapter->device_mode);
13798 if (VOS_STATUS_SUCCESS !=
13799 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
13800 {
13801 hddLog(LOGE, FL("failed to abort ROC"));
13802 return VOS_STATUS_E_FAILURE;
13803 }
13804 }
13805 }
13806 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13807 pAdapterNode = pNext;
13808 }
13809 return VOS_STATUS_SUCCESS;
13810}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053013811
Mihir Shete0be28772015-02-17 18:42:14 +053013812hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
13813{
13814 hdd_adapter_t *pAdapter;
13815 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13816 hdd_cfg80211_state_t *cfgState;
13817 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
13818 VOS_STATUS vosStatus;
13819
13820 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
13821 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13822 {
13823 pAdapter = pAdapterNode->pAdapter;
13824 if (NULL != pAdapter)
13825 {
13826 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
13827 pRemainChanCtx = cfgState->remain_on_chan_ctx;
13828 if (pRemainChanCtx)
13829 break;
13830 }
13831 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
13832 pAdapterNode = pNext;
13833 }
13834 return pRemainChanCtx;
13835}
13836
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053013837/**
13838 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
13839 *
13840 * @pHddCtx: HDD context within host driver
13841 * @dfsScanMode: dfsScanMode passed from ioctl
13842 *
13843 */
13844
13845VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
13846 tANI_U8 dfsScanMode)
13847{
13848 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13849 hdd_adapter_t *pAdapter;
13850 VOS_STATUS vosStatus;
13851 hdd_station_ctx_t *pHddStaCtx;
13852 eHalStatus status = eHAL_STATUS_SUCCESS;
13853
13854 if(!pHddCtx)
13855 {
13856 hddLog(LOGE, FL("HDD context is Null"));
13857 return eHAL_STATUS_FAILURE;
13858 }
13859
13860 if (pHddCtx->scan_info.mScanPending)
13861 {
13862 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
13863 pHddCtx->scan_info.sessionId);
13864 hdd_abort_mac_scan(pHddCtx,
13865 pHddCtx->scan_info.sessionId,
13866 eCSR_SCAN_ABORT_DEFAULT);
13867 }
13868
13869 if (!dfsScanMode)
13870 {
13871 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
13872 while ((NULL != pAdapterNode) &&
13873 (VOS_STATUS_SUCCESS == vosStatus))
13874 {
13875 pAdapter = pAdapterNode->pAdapter;
13876
13877 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13878 {
13879 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13880
13881 if(!pHddStaCtx)
13882 {
13883 hddLog(LOGE, FL("HDD STA context is Null"));
13884 return eHAL_STATUS_FAILURE;
13885 }
13886
13887 /* if STA is already connected on DFS channel,
13888 disconnect immediately*/
13889 if (hdd_connIsConnected(pHddStaCtx) &&
13890 (NV_CHANNEL_DFS ==
13891 vos_nv_getChannelEnabledState(
13892 pHddStaCtx->conn_info.operationChannel)))
13893 {
13894 status = sme_RoamDisconnect(pHddCtx->hHal,
13895 pAdapter->sessionId,
13896 eCSR_DISCONNECT_REASON_UNSPECIFIED);
13897 hddLog(LOG1, FL("Client connected on DFS channel %d,"
13898 "sme_RoamDisconnect returned with status: %d"
13899 "for sessionid: %d"), pHddStaCtx->conn_info.
13900 operationChannel, status, pAdapter->sessionId);
13901 }
13902 }
13903
13904 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
13905 &pNext);
13906 pAdapterNode = pNext;
13907 }
13908 }
13909
13910 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
13911 sme_UpdateDFSRoamMode(pHddCtx->hHal,
13912 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
13913
13914 status = sme_HandleDFSChanScan(pHddCtx->hHal);
13915 if (!HAL_STATUS_SUCCESS(status))
13916 {
13917 hddLog(LOGE,
13918 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
13919 return status;
13920 }
13921
13922 return status;
13923}
13924
Nirav Shah7e3c8132015-06-22 23:51:42 +053013925static int hdd_log2_ceil(unsigned value)
13926{
13927 /* need to switch to unsigned math so that negative values
13928 * will right-shift towards 0 instead of -1
13929 */
13930 unsigned tmp = value;
13931 int log2 = -1;
13932
13933 if (value == 0)
13934 return 0;
13935
13936 while (tmp) {
13937 log2++;
13938 tmp >>= 1;
13939 }
13940 if (1U << log2 != value)
13941 log2++;
13942
13943 return log2;
13944}
13945
13946/**
13947 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
13948 * @pAdapter: adapter handle
13949 *
13950 * Return: vos status
13951 */
13952VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
13953{
13954 int hash_elem, log2, i;
13955
13956 spin_lock_bh( &pAdapter->sta_hash_lock);
13957 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
13958 spin_unlock_bh( &pAdapter->sta_hash_lock);
13959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13960 "%s: hash already attached for session id %d",
13961 __func__, pAdapter->sessionId);
13962 return VOS_STATUS_SUCCESS;
13963 }
13964 spin_unlock_bh( &pAdapter->sta_hash_lock);
13965
13966 hash_elem = WLAN_MAX_STA_COUNT;
13967 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
13968 log2 = hdd_log2_ceil(hash_elem);
13969 hash_elem = 1 << log2;
13970
13971 pAdapter->sta_id_hash.mask = hash_elem - 1;
13972 pAdapter->sta_id_hash.idx_bits = log2;
13973 pAdapter->sta_id_hash.bins =
13974 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
13975 if (!pAdapter->sta_id_hash.bins) {
13976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13977 "%s: malloc failed for session %d",
13978 __func__, pAdapter->sessionId);
13979 return VOS_STATUS_E_NOMEM;
13980 }
13981
13982 for (i = 0; i < hash_elem; i++)
13983 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
13984
13985 spin_lock_bh( &pAdapter->sta_hash_lock);
13986 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
13987 spin_unlock_bh( &pAdapter->sta_hash_lock);
13988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13989 "%s: Station ID Hash attached for session id %d",
13990 __func__, pAdapter->sessionId);
13991
13992 return VOS_STATUS_SUCCESS;
13993}
13994
13995/**
13996 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
13997 * @pAdapter: adapter handle
13998 *
13999 * Return: vos status
14000 */
14001VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
14002{
14003 int hash_elem, i;
14004 v_SIZE_t size;
14005
14006 spin_lock_bh( &pAdapter->sta_hash_lock);
14007 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14008 spin_unlock_bh( &pAdapter->sta_hash_lock);
14009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14010 "%s: hash not initialized for session id %d",
14011 __func__, pAdapter->sessionId);
14012 return VOS_STATUS_SUCCESS;
14013 }
14014
14015 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
14016 spin_unlock_bh( &pAdapter->sta_hash_lock);
14017
14018 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
14019
14020 /* free all station info*/
14021 for (i = 0; i < hash_elem; i++) {
14022 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
14023 if (size != 0) {
14024 VOS_STATUS status;
14025 hdd_staid_hash_node_t *sta_info_node = NULL;
14026 hdd_staid_hash_node_t *next_node = NULL;
14027 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
14028 (hdd_list_node_t**) &sta_info_node );
14029
14030 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14031 {
14032 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
14033 &sta_info_node->node);
14034 vos_mem_free(sta_info_node);
14035
14036 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
14037 (hdd_list_node_t*)sta_info_node,
14038 (hdd_list_node_t**)&next_node);
14039 sta_info_node = next_node;
14040 }
14041 }
14042 }
14043
14044 vos_mem_free(pAdapter->sta_id_hash.bins);
14045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14046 "%s: Station ID Hash detached for session id %d",
14047 __func__, pAdapter->sessionId);
14048 return VOS_STATUS_SUCCESS;
14049}
14050
14051/**
14052 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
14053 * @pAdapter: adapter handle
14054 * @mac_addr_in: input mac address
14055 *
14056 * Return: index derived from mac address
14057 */
14058int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
14059 v_MACADDR_t *mac_addr_in)
14060{
14061 uint16 index;
14062 struct hdd_align_mac_addr_t * mac_addr =
14063 (struct hdd_align_mac_addr_t *)mac_addr_in;
14064
14065 index = mac_addr->bytes_ab ^
14066 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
14067 index ^= index >> pAdapter->sta_id_hash.idx_bits;
14068 index &= pAdapter->sta_id_hash.mask;
14069 return index;
14070}
14071
14072/**
14073 * hdd_sta_id_hash_add_entry() - add entry in hash
14074 * @pAdapter: adapter handle
14075 * @sta_id: station id
14076 * @mac_addr: mac address
14077 *
14078 * Return: vos status
14079 */
14080VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
14081 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14082{
14083 uint16 index;
14084 hdd_staid_hash_node_t *sta_info_node = NULL;
14085
Nirav Shah7e3c8132015-06-22 23:51:42 +053014086 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14087 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
14088 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053014089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14090 "%s: malloc failed", __func__);
14091 return VOS_STATUS_E_NOMEM;
14092 }
14093
14094 sta_info_node->sta_id = sta_id;
14095 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
14096
Nirav Shah303ed5c2015-08-24 10:29:25 +053014097 spin_lock_bh( &pAdapter->sta_hash_lock);
14098 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14099 spin_unlock_bh( &pAdapter->sta_hash_lock);
14100 vos_mem_free(sta_info_node);
14101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14102 "%s: hash is not initialized for session id %d",
14103 __func__, pAdapter->sessionId);
14104 return VOS_STATUS_E_FAILURE;
14105 }
14106
Nirav Shah7e3c8132015-06-22 23:51:42 +053014107 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
14108 (hdd_list_node_t*) sta_info_node );
14109 spin_unlock_bh( &pAdapter->sta_hash_lock);
14110 return VOS_STATUS_SUCCESS;
14111}
14112
14113/**
14114 * hdd_sta_id_hash_remove_entry() - remove entry from hash
14115 * @pAdapter: adapter handle
14116 * @sta_id: station id
14117 * @mac_addr: mac address
14118 *
14119 * Return: vos status
14120 */
14121VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
14122 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14123{
14124 uint16 index;
14125 VOS_STATUS status;
14126 hdd_staid_hash_node_t *sta_info_node = NULL;
14127 hdd_staid_hash_node_t *next_node = NULL;
14128
14129 spin_lock_bh( &pAdapter->sta_hash_lock);
14130 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14131 spin_unlock_bh( &pAdapter->sta_hash_lock);
14132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14133 "%s: hash is not initialized for session id %d",
14134 __func__, pAdapter->sessionId);
14135 return VOS_STATUS_E_FAILURE;
14136 }
14137
14138 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14139 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14140 (hdd_list_node_t**) &sta_info_node );
14141
14142 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14143 {
14144 if (sta_info_node->sta_id == sta_id) {
14145 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
14146 &sta_info_node->node);
14147 vos_mem_free(sta_info_node);
14148 break;
14149 }
14150 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14151 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
14152 sta_info_node = next_node;
14153 }
14154 spin_unlock_bh( &pAdapter->sta_hash_lock);
14155 return status;
14156}
14157
14158/**
14159 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
14160 * @pAdapter: adapter handle
14161 * @mac_addr_in: mac address
14162 *
14163 * Return: station id
14164 */
14165int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
14166 v_MACADDR_t *mac_addr_in)
14167{
14168 uint8 is_found = 0;
14169 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
14170 uint16 index;
14171 VOS_STATUS status;
14172 hdd_staid_hash_node_t *sta_info_node = NULL;
14173 hdd_staid_hash_node_t *next_node = NULL;
14174
14175 spin_lock_bh( &pAdapter->sta_hash_lock);
14176 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14177 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053014178 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053014179 FL("hash is not initialized for session id %d"),
14180 pAdapter->sessionId);
14181 return HDD_WLAN_INVALID_STA_ID;
14182 }
14183
14184 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
14185 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14186 (hdd_list_node_t**) &sta_info_node );
14187
14188 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14189 {
14190 if (vos_mem_compare(&sta_info_node->mac_addr,
14191 mac_addr_in, sizeof(v_MACADDR_t))) {
14192 is_found = 1;
14193 sta_id = sta_info_node->sta_id;
14194 break;
14195 }
14196 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14197 (hdd_list_node_t*)sta_info_node,
14198 (hdd_list_node_t**)&next_node);
14199 sta_info_node = next_node;
14200 }
14201 spin_unlock_bh( &pAdapter->sta_hash_lock);
14202 return sta_id;
14203}
14204
c_manjeecfd1efb2015-09-25 19:32:34 +053014205/*FW memory dump feature*/
14206/**
14207 * This structure hold information about the /proc file
14208 *
14209 */
14210static struct proc_dir_entry *proc_file, *proc_dir;
14211
14212/**
14213 * memdump_read() - perform read operation in memory dump proc file
14214 *
14215 * @file - handle for the proc file.
14216 * @buf - pointer to user space buffer.
14217 * @count - number of bytes to be read.
14218 * @pos - offset in the from buffer.
14219 *
14220 * This function performs read operation for the memory dump proc file.
14221 *
14222 * Return: number of bytes read on success, error code otherwise.
14223 */
14224static ssize_t memdump_read(struct file *file, char __user *buf,
14225 size_t count, loff_t *pos)
14226{
14227 int status;
14228 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
14229 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053014230 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053014231 ENTER();
14232
14233 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
14234 status = wlan_hdd_validate_context(hdd_ctx);
14235 if (0 != status) {
14236 return -EINVAL;
14237 }
14238
14239 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
14240 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
14241 return -EINVAL;
14242 }
14243
14244 /* run fs_read_handler in an atomic context*/
14245 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053014246 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
14247 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053014248 {
14249 /*Free the fwr mem dump buffer */
14250 wlan_free_fwr_mem_dump_buffer();
14251 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053014252 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053014253 }
14254 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
14255 vos_ssr_unprotect(__func__);
14256 EXIT();
14257 return ret_count;
14258}
14259
14260/**
14261 * struct memdump_fops - file operations for memory dump feature
14262 * @read - read function for memory dump operation.
14263 *
14264 * This structure initialize the file operation handle for memory
14265 * dump feature
14266 */
14267static const struct file_operations memdump_fops = {
14268 read: memdump_read
14269};
14270
14271/*
14272* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
14273* To be passed by HDD to WDA and called upon receiving of response
14274* from firmware
14275* @fwMemDumpReqContext : memory dump request context
14276* @dump_rsp : dump response from HAL
14277* Returns none
14278*/
14279void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
14280 tAniFwrDumpRsp *dump_rsp)
14281{
c_manjeef1495642015-10-13 18:35:01 +053014282 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053014283
c_manjeef1495642015-10-13 18:35:01 +053014284 ENTER();
14285 spin_lock(&hdd_context_lock);
14286 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
14287 spin_unlock(&hdd_context_lock);
14288 return;
14289 }
14290 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053014291 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053014292 hddLog(LOGE, FL("fw dump request declined by fwr"));
14293 //set the request completion variable
14294 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053014295 //Free the allocated fwr dump
14296 wlan_free_fwr_mem_dump_buffer();
14297 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053014298 }
c_manjeef1495642015-10-13 18:35:01 +053014299 else {
14300 hddLog(LOG1, FL("fw dump request accepted by fwr"));
14301 /* register the HDD callback which will be called by SVC */
14302 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
14303 }
14304 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014305 EXIT();
14306
14307}
14308
14309/**
14310 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
14311 *
14312 * This function removes file/dir under proc file system that was
14313 * processing firmware memory dump
14314 *
14315 * Return: None
14316 */
14317static void memdump_procfs_remove(void)
14318{
14319 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14320 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
14321 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14322 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14323 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
14324}
14325
14326/**
14327 * memdump_procfs_init() - Initialize procfs for memory dump
14328 *
14329 * @vos_ctx - Global vos context.
14330 *
14331 * This function create file under proc file system to be used later for
14332 * processing firmware memory dump
14333 *
14334 * Return: 0 on success, error code otherwise.
14335 */
14336static int memdump_procfs_init(void *vos_ctx)
14337{
14338 hdd_context_t *hdd_ctx;
14339
14340 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14341 if (!hdd_ctx) {
14342 hddLog(LOGE , FL("Invalid HDD context"));
14343 return -EINVAL;
14344 }
14345
14346 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
14347 if (proc_dir == NULL) {
14348 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14349 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14350 PROCFS_MEMDUMP_DIR);
14351 return -ENOMEM;
14352 }
14353
14354 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
14355 S_IRUSR | S_IWUSR, proc_dir,
14356 &memdump_fops, hdd_ctx);
14357 if (proc_file == NULL) {
14358 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14359 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14360 PROCFS_MEMDUMP_NAME);
14361 return -ENOMEM;
14362 }
14363
14364 hddLog(LOG1 , FL("/proc/%s/%s created"),
14365 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14366
14367 return 0;
14368}
14369
14370/**
14371 * memdump_init() - Initialization function for memory dump feature
14372 *
14373 * This function creates proc file for memdump feature and registers
14374 * HDD callback function with SME.
14375 *
14376 * Return - 0 on success, error otherwise
14377 */
14378int memdump_init(void)
14379{
14380 hdd_context_t *hdd_ctx;
14381 void *vos_ctx;
14382 int status = 0;
14383
14384 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14385 if (!vos_ctx) {
14386 hddLog(LOGE, FL("Invalid VOS context"));
14387 return -EINVAL;
14388 }
14389
14390 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14391 if (!hdd_ctx) {
14392 hddLog(LOGE , FL("Invalid HDD context"));
14393 return -EINVAL;
14394 }
14395
14396 status = memdump_procfs_init(vos_ctx);
14397 if (status) {
14398 hddLog(LOGE , FL("Failed to create proc file"));
14399 return status;
14400 }
14401
14402 return 0;
14403}
14404
14405/**
14406 * memdump_deinit() - De initialize memdump feature
14407 *
14408 * This function removes proc file created for memdump feature.
14409 *
14410 * Return: None
14411 */
14412int memdump_deinit(void)
14413{
14414 hdd_context_t *hdd_ctx;
14415 void *vos_ctx;
14416
14417 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14418 if (!vos_ctx) {
14419 hddLog(LOGE, FL("Invalid VOS context"));
14420 return -EINVAL;
14421 }
14422
14423 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14424 if(!hdd_ctx) {
14425 hddLog(LOGE , FL("Invalid HDD context"));
14426 return -EINVAL;
14427 }
14428
14429 memdump_procfs_remove();
14430 return 0;
14431}
14432
14433/**
14434 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
14435 * Return: HAL status
14436 */
14437
14438int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
14439{
14440 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053014441 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014442 eHalStatus status = eHAL_STATUS_FAILURE;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014443 int ret=0, result;
c_manjeecfd1efb2015-09-25 19:32:34 +053014444 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053014445
c_manjeecfd1efb2015-09-25 19:32:34 +053014446 /*Check whether a dump request is already going on
14447 *Caution this function will free previously held memory if new dump request is allowed*/
14448 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
14449 hddLog(LOGE, FL("Fw memdump already in progress"));
14450 return -EBUSY;
14451 }
14452 //Allocate memory for fw mem dump buffer
14453 ret = wlan_fwr_mem_dump_buffer_allocation();
14454 if(ret == -EFAULT)
14455 {
14456 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
14457 return ret;
14458 }
14459 if (0 != ret) {
14460 hddLog(LOGE, FL("Fwr mem Allocation failed"));
14461 return -ENOMEM;
14462 }
c_manjeef1495642015-10-13 18:35:01 +053014463 init_completion(&fw_mem_dump_ctx.req_completion);
14464 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
14465 fw_mem_dump_ctx.status = false;
14466
c_manjeecfd1efb2015-09-25 19:32:34 +053014467 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053014468 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014469 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
14470 if(eHAL_STATUS_SUCCESS != status)
14471 {
14472 hddLog(VOS_TRACE_LEVEL_ERROR,
14473 "%s: fw_mem_dump_req failed ", __func__);
14474 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053014475 ret = -EFAULT;
14476 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053014477 }
c_manjeef1495642015-10-13 18:35:01 +053014478 /*wait for fw mem dump completion to send event to userspace*/
Abhishek Singh4eca9822015-12-09 18:07:34 +053014479 result =
14480 wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,
14481 msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
14482 if (0 >= result )
c_manjeef1495642015-10-13 18:35:01 +053014483 {
14484 hddLog(VOS_TRACE_LEVEL_ERROR,
Abhishek Singh4eca9822015-12-09 18:07:34 +053014485 "%s: fw_mem_dump_req timeout %d ", __func__,result);
14486 ret = -ETIMEDOUT;
c_manjeef1495642015-10-13 18:35:01 +053014487 }
14488cleanup:
14489 spin_lock(&hdd_context_lock);
14490 fw_mem_dump_ctx.magic = 0;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014491 if(!ret && !fw_mem_dump_ctx.status)
14492 ret = -EFAULT;
c_manjeef1495642015-10-13 18:35:01 +053014493 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014494
c_manjeef1495642015-10-13 18:35:01 +053014495 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053014496 return ret;
c_manjeef1495642015-10-13 18:35:01 +053014497}
14498
14499/**
14500 * HDD callback which will be called by SVC to indicate mem dump completion.
14501 */
14502void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
14503{
14504 if (!pHddFwMemDumpCtx) {
14505 hddLog(VOS_TRACE_LEVEL_ERROR,
14506 "%s: HDD context not valid ", __func__);
14507 return;
14508 }
14509 spin_lock(&hdd_context_lock);
14510 /* check the req magic and set status */
14511 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
14512 {
14513 pHddFwMemDumpCtx->status = true;
14514 //signal the completion
14515 complete(&(pHddFwMemDumpCtx->req_completion));
14516 }
14517 else
14518 {
14519 hddLog(VOS_TRACE_LEVEL_ERROR,
14520 "%s: fw mem dump request possible timeout ", __func__);
14521 }
14522 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014523}
14524
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053014525void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
14526{
14527 if (NULL == pAdapter)
14528 {
14529 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
14530 return;
14531 }
14532 init_completion(&pAdapter->session_open_comp_var);
14533 init_completion(&pAdapter->session_close_comp_var);
14534 init_completion(&pAdapter->disconnect_comp_var);
14535 init_completion(&pAdapter->linkup_event_var);
14536 init_completion(&pAdapter->cancel_rem_on_chan_var);
14537 init_completion(&pAdapter->rem_on_chan_ready_event);
14538 init_completion(&pAdapter->pno_comp_var);
14539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14540 init_completion(&pAdapter->offchannel_tx_event);
14541#endif
14542 init_completion(&pAdapter->tx_action_cnf_event);
14543#ifdef FEATURE_WLAN_TDLS
14544 init_completion(&pAdapter->tdls_add_station_comp);
14545 init_completion(&pAdapter->tdls_del_station_comp);
14546 init_completion(&pAdapter->tdls_mgmt_comp);
14547 init_completion(&pAdapter->tdls_link_establish_req_comp);
14548#endif
14549
14550#ifdef WLAN_FEATURE_RMC
14551 init_completion(&pAdapter->ibss_peer_info_comp);
14552#endif /* WLAN_FEATURE_RMC */
14553 init_completion(&pAdapter->ula_complete);
14554 init_completion(&pAdapter->change_country_code);
14555
14556#ifdef FEATURE_WLAN_BATCH_SCAN
14557 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
14558 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
14559#endif
14560
14561 return;
14562}
c_manjeecfd1efb2015-09-25 19:32:34 +053014563
14564
Jeff Johnson295189b2012-06-20 16:38:30 -070014565//Register the module init/exit functions
14566module_init(hdd_module_init);
14567module_exit(hdd_module_exit);
14568
14569MODULE_LICENSE("Dual BSD/GPL");
14570MODULE_AUTHOR("Qualcomm Atheros, Inc.");
14571MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
14572
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014573module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
14574 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014575
Jeff Johnson76052702013-04-16 13:55:05 -070014576module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070014577 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080014578
14579module_param(enable_dfs_chan_scan, int,
14580 S_IRUSR | S_IRGRP | S_IROTH);
14581
14582module_param(enable_11d, int,
14583 S_IRUSR | S_IRGRP | S_IROTH);
14584
14585module_param(country_code, charp,
14586 S_IRUSR | S_IRGRP | S_IROTH);