blob: 9e2f2ee9c08f6086bdc9810b437aa8eb48c677f5 [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/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302504 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302505 *
2506 * @pAdapter: Adapter upon which the command was received
2507 * @bssid: BSSID with which to reassociate
2508 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302509 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302510 *
2511 * Return: 0 for success non-zero for failure
2512 */
2513#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302514int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302515 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302516{
2517 hdd_station_ctx_t *pHddStaCtx;
2518 tCsrHandoffRequest handoffInfo;
2519 hdd_context_t *pHddCtx = NULL;
2520 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2521
2522 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2523
2524 /* if not associated, no need to proceed with reassoc */
2525 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2526 hddLog(LOG1, FL("Not associated"));
2527 return -EINVAL;
2528 }
2529
2530 /* if the target bssid is same as currently associated AP,
2531 then no need to proceed with reassoc */
2532 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2533 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2534 return -EINVAL;
2535 }
2536
2537 /* Check channel number is a valid channel number */
2538 if (VOS_STATUS_SUCCESS !=
2539 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2540 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2541 return -EINVAL;
2542 }
2543
2544 /* Proceed with reassoc */
2545 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302546 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302547 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2548 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2549 return 0;
2550}
2551#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302552int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302553 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302554{
2555 return -EPERM;
2556}
2557#endif
2558
2559/**
2560 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2561 * This function parses the v1 REASSOC command with the format
2562 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2563 * Hex-ASCII representation of the BSSID and CH is the ASCII
2564 * representation of the channel. For example
2565 * REASSOC 00:0a:0b:11:22:33 48
2566 *
2567 * @pAdapter: Adapter upon which the command was received
2568 * @command: ASCII text command that was received
2569 *
2570 * Return: 0 for success non-zero for failure
2571 */
2572static int
2573hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2574{
2575 tANI_U8 channel = 0;
2576 tSirMacAddr bssid;
2577 int ret;
2578
2579 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2580 if (ret)
2581 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2582 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302583 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302584
2585 return ret;
2586}
2587
2588/**
2589 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2590 * This function parses the v2 REASSOC command with the format
2591 * REASSOC <android_wifi_reassoc_params>
2592 *
2593 * @pAdapter: Adapter upon which the command was received
2594 * @command: command that was received, ASCII command followed
2595 * by binary data
2596 *
2597 * Return: 0 for success non-zero for failure
2598 */
2599static int
2600hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command)
2601{
2602 struct android_wifi_reassoc_params params;
2603 tSirMacAddr bssid;
2604 int ret;
2605
2606 /* The params are located after "REASSOC " */
2607 memcpy(&params, command + 8, sizeof(params));
2608
2609 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2610 hddLog(LOGE, FL("MAC address parsing failed"));
2611 ret = -EINVAL;
2612 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302613 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302614 }
2615 return ret;
2616}
2617
2618/**
2619 * hdd_parse_reassoc() - parse the REASSOC command
2620 * There are two different versions of the REASSOC command.Version 1
2621 * of the command contains a parameter list that is ASCII characters
2622 * whereas version 2 contains a combination of ASCII and binary
2623 * payload. Determine if a version 1 or a version 2 command is being
2624 * parsed by examining the parameters, and then dispatch the parser
2625 * that is appropriate for the command.
2626 *
2627 * @pAdapter: Adapter upon which the command was received
2628 * @command: command that was received
2629 *
2630 * Return: 0 for success non-zero for failure
2631 */
2632static int
2633hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command)
2634{
2635 int ret;
2636
2637 /*
2638 * both versions start with "REASSOC"
2639 * v1 has a bssid and channel # as an ASCII string
2640 * REASSOC xx:xx:xx:xx:xx:xx CH
2641 * v2 has a C struct
2642 * REASSOC <binary c struct>
2643 *
2644 * The first field in the v2 struct is also the bssid in ASCII.
2645 * But in the case of a v2 message the BSSID is NUL-terminated.
2646 * Hence we can peek at that offset to see if this is V1 or V2
2647 * REASSOC xx:xx:xx:xx:xx:xx*
2648 * 1111111111222222
2649 * 01234567890123456789012345
2650 */
2651 if (command[25])
2652 ret = hdd_parse_reassoc_v1(pAdapter, command);
2653 else
2654 ret = hdd_parse_reassoc_v2(pAdapter, command);
2655
2656 return ret;
2657}
2658#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2659
c_hpothu92367912014-05-01 15:18:17 +05302660static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data)
2661{
c_hpothu39eb1e32014-06-26 16:31:50 +05302662 bcnMissRateContext_t *pCBCtx;
2663
2664 if (NULL == data)
2665 {
2666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2667 return;
2668 }
c_hpothu92367912014-05-01 15:18:17 +05302669
2670 /* there is a race condition that exists between this callback
2671 function and the caller since the caller could time out either
2672 before or while this code is executing. we use a spinlock to
2673 serialize these actions */
2674 spin_lock(&hdd_context_lock);
2675
c_hpothu39eb1e32014-06-26 16:31:50 +05302676 pCBCtx = (bcnMissRateContext_t *)data;
c_hpothu92367912014-05-01 15:18:17 +05302677 gbcnMissRate = -1;
2678
c_hpothu39eb1e32014-06-26 16:31:50 +05302679 if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC)
c_hpothu92367912014-05-01 15:18:17 +05302680 {
2681 hddLog(VOS_TRACE_LEVEL_ERROR,
c_hpothu39eb1e32014-06-26 16:31:50 +05302682 FL("invalid context magic: %08x"), pCBCtx->magic);
c_hpothu92367912014-05-01 15:18:17 +05302683 spin_unlock(&hdd_context_lock);
2684 return ;
2685 }
2686
2687 if (VOS_STATUS_SUCCESS == status)
2688 {
c_hpothu39eb1e32014-06-26 16:31:50 +05302689 gbcnMissRate = bcnMissRate;
c_hpothu92367912014-05-01 15:18:17 +05302690 }
c_hpothu39eb1e32014-06-26 16:31:50 +05302691 else
2692 {
2693 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
2694 }
2695
c_hpothu92367912014-05-01 15:18:17 +05302696 complete(&(pCBCtx->completion));
2697 spin_unlock(&hdd_context_lock);
2698
2699 return;
2700}
2701
Abhishek Singh08aa7762014-12-16 13:59:03 +05302702void hdd_FWStatisCB( VOS_STATUS status,
2703 tSirFwStatsResult *fwStatsResult, void *pContext )
Satyanarayana Dash72806012014-12-02 14:30:08 +05302704{
2705 fwStatsContext_t *fwStatsCtx;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302706 hdd_adapter_t *pAdapter;
2707
2708 hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status);
2709
Abhishek Singh08aa7762014-12-16 13:59:03 +05302710 if (NULL == pContext)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302711 {
2712 hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL"));
2713 return;
2714 }
2715 /* there is a race condition that exists between this callback
2716 function and the caller since the caller could time out either
2717 before or while this code is executing. we use a spinlock to
2718 serialize these actions */
2719 spin_lock(&hdd_context_lock);
Abhishek Singh08aa7762014-12-16 13:59:03 +05302720 fwStatsCtx = (fwStatsContext_t *) pContext;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302721 if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC)
2722 {
2723 hddLog(VOS_TRACE_LEVEL_ERROR,
2724 FL("invalid context magic: %08x"), fwStatsCtx->magic);
2725 spin_unlock(&hdd_context_lock);
2726 return;
2727 }
2728 pAdapter = fwStatsCtx->pAdapter;
2729 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
2730 {
2731 hddLog(VOS_TRACE_LEVEL_ERROR,
2732 FL("pAdapter returned is NULL or invalid"));
2733 spin_unlock(&hdd_context_lock);
2734 return;
2735 }
2736 pAdapter->fwStatsRsp.type = 0;
Abhishek Singh08aa7762014-12-16 13:59:03 +05302737 if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult))
Satyanarayana Dash72806012014-12-02 14:30:08 +05302738 {
Satyanarayana Dash72806012014-12-02 14:30:08 +05302739 switch( fwStatsResult->type )
2740 {
2741 case FW_UBSP_STATS:
2742 {
Abhishek Singh08aa7762014-12-16 13:59:03 +05302743 memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult));
Satyanarayana Dash72806012014-12-02 14:30:08 +05302744 hddLog(VOS_TRACE_LEVEL_INFO,
2745 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
Abhishek Singh08aa7762014-12-16 13:59:03 +05302746 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt,
2747 pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302748 }
2749 break;
2750 default:
2751 {
2752 hddLog(VOS_TRACE_LEVEL_ERROR,
2753 FL(" No handling for stats type %d"),fwStatsResult->type);
2754 }
2755 }
2756 }
2757 complete(&(fwStatsCtx->completion));
2758 spin_unlock(&hdd_context_lock);
2759 return;
2760}
2761
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302762static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2763{
2764 int ret = 0;
2765
2766 if (!pCfg || !command || !extra || !len)
2767 {
2768 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2769 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2770 ret = -EINVAL;
2771 return ret;
2772 }
2773
2774 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2775 {
2776 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2777 (int)pCfg->nActiveMaxChnTime);
2778 return ret;
2779 }
2780 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2781 {
2782 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2783 (int)pCfg->nActiveMinChnTime);
2784 return ret;
2785 }
2786 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2787 {
2788 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2789 (int)pCfg->nPassiveMaxChnTime);
2790 return ret;
2791 }
2792 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2793 {
2794 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2795 (int)pCfg->nPassiveMinChnTime);
2796 return ret;
2797 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302798 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2799 {
2800 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2801 (int)pCfg->nActiveMaxChnTime);
2802 return ret;
2803 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302804 else
2805 {
2806 ret = -EINVAL;
2807 }
2808
2809 return ret;
2810}
2811
2812static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
2813{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302814 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302815 hdd_config_t *pCfg;
2816 tANI_U8 *value = command;
2817 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302818 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302819
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302820 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
2821 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302822 {
2823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2824 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2825 ret = -EINVAL;
2826 return ret;
2827 }
2828
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302829 vos_mem_zero(&smeConfig, sizeof(smeConfig));
2830 sme_GetConfigParam(hHal, &smeConfig);
2831
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302832 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
2833 {
2834 value = value + 24;
2835 temp = kstrtou32(value, 10, &val);
2836 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2837 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2838 {
2839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2840 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
2841 ret = -EFAULT;
2842 return ret;
2843 }
2844 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302845 smeConfig.csrConfig.nActiveMaxChnTime = val;
2846 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302847 }
2848 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
2849 {
2850 value = value + 24;
2851 temp = kstrtou32(value, 10, &val);
2852 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
2853 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
2854 {
2855 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2856 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
2857 ret = -EFAULT;
2858 return ret;
2859 }
2860 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302861 smeConfig.csrConfig.nActiveMinChnTime = val;
2862 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302863 }
2864 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
2865 {
2866 value = value + 25;
2867 temp = kstrtou32(value, 10, &val);
2868 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
2869 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
2870 {
2871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2872 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
2873 ret = -EFAULT;
2874 return ret;
2875 }
2876 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302877 smeConfig.csrConfig.nPassiveMaxChnTime = val;
2878 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302879 }
2880 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
2881 {
2882 value = value + 25;
2883 temp = kstrtou32(value, 10, &val);
2884 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
2885 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
2886 {
2887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2888 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
2889 ret = -EFAULT;
2890 return ret;
2891 }
2892 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05302893 smeConfig.csrConfig.nPassiveMinChnTime = val;
2894 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302895 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302896 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
2897 {
2898 value = value + 13;
2899 temp = kstrtou32(value, 10, &val);
2900 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
2901 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
2902 {
2903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2904 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
2905 ret = -EFAULT;
2906 return ret;
2907 }
2908 pCfg->nActiveMaxChnTime = val;
2909 smeConfig.csrConfig.nActiveMaxChnTime = val;
2910 sme_UpdateConfig(hHal, &smeConfig);
2911 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302912 else
2913 {
2914 ret = -EINVAL;
2915 }
2916
2917 return ret;
2918}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302919static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
2920 tANI_U8 cmd_len)
2921{
2922 tANI_U8 *value;
2923 tANI_U8 fcc_constraint;
2924
2925 eHalStatus status;
2926 int ret = 0;
2927 value = cmd + cmd_len + 1;
2928
2929 ret = kstrtou8(value, 10, &fcc_constraint);
2930 if ((ret < 0) || (fcc_constraint > 1)) {
2931 /*
2932 * If the input value is greater than max value of datatype,
2933 * then also it is a failure
2934 */
2935 hddLog(VOS_TRACE_LEVEL_ERROR,
2936 "%s: value out of range", __func__);
2937 return -EINVAL;
2938 }
2939
2940 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint);
2941 if (status != eHAL_STATUS_SUCCESS)
2942 ret = -EPERM;
2943
2944 return ret;
2945}
2946
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302947/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05302948
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05302949 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
2950 FW will send *ONE* CA ind to Host(even though it is duplicate).
2951 When Host send IOCTL (disable), FW doesn't perform any action.
2952 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
2953 sends CA ind to host. (regard less of IOCTL status)
2954 \param - pHddCtx - HDD context
2955 \param - command - command received from framework
2956 \param - cmd_len - len of the command
2957
2958 \return - 0 on success, appropriate error values on failure.
2959
2960 --------------------------------------------------------------------------*/
2961int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
2962{
2963 tANI_U8 set_value;
2964 int ret = 0;
2965 eHalStatus status;
2966
2967 ret = wlan_hdd_validate_context(pHddCtx);
2968 if (0 != ret)
2969 {
2970 ret = -EINVAL;
2971 goto exit;
2972 }
2973
2974 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
2975 {
2976 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
2977 " ini param to control channel avooidance indication");
2978 ret = 0;
2979 goto exit;
2980 }
2981
2982 set_value = command[cmd_len + 1] - '0';
2983 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
2984 if (status != eHAL_STATUS_SUCCESS)
2985 {
2986 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
2987 " enableDisableChanAoidance command to SME\n", __func__);
2988 ret = -EINVAL;
2989 }
2990
2991exit:
2992 return ret;
2993}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302994
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05302995/**
2996 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
2997 * @pHddCtx: Pointer to the HDD context
2998 * @channel: channel to reassociate
2999 * @targetApBssid: Target AP/BSSID to reassociate
3000 *
3001 * Return: None
3002 */
3003#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3004static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3005 uint8_t channel, tSirMacAddr targetApBssid)
3006{
3007 tCsrHandoffRequest handoffInfo;
3008 handoffInfo.channel = channel;
3009 handoffInfo.src = FASTREASSOC;
3010 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3011 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3012}
3013#else
3014static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3015 uint8_t channel, tSirMacAddr targetApBssid)
3016{
3017}
3018#endif
3019
3020/**
3021 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3022 * @pAdapter: Pointer to HDD adapter
3023 * @channel: Channel to scan/roam
3024 * @targetApBssid: BSSID to roam
3025 *
3026 * Return: None
3027 */
3028#ifdef QCA_WIFI_ISOC
3029static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3030 uint8_t channel, tSirMacAddr targetApBssid)
3031{
3032 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3033 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3034}
3035#else
3036static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3037 uint8_t channel, tSirMacAddr targetApBssid)
3038{
3039}
3040#endif
3041
3042/**
3043 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3044 * @pAdapter: pointer to hdd adapter
3045 * @command: pointer to the command received
3046 *
3047 * Return: VOS_STATUS enum
3048 */
3049static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3050 uint8_t *command)
3051{
3052 tANI_U8 *value = command;
3053 tANI_U8 channel = 0;
3054 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303055 hdd_station_ctx_t *pHddStaCtx = NULL;
3056 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303057 int ret;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303058 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3059 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3060
3061 /* if not associated, no need to proceed with reassoc */
3062 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3063 hddLog(LOG1, FL("Not associated!"));
3064 return eHAL_STATUS_FAILURE;
3065 }
3066
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303067 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3068 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303069 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3070 return eHAL_STATUS_FAILURE;
3071 }
3072
3073 /* if the target bssid is same as currently associated AP,
3074 then no need to proceed with reassoc */
3075 if (vos_mem_compare(targetApBssid,
3076 pHddStaCtx->conn_info.bssId,
3077 sizeof(tSirMacAddr))) {
3078 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
3079 return eHAL_STATUS_FAILURE;
3080 }
3081
3082 /* Check channel number is a valid channel number */
3083 if (VOS_STATUS_SUCCESS !=
3084 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3085 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3086 return eHAL_STATUS_FAILURE;
3087 }
3088
3089 /* Proceed with reassoc */
3090 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3091
3092 /* Proceed with scan/roam */
3093 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3094
3095 return eHAL_STATUS_SUCCESS;
3096}
3097
3098/**
3099 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3100 * @handoffInfo: Pointer to the csr Handoff Request.
3101 *
3102 * Return: None
3103 */
3104#ifndef QCA_WIFI_ISOC
3105static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3106{
3107 handoffInfo->src = REASSOC;
3108}
3109#else
3110static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3111{
3112}
3113#endif
3114
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003115static int hdd_driver_command(hdd_adapter_t *pAdapter,
3116 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003117{
Jeff Johnson295189b2012-06-20 16:38:30 -07003118 hdd_priv_data_t priv_data;
3119 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303120 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3121 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003122 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303123 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303124#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3125 struct cfg80211_mgmt_tx_params params;
3126#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303127
3128 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003129 /*
3130 * Note that valid pointers are provided by caller
3131 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003132
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003133 /* copy to local struct to avoid numerous changes to legacy code */
3134 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003135
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003136 if (priv_data.total_len <= 0 ||
3137 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003138 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003139 hddLog(VOS_TRACE_LEVEL_WARN,
3140 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3141 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003142 ret = -EINVAL;
3143 goto exit;
3144 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303145 status = wlan_hdd_validate_context(pHddCtx);
3146 if (0 != status)
3147 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303148 ret = -EINVAL;
3149 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303150 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003151 /* Allocate +1 for '\0' */
3152 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003153 if (!command)
3154 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003155 hddLog(VOS_TRACE_LEVEL_ERROR,
3156 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003157 ret = -ENOMEM;
3158 goto exit;
3159 }
3160
3161 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3162 {
3163 ret = -EFAULT;
3164 goto exit;
3165 }
3166
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003167 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003168 command[priv_data.total_len] = '\0';
3169
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003170 /* at one time the following block of code was conditional. braces
3171 * have been retained to avoid re-indenting the legacy code
3172 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003173 {
3174 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3175
3176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003177 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003178
3179 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3180 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303181 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3182 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3183 pAdapter->sessionId, (unsigned)
3184 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3185 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3186 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3187 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003188 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3189 sizeof(tSirMacAddr)))
3190 {
3191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003192 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003193 ret = -EFAULT;
3194 }
3195 }
Amar Singhal0974e402013-02-12 14:27:46 -08003196 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003197 {
Amar Singhal0974e402013-02-12 14:27:46 -08003198 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003199
Jeff Johnson295189b2012-06-20 16:38:30 -07003200 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003201
3202 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003203 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003205 "%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 +05303206 if(VOS_FTM_MODE != hdd_get_conparam())
3207 {
3208 /* Change band request received */
3209 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3210 if(ret < 0)
3211 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3212 "%s: failed to set band ret=%d", __func__, ret);
3213 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003214 }
Kiet Lamf040f472013-11-20 21:15:23 +05303215 else if(strncmp(command, "SETWMMPS", 8) == 0)
3216 {
3217 tANI_U8 *ptr = command;
3218 ret = hdd_wmmps_helper(pAdapter, ptr);
3219 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303220
3221 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3222 {
3223 tANI_U8 *ptr = command;
3224 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
3225 }
3226
Jeff Johnson32d95a32012-09-10 13:15:23 -07003227 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
3228 {
3229 char *country_code;
3230
3231 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003232
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003233 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07003234 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003235#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05303236 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07003237#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003238 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3239 (void *)(tSmeChangeCountryCallback)
3240 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05303241 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003242 if (eHAL_STATUS_SUCCESS == ret)
3243 {
3244 ret = wait_for_completion_interruptible_timeout(
3245 &pAdapter->change_country_code,
3246 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
3247 if (0 >= ret)
3248 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303250 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003251 }
3252 }
3253 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07003254 {
3255 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003256 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003257 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07003258 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07003259
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003260 }
3261 /*
3262 command should be a string having format
3263 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
3264 */
Amar Singhal0974e402013-02-12 14:27:46 -08003265 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003266 {
Amar Singhal0974e402013-02-12 14:27:46 -08003267 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003268
3269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07003270 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07003271
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08003272 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07003273 }
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003274 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
3275 {
3276 int suspend = 0;
3277 tANI_U8 *ptr = (tANI_U8*)command + 15;
3278
3279 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303280 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3281 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
3282 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08003283 hdd_set_wlan_suspend_mode(suspend);
3284 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003285#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
3286 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
3287 {
3288 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003289 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003290 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
3291 eHalStatus status = eHAL_STATUS_SUCCESS;
3292
3293 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
3294 value = value + 15;
3295
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003296 /* Convert the value from ascii to integer */
3297 ret = kstrtos8(value, 10, &rssi);
3298 if (ret < 0)
3299 {
3300 /* If the input value is greater than max value of datatype, then also
3301 kstrtou8 fails */
3302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3303 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07003304 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003305 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3306 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3307 ret = -EINVAL;
3308 goto exit;
3309 }
3310
Srinivas Girigowdade697412013-02-14 16:31:48 -08003311 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003312
Srinivas Girigowdade697412013-02-14 16:31:48 -08003313 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
3314 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
3315 {
3316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3317 "Neighbor lookup threshold value %d is out of range"
3318 " (Min: %d Max: %d)", lookUpThreshold,
3319 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
3320 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
3321 ret = -EINVAL;
3322 goto exit;
3323 }
3324
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303325 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3326 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
3327 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3329 "%s: Received Command to Set Roam trigger"
3330 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
3331
3332 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
3333 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
3334 if (eHAL_STATUS_SUCCESS != status)
3335 {
3336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3337 "%s: Failed to set roam trigger, try again", __func__);
3338 ret = -EPERM;
3339 goto exit;
3340 }
3341
3342 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05303343 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003344 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
3345 }
3346 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
3347 {
3348 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
3349 int rssi = (-1) * lookUpThreshold;
3350 char extra[32];
3351 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303352 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3353 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
3354 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003355 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05303356 len = VOS_MIN(priv_data.total_len, len + 1);
3357 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003358 {
3359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3360 "%s: failed to copy data to user buffer", __func__);
3361 ret = -EFAULT;
3362 goto exit;
3363 }
3364 }
3365 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
3366 {
3367 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003368 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003369 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003370
Srinivas Girigowdade697412013-02-14 16:31:48 -08003371 /* input refresh period is in terms of seconds */
3372 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
3373 value = value + 18;
3374 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003375 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003376 if (ret < 0)
3377 {
3378 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003379 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003381 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08003382 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003383 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3384 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003385 ret = -EINVAL;
3386 goto exit;
3387 }
3388
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003389 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
3390 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003391 {
3392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003393 "Roam scan period value %d is out of range"
3394 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07003395 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
3396 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003397 ret = -EINVAL;
3398 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303399 }
3400 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3401 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
3402 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003403 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003404
3405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3406 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003407 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003408
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003409 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
3410 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003411 }
3412 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
3413 {
3414 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3415 char extra[32];
3416 tANI_U8 len = 0;
3417
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303418 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3419 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
3420 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003421 len = scnprintf(extra, sizeof(extra), "%s %d",
3422 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003423 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05303424 len = VOS_MIN(priv_data.total_len, len + 1);
3425 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3427 "%s: failed to copy data to user buffer", __func__);
3428 ret = -EFAULT;
3429 goto exit;
3430 }
3431 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003432 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
3433 {
3434 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003435 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003436 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003437
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003438 /* input refresh period is in terms of seconds */
3439 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
3440 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003441
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003442 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003443 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003444 if (ret < 0)
3445 {
3446 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003447 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003449 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003450 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003451 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3452 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3453 ret = -EINVAL;
3454 goto exit;
3455 }
3456
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003457 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
3458 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
3459 {
3460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3461 "Neighbor scan results refresh period value %d is out of range"
3462 " (Min: %d Max: %d)", roamScanRefreshPeriod,
3463 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
3464 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
3465 ret = -EINVAL;
3466 goto exit;
3467 }
3468 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
3469
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3471 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003472 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003473
3474 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
3475 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
3476 }
3477 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
3478 {
3479 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
3480 char extra[32];
3481 tANI_U8 len = 0;
3482
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003483 len = scnprintf(extra, sizeof(extra), "%s %d",
3484 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003485 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05303486 len = VOS_MIN(priv_data.total_len, len + 1);
3487 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3489 "%s: failed to copy data to user buffer", __func__);
3490 ret = -EFAULT;
3491 goto exit;
3492 }
3493 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003494#ifdef FEATURE_WLAN_LFR
3495 /* SETROAMMODE */
3496 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
3497 {
3498 tANI_U8 *value = command;
3499 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
3500
3501 /* Move pointer to ahead of SETROAMMODE<delimiter> */
3502 value = value + SIZE_OF_SETROAMMODE + 1;
3503
3504 /* Convert the value from ascii to integer */
3505 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
3506 if (ret < 0)
3507 {
3508 /* If the input value is greater than max value of datatype, then also
3509 kstrtou8 fails */
3510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3511 "%s: kstrtou8 failed range [%d - %d]", __func__,
3512 CFG_LFR_FEATURE_ENABLED_MIN,
3513 CFG_LFR_FEATURE_ENABLED_MAX);
3514 ret = -EINVAL;
3515 goto exit;
3516 }
3517 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
3518 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
3519 {
3520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3521 "Roam Mode value %d is out of range"
3522 " (Min: %d Max: %d)", roamMode,
3523 CFG_LFR_FEATURE_ENABLED_MIN,
3524 CFG_LFR_FEATURE_ENABLED_MAX);
3525 ret = -EINVAL;
3526 goto exit;
3527 }
3528
3529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3530 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
3531 /*
3532 * Note that
3533 * SETROAMMODE 0 is to enable LFR while
3534 * SETROAMMODE 1 is to disable LFR, but
3535 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
3536 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
3537 */
3538 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3539 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
3540 else
3541 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
3542
3543 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
3544 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
3545 }
3546 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303547 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003548 {
3549 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3550 char extra[32];
3551 tANI_U8 len = 0;
3552
3553 /*
3554 * roamMode value shall be inverted because the sementics is different.
3555 */
3556 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
3557 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
3558 else
3559 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
3560
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003561 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05303562 len = VOS_MIN(priv_data.total_len, len + 1);
3563 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07003564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3565 "%s: failed to copy data to user buffer", __func__);
3566 ret = -EFAULT;
3567 goto exit;
3568 }
3569 }
3570#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08003571#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003572#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003573 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
3574 {
3575 tANI_U8 *value = command;
3576 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
3577
3578 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
3579 value = value + 13;
3580 /* Convert the value from ascii to integer */
3581 ret = kstrtou8(value, 10, &roamRssiDiff);
3582 if (ret < 0)
3583 {
3584 /* If the input value is greater than max value of datatype, then also
3585 kstrtou8 fails */
3586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3587 "%s: kstrtou8 failed range [%d - %d]", __func__,
3588 CFG_ROAM_RSSI_DIFF_MIN,
3589 CFG_ROAM_RSSI_DIFF_MAX);
3590 ret = -EINVAL;
3591 goto exit;
3592 }
3593
3594 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
3595 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
3596 {
3597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3598 "Roam rssi diff value %d is out of range"
3599 " (Min: %d Max: %d)", roamRssiDiff,
3600 CFG_ROAM_RSSI_DIFF_MIN,
3601 CFG_ROAM_RSSI_DIFF_MAX);
3602 ret = -EINVAL;
3603 goto exit;
3604 }
3605
3606 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3607 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
3608
3609 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
3610 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
3611 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05303612 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003613 {
3614 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
3615 char extra[32];
3616 tANI_U8 len = 0;
3617
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303618 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3619 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
3620 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003621 len = scnprintf(extra, sizeof(extra), "%s %d",
3622 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05303623 len = VOS_MIN(priv_data.total_len, len + 1);
3624 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3626 "%s: failed to copy data to user buffer", __func__);
3627 ret = -EFAULT;
3628 goto exit;
3629 }
3630 }
3631#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003632#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003633 else if (strncmp(command, "GETBAND", 7) == 0)
3634 {
3635 int band = -1;
3636 char extra[32];
3637 tANI_U8 len = 0;
3638 hdd_getBand_helper(pHddCtx, &band);
3639
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303640 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3641 TRACE_CODE_HDD_GETBAND_IOCTL,
3642 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003643 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05303644 len = VOS_MIN(priv_data.total_len, len + 1);
3645 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08003646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3647 "%s: failed to copy data to user buffer", __func__);
3648 ret = -EFAULT;
3649 goto exit;
3650 }
3651 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003652 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
3653 {
3654 tANI_U8 *value = command;
3655 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3656 tANI_U8 numChannels = 0;
3657 eHalStatus status = eHAL_STATUS_SUCCESS;
3658
3659 status = hdd_parse_channellist(value, ChannelList, &numChannels);
3660 if (eHAL_STATUS_SUCCESS != status)
3661 {
3662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3663 "%s: Failed to parse channel list information", __func__);
3664 ret = -EINVAL;
3665 goto exit;
3666 }
3667
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303668 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3669 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
3670 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003671 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
3672 {
3673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3674 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
3675 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
3676 ret = -EINVAL;
3677 goto exit;
3678 }
3679 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
3680 numChannels);
3681 if (eHAL_STATUS_SUCCESS != status)
3682 {
3683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3684 "%s: Failed to update channel list information", __func__);
3685 ret = -EINVAL;
3686 goto exit;
3687 }
3688 }
3689 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
3690 {
3691 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3692 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07003693 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003694 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07003695 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003696
3697 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
3698 ChannelList, &numChannels ))
3699 {
3700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3701 "%s: failed to get roam scan channel list", __func__);
3702 ret = -EFAULT;
3703 goto exit;
3704 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303705 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3706 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
3707 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08003708 /* output channel list is of the format
3709 [Number of roam scan channels][Channel1][Channel2]... */
3710 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003711 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05303712 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08003713 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003714 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
3715 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08003716 }
3717
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05303718 len = VOS_MIN(priv_data.total_len, len + 1);
3719 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08003720 {
3721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3722 "%s: failed to copy data to user buffer", __func__);
3723 ret = -EFAULT;
3724 goto exit;
3725 }
3726 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003727 else if (strncmp(command, "GETCCXMODE", 10) == 0)
3728 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003729 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003730 char extra[32];
3731 tANI_U8 len = 0;
3732
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003733 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003734 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003735 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003736 hdd_is_okc_mode_enabled(pHddCtx) &&
3737 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3738 {
3739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003740 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003741 " hence this operation is not permitted!", __func__);
3742 ret = -EPERM;
3743 goto exit;
3744 }
3745
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003746 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003747 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05303748 len = VOS_MIN(priv_data.total_len, len + 1);
3749 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003750 {
3751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3752 "%s: failed to copy data to user buffer", __func__);
3753 ret = -EFAULT;
3754 goto exit;
3755 }
3756 }
3757 else if (strncmp(command, "GETOKCMODE", 10) == 0)
3758 {
3759 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
3760 char extra[32];
3761 tANI_U8 len = 0;
3762
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003763 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003764 then this operation is not permitted (return FAILURE) */
3765 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003766 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003767 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
3768 {
3769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003770 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07003771 " hence this operation is not permitted!", __func__);
3772 ret = -EPERM;
3773 goto exit;
3774 }
3775
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003776 len = scnprintf(extra, sizeof(extra), "%s %d",
3777 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05303778 len = VOS_MIN(priv_data.total_len, len + 1);
3779 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003780 {
3781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3782 "%s: failed to copy data to user buffer", __func__);
3783 ret = -EFAULT;
3784 goto exit;
3785 }
3786 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07003787 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003788 {
3789 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3790 char extra[32];
3791 tANI_U8 len = 0;
3792
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003793 len = scnprintf(extra, sizeof(extra), "%s %d",
3794 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05303795 len = VOS_MIN(priv_data.total_len, len + 1);
3796 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003797 {
3798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3799 "%s: failed to copy data to user buffer", __func__);
3800 ret = -EFAULT;
3801 goto exit;
3802 }
3803 }
3804 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
3805 {
3806 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
3807 char extra[32];
3808 tANI_U8 len = 0;
3809
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003810 len = scnprintf(extra, sizeof(extra), "%s %d",
3811 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05303812 len = VOS_MIN(priv_data.total_len, len + 1);
3813 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003814 {
3815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3816 "%s: failed to copy data to user buffer", __func__);
3817 ret = -EFAULT;
3818 goto exit;
3819 }
3820 }
3821 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
3822 {
3823 tANI_U8 *value = command;
3824 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
3825
3826 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
3827 value = value + 26;
3828 /* Convert the value from ascii to integer */
3829 ret = kstrtou8(value, 10, &minTime);
3830 if (ret < 0)
3831 {
3832 /* If the input value is greater than max value of datatype, then also
3833 kstrtou8 fails */
3834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3835 "%s: kstrtou8 failed range [%d - %d]", __func__,
3836 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3837 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3838 ret = -EINVAL;
3839 goto exit;
3840 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003841 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
3842 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
3843 {
3844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3845 "scan min channel time value %d is out of range"
3846 " (Min: %d Max: %d)", minTime,
3847 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
3848 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
3849 ret = -EINVAL;
3850 goto exit;
3851 }
3852
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303853 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3854 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
3855 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3857 "%s: Received Command to change channel min time = %d", __func__, minTime);
3858
3859 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
3860 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
3861 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003862 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
3863 {
3864 tANI_U8 *value = command;
3865 tANI_U8 channel = 0;
3866 tANI_U8 dwellTime = 0;
3867 tANI_U8 bufLen = 0;
3868 tANI_U8 *buf = NULL;
3869 tSirMacAddr targetApBssid;
3870 eHalStatus status = eHAL_STATUS_SUCCESS;
3871 struct ieee80211_channel chan;
3872 tANI_U8 finalLen = 0;
3873 tANI_U8 *finalBuf = NULL;
3874 tANI_U8 temp = 0;
3875 u64 cookie;
3876 hdd_station_ctx_t *pHddStaCtx = NULL;
3877 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3878
3879 /* if not associated, no need to send action frame */
3880 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
3881 {
3882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
3883 ret = -EINVAL;
3884 goto exit;
3885 }
3886
3887 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
3888 &dwellTime, &buf, &bufLen);
3889 if (eHAL_STATUS_SUCCESS != status)
3890 {
3891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3892 "%s: Failed to parse send action frame data", __func__);
3893 ret = -EINVAL;
3894 goto exit;
3895 }
3896
3897 /* if the target bssid is different from currently associated AP,
3898 then no need to send action frame */
3899 if (VOS_TRUE != vos_mem_compare(targetApBssid,
3900 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
3901 {
3902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
3903 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003904 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003905 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003906 goto exit;
3907 }
3908
3909 /* if the channel number is different from operating channel then
3910 no need to send action frame */
3911 if (channel != pHddStaCtx->conn_info.operationChannel)
3912 {
3913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3914 "%s: channel(%d) is different from operating channel(%d)",
3915 __func__, channel, pHddStaCtx->conn_info.operationChannel);
3916 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003917 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003918 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003919 goto exit;
3920 }
3921 chan.center_freq = sme_ChnToFreq(channel);
3922
3923 finalLen = bufLen + 24;
3924 finalBuf = vos_mem_malloc(finalLen);
3925 if (NULL == finalBuf)
3926 {
3927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
3928 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07003929 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003930 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003931 goto exit;
3932 }
3933 vos_mem_zero(finalBuf, finalLen);
3934
3935 /* Fill subtype */
3936 temp = SIR_MAC_MGMT_ACTION << 4;
3937 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
3938
3939 /* Fill type */
3940 temp = SIR_MAC_MGMT_FRAME;
3941 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
3942
3943 /* Fill destination address (bssid of the AP) */
3944 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
3945
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003946 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003947 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
3948
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07003949 /* Fill BSSID (AP mac address) */
3950 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003951
3952 /* Fill received buffer from 24th address */
3953 vos_mem_copy(finalBuf + 24, buf, bufLen);
3954
Jeff Johnson11c33152013-04-16 17:52:40 -07003955 /* done with the parsed buffer */
3956 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08003957 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07003958
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303959#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3960 params.chan = &chan;
3961 params.offchan = 0;
3962 params.wait = dwellTime;
3963 params.buf = finalBuf;
3964 params.len = finalLen;
3965 params.no_cck = 1;
3966 params.dont_wait_for_ack = 1;
3967 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
3968#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05303969 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07003970#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3971 &(pAdapter->wdev),
3972#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003973 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07003974#endif
3975 &chan, 0,
3976#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
3977 NL80211_CHAN_HT20, 1,
3978#endif
3979 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003980 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303981#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07003982 vos_mem_free(finalBuf);
3983 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003984 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
3985 {
3986 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
3987 char extra[32];
3988 tANI_U8 len = 0;
3989
3990 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07003991 len = scnprintf(extra, sizeof(extra), "%s %d",
3992 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303993 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3994 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
3995 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05303996 len = VOS_MIN(priv_data.total_len, len + 1);
3997 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07003998 {
3999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4000 "%s: failed to copy data to user buffer", __func__);
4001 ret = -EFAULT;
4002 goto exit;
4003 }
4004 }
4005 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4006 {
4007 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004008 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004009
4010 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4011 value = value + 19;
4012 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004013 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004014 if (ret < 0)
4015 {
4016 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004017 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004019 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004020 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4021 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4022 ret = -EINVAL;
4023 goto exit;
4024 }
4025
4026 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4027 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4028 {
4029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4030 "lfr mode value %d is out of range"
4031 " (Min: %d Max: %d)", maxTime,
4032 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4033 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4034 ret = -EINVAL;
4035 goto exit;
4036 }
4037
4038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4039 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4040
4041 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4042 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4043 }
4044 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4045 {
4046 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4047 char extra[32];
4048 tANI_U8 len = 0;
4049
4050 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004051 len = scnprintf(extra, sizeof(extra), "%s %d",
4052 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304053 len = VOS_MIN(priv_data.total_len, len + 1);
4054 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004055 {
4056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4057 "%s: failed to copy data to user buffer", __func__);
4058 ret = -EFAULT;
4059 goto exit;
4060 }
4061 }
4062 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4063 {
4064 tANI_U8 *value = command;
4065 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4066
4067 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4068 value = value + 16;
4069 /* Convert the value from ascii to integer */
4070 ret = kstrtou16(value, 10, &val);
4071 if (ret < 0)
4072 {
4073 /* If the input value is greater than max value of datatype, then also
4074 kstrtou16 fails */
4075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4076 "%s: kstrtou16 failed range [%d - %d]", __func__,
4077 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4078 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4079 ret = -EINVAL;
4080 goto exit;
4081 }
4082
4083 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4084 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4085 {
4086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4087 "scan home time value %d is out of range"
4088 " (Min: %d Max: %d)", val,
4089 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4090 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4091 ret = -EINVAL;
4092 goto exit;
4093 }
4094
4095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4096 "%s: Received Command to change scan home time = %d", __func__, val);
4097
4098 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4099 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4100 }
4101 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4102 {
4103 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4104 char extra[32];
4105 tANI_U8 len = 0;
4106
4107 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004108 len = scnprintf(extra, sizeof(extra), "%s %d",
4109 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304110 len = VOS_MIN(priv_data.total_len, len + 1);
4111 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004112 {
4113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4114 "%s: failed to copy data to user buffer", __func__);
4115 ret = -EFAULT;
4116 goto exit;
4117 }
4118 }
4119 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4120 {
4121 tANI_U8 *value = command;
4122 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4123
4124 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4125 value = value + 17;
4126 /* Convert the value from ascii to integer */
4127 ret = kstrtou8(value, 10, &val);
4128 if (ret < 0)
4129 {
4130 /* If the input value is greater than max value of datatype, then also
4131 kstrtou8 fails */
4132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4133 "%s: kstrtou8 failed range [%d - %d]", __func__,
4134 CFG_ROAM_INTRA_BAND_MIN,
4135 CFG_ROAM_INTRA_BAND_MAX);
4136 ret = -EINVAL;
4137 goto exit;
4138 }
4139
4140 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4141 (val > CFG_ROAM_INTRA_BAND_MAX))
4142 {
4143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4144 "intra band mode value %d is out of range"
4145 " (Min: %d Max: %d)", val,
4146 CFG_ROAM_INTRA_BAND_MIN,
4147 CFG_ROAM_INTRA_BAND_MAX);
4148 ret = -EINVAL;
4149 goto exit;
4150 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4152 "%s: Received Command to change intra band = %d", __func__, val);
4153
4154 pHddCtx->cfg_ini->nRoamIntraBand = val;
4155 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
4156 }
4157 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
4158 {
4159 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
4160 char extra[32];
4161 tANI_U8 len = 0;
4162
4163 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004164 len = scnprintf(extra, sizeof(extra), "%s %d",
4165 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05304166 len = VOS_MIN(priv_data.total_len, len + 1);
4167 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004168 {
4169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4170 "%s: failed to copy data to user buffer", __func__);
4171 ret = -EFAULT;
4172 goto exit;
4173 }
4174 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004175 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
4176 {
4177 tANI_U8 *value = command;
4178 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
4179
4180 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
4181 value = value + 15;
4182 /* Convert the value from ascii to integer */
4183 ret = kstrtou8(value, 10, &nProbes);
4184 if (ret < 0)
4185 {
4186 /* If the input value is greater than max value of datatype, then also
4187 kstrtou8 fails */
4188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4189 "%s: kstrtou8 failed range [%d - %d]", __func__,
4190 CFG_ROAM_SCAN_N_PROBES_MIN,
4191 CFG_ROAM_SCAN_N_PROBES_MAX);
4192 ret = -EINVAL;
4193 goto exit;
4194 }
4195
4196 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
4197 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
4198 {
4199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4200 "NProbes value %d is out of range"
4201 " (Min: %d Max: %d)", nProbes,
4202 CFG_ROAM_SCAN_N_PROBES_MIN,
4203 CFG_ROAM_SCAN_N_PROBES_MAX);
4204 ret = -EINVAL;
4205 goto exit;
4206 }
4207
4208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4209 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
4210
4211 pHddCtx->cfg_ini->nProbes = nProbes;
4212 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
4213 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304214 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004215 {
4216 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
4217 char extra[32];
4218 tANI_U8 len = 0;
4219
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004220 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05304221 len = VOS_MIN(priv_data.total_len, len + 1);
4222 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4224 "%s: failed to copy data to user buffer", __func__);
4225 ret = -EFAULT;
4226 goto exit;
4227 }
4228 }
4229 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
4230 {
4231 tANI_U8 *value = command;
4232 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
4233
4234 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
4235 /* input value is in units of msec */
4236 value = value + 20;
4237 /* Convert the value from ascii to integer */
4238 ret = kstrtou16(value, 10, &homeAwayTime);
4239 if (ret < 0)
4240 {
4241 /* If the input value is greater than max value of datatype, then also
4242 kstrtou8 fails */
4243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4244 "%s: kstrtou8 failed range [%d - %d]", __func__,
4245 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4246 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4247 ret = -EINVAL;
4248 goto exit;
4249 }
4250
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004251 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
4252 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
4253 {
4254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4255 "homeAwayTime value %d is out of range"
4256 " (Min: %d Max: %d)", homeAwayTime,
4257 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
4258 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
4259 ret = -EINVAL;
4260 goto exit;
4261 }
4262
4263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4264 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07004265 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
4266 {
4267 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
4268 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
4269 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004270 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304271 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004272 {
4273 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
4274 char extra[32];
4275 tANI_U8 len = 0;
4276
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004277 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05304278 len = VOS_MIN(priv_data.total_len, len + 1);
4279 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4281 "%s: failed to copy data to user buffer", __func__);
4282 ret = -EFAULT;
4283 goto exit;
4284 }
4285 }
4286 else if (strncmp(command, "REASSOC", 7) == 0)
4287 {
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05304288 ret = hdd_parse_reassoc(pAdapter, command);
4289 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004290 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07004291 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004292 else if (strncmp(command, "SETWESMODE", 10) == 0)
4293 {
4294 tANI_U8 *value = command;
4295 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
4296
4297 /* Move pointer to ahead of SETWESMODE<delimiter> */
4298 value = value + 11;
4299 /* Convert the value from ascii to integer */
4300 ret = kstrtou8(value, 10, &wesMode);
4301 if (ret < 0)
4302 {
4303 /* If the input value is greater than max value of datatype, then also
4304 kstrtou8 fails */
4305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4306 "%s: kstrtou8 failed range [%d - %d]", __func__,
4307 CFG_ENABLE_WES_MODE_NAME_MIN,
4308 CFG_ENABLE_WES_MODE_NAME_MAX);
4309 ret = -EINVAL;
4310 goto exit;
4311 }
4312
4313 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
4314 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
4315 {
4316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4317 "WES Mode value %d is out of range"
4318 " (Min: %d Max: %d)", wesMode,
4319 CFG_ENABLE_WES_MODE_NAME_MIN,
4320 CFG_ENABLE_WES_MODE_NAME_MAX);
4321 ret = -EINVAL;
4322 goto exit;
4323 }
4324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4325 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
4326
4327 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
4328 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
4329 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304330 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004331 {
4332 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
4333 char extra[32];
4334 tANI_U8 len = 0;
4335
Arif Hussain826d9412013-11-12 16:44:54 -08004336 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05304337 len = VOS_MIN(priv_data.total_len, len + 1);
4338 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4340 "%s: failed to copy data to user buffer", __func__);
4341 ret = -EFAULT;
4342 goto exit;
4343 }
4344 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004345#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004346#ifdef FEATURE_WLAN_LFR
4347 else if (strncmp(command, "SETFASTROAM", 11) == 0)
4348 {
4349 tANI_U8 *value = command;
4350 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4351
4352 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4353 value = value + 12;
4354 /* Convert the value from ascii to integer */
4355 ret = kstrtou8(value, 10, &lfrMode);
4356 if (ret < 0)
4357 {
4358 /* If the input value is greater than max value of datatype, then also
4359 kstrtou8 fails */
4360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4361 "%s: kstrtou8 failed range [%d - %d]", __func__,
4362 CFG_LFR_FEATURE_ENABLED_MIN,
4363 CFG_LFR_FEATURE_ENABLED_MAX);
4364 ret = -EINVAL;
4365 goto exit;
4366 }
4367
4368 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4369 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
4370 {
4371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4372 "lfr mode value %d is out of range"
4373 " (Min: %d Max: %d)", lfrMode,
4374 CFG_LFR_FEATURE_ENABLED_MIN,
4375 CFG_LFR_FEATURE_ENABLED_MAX);
4376 ret = -EINVAL;
4377 goto exit;
4378 }
4379
4380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4381 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
4382
4383 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
4384 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
4385 }
4386#endif
4387#ifdef WLAN_FEATURE_VOWIFI_11R
4388 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
4389 {
4390 tANI_U8 *value = command;
4391 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
4392
4393 /* Move pointer to ahead of SETFASTROAM<delimiter> */
4394 value = value + 18;
4395 /* Convert the value from ascii to integer */
4396 ret = kstrtou8(value, 10, &ft);
4397 if (ret < 0)
4398 {
4399 /* If the input value is greater than max value of datatype, then also
4400 kstrtou8 fails */
4401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4402 "%s: kstrtou8 failed range [%d - %d]", __func__,
4403 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4404 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4405 ret = -EINVAL;
4406 goto exit;
4407 }
4408
4409 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
4410 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
4411 {
4412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4413 "ft mode value %d is out of range"
4414 " (Min: %d Max: %d)", ft,
4415 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
4416 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
4417 ret = -EINVAL;
4418 goto exit;
4419 }
4420
4421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4422 "%s: Received Command to change ft mode = %d", __func__, ft);
4423
4424 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
4425 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
4426 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304427 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
4428 {
4429 tANI_U8 *value = command;
4430 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304431
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304432 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
4433 value = value + 15;
4434 /* Convert the value from ascii to integer */
4435 ret = kstrtou8(value, 10, &dfsScanMode);
4436 if (ret < 0)
4437 {
4438 /* If the input value is greater than max value of
4439 datatype, then also kstrtou8 fails
4440 */
4441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4442 "%s: kstrtou8 failed range [%d - %d]", __func__,
4443 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4444 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4445 ret = -EINVAL;
4446 goto exit;
4447 }
4448
4449 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
4450 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
4451 {
4452 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4453 "dfsScanMode value %d is out of range"
4454 " (Min: %d Max: %d)", dfsScanMode,
4455 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
4456 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
4457 ret = -EINVAL;
4458 goto exit;
4459 }
4460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4461 "%s: Received Command to Set DFS Scan Mode = %d",
4462 __func__, dfsScanMode);
4463
4464 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
4465 }
4466 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
4467 {
4468 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
4469 char extra[32];
4470 tANI_U8 len = 0;
4471
4472 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05304473 len = VOS_MIN(priv_data.total_len, len + 1);
4474 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05304475 {
4476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4477 "%s: failed to copy data to user buffer", __func__);
4478 ret = -EFAULT;
4479 goto exit;
4480 }
4481 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304482 else if (strncmp(command, "FASTREASSOC", 11) == 0)
4483 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05304484 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
4485 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304486 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05304487 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004488#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004489#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004490 else if (strncmp(command, "SETCCXMODE", 10) == 0)
4491 {
4492 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004493 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004494
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004495 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004496 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004497 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004498 hdd_is_okc_mode_enabled(pHddCtx) &&
4499 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4500 {
4501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004502 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004503 " hence this operation is not permitted!", __func__);
4504 ret = -EPERM;
4505 goto exit;
4506 }
4507
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004508 /* Move pointer to ahead of SETCCXMODE<delimiter> */
4509 value = value + 11;
4510 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004511 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004512 if (ret < 0)
4513 {
4514 /* If the input value is greater than max value of datatype, then also
4515 kstrtou8 fails */
4516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4517 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004518 CFG_ESE_FEATURE_ENABLED_MIN,
4519 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004520 ret = -EINVAL;
4521 goto exit;
4522 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004523 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
4524 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004525 {
4526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004527 "Ese mode value %d is out of range"
4528 " (Min: %d Max: %d)", eseMode,
4529 CFG_ESE_FEATURE_ENABLED_MIN,
4530 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004531 ret = -EINVAL;
4532 goto exit;
4533 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004535 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004536
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004537 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
4538 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004539 }
4540#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004541 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
4542 {
4543 tANI_U8 *value = command;
4544 tANI_BOOLEAN roamScanControl = 0;
4545
4546 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
4547 value = value + 19;
4548 /* Convert the value from ascii to integer */
4549 ret = kstrtou8(value, 10, &roamScanControl);
4550 if (ret < 0)
4551 {
4552 /* If the input value is greater than max value of datatype, then also
4553 kstrtou8 fails */
4554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4555 "%s: kstrtou8 failed ", __func__);
4556 ret = -EINVAL;
4557 goto exit;
4558 }
4559
4560 if (0 != roamScanControl)
4561 {
4562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4563 "roam scan control invalid value = %d",
4564 roamScanControl);
4565 ret = -EINVAL;
4566 goto exit;
4567 }
4568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4569 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
4570
4571 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
4572 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004573#ifdef FEATURE_WLAN_OKC
4574 else if (strncmp(command, "SETOKCMODE", 10) == 0)
4575 {
4576 tANI_U8 *value = command;
4577 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
4578
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004579 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004580 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004581 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004582 hdd_is_okc_mode_enabled(pHddCtx) &&
4583 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4584 {
4585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004586 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004587 " hence this operation is not permitted!", __func__);
4588 ret = -EPERM;
4589 goto exit;
4590 }
4591
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004592 /* Move pointer to ahead of SETOKCMODE<delimiter> */
4593 value = value + 11;
4594 /* Convert the value from ascii to integer */
4595 ret = kstrtou8(value, 10, &okcMode);
4596 if (ret < 0)
4597 {
4598 /* If the input value is greater than max value of datatype, then also
4599 kstrtou8 fails */
4600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4601 "%s: kstrtou8 failed range [%d - %d]", __func__,
4602 CFG_OKC_FEATURE_ENABLED_MIN,
4603 CFG_OKC_FEATURE_ENABLED_MAX);
4604 ret = -EINVAL;
4605 goto exit;
4606 }
4607
4608 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
4609 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
4610 {
4611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4612 "Okc mode value %d is out of range"
4613 " (Min: %d Max: %d)", okcMode,
4614 CFG_OKC_FEATURE_ENABLED_MIN,
4615 CFG_OKC_FEATURE_ENABLED_MAX);
4616 ret = -EINVAL;
4617 goto exit;
4618 }
4619
4620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4621 "%s: Received Command to change okc mode = %d", __func__, okcMode);
4622
4623 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
4624 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07004625#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304626 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004627 {
4628 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
4629 char extra[32];
4630 tANI_U8 len = 0;
4631
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004632 len = scnprintf(extra, sizeof(extra), "%s %d",
4633 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05304634 len = VOS_MIN(priv_data.total_len, len + 1);
4635 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4637 "%s: failed to copy data to user buffer", __func__);
4638 ret = -EFAULT;
4639 goto exit;
4640 }
4641 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05304642#ifdef WLAN_FEATURE_PACKET_FILTERING
4643 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
4644 {
4645 tANI_U8 filterType = 0;
4646 tANI_U8 *value = command;
4647
4648 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
4649 value = value + 22;
4650
4651 /* Convert the value from ascii to integer */
4652 ret = kstrtou8(value, 10, &filterType);
4653 if (ret < 0)
4654 {
4655 /* If the input value is greater than max value of datatype,
4656 * then also kstrtou8 fails
4657 */
4658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4659 "%s: kstrtou8 failed range ", __func__);
4660 ret = -EINVAL;
4661 goto exit;
4662 }
4663
4664 if (filterType != 0 && filterType != 1)
4665 {
4666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4667 "%s: Accepted Values are 0 and 1 ", __func__);
4668 ret = -EINVAL;
4669 goto exit;
4670 }
4671 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
4672 pAdapter->sessionId);
4673 }
4674#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304675 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
4676 {
Kiet Lamad161252014-07-22 11:23:32 -07004677 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304678 int ret;
4679
Kiet Lamad161252014-07-22 11:23:32 -07004680 dhcpPhase = command + 11;
4681 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304682 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004684 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304685
4686 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07004687
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05304688 ret = wlan_hdd_scan_abort(pAdapter);
4689 if (ret < 0)
4690 {
4691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4692 FL("failed to abort existing scan %d"), ret);
4693 }
4694
Kiet Lamad161252014-07-22 11:23:32 -07004695 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
4696 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304697 }
Kiet Lamad161252014-07-22 11:23:32 -07004698 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304699 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05304700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07004701 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05304702
4703 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07004704
4705 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
4706 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05304707 }
4708 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004709 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
4710 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304711 hddLog(LOG1,
4712 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304713 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004714 }
4715 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
4716 {
Abhishek Singh58749d62016-02-03 15:27:20 +05304717 hddLog(LOG1,
4718 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05304719 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07004720 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304721 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
4722 {
4723 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4724 char extra[32];
4725 tANI_U8 len = 0;
4726
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304727 memset(extra, 0, sizeof(extra));
4728 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05304729 len = VOS_MIN(priv_data.total_len, len + 1);
4730 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4732 "%s: failed to copy data to user buffer", __func__);
4733 ret = -EFAULT;
4734 goto exit;
4735 }
4736 ret = len;
4737 }
4738 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
4739 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05304740 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05304741 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004742 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
4743 {
4744 tANI_U8 filterType = 0;
4745 tANI_U8 *value;
4746 value = command + 9;
4747
4748 /* Convert the value from ascii to integer */
4749 ret = kstrtou8(value, 10, &filterType);
4750 if (ret < 0)
4751 {
4752 /* If the input value is greater than max value of datatype,
4753 * then also kstrtou8 fails
4754 */
4755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4756 "%s: kstrtou8 failed range ", __func__);
4757 ret = -EINVAL;
4758 goto exit;
4759 }
4760 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
4761 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
4762 {
4763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4764 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
4765 " 2-Sink ", __func__);
4766 ret = -EINVAL;
4767 goto exit;
4768 }
4769 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
4770 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05304771 pScanInfo = &pHddCtx->scan_info;
4772 if (filterType && pScanInfo != NULL &&
4773 pHddCtx->scan_info.mScanPending)
4774 {
4775 /*Miracast Session started. Abort Scan */
4776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4777 "%s, Aborting Scan For Miracast",__func__);
4778 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
4779 eCSR_SCAN_ABORT_DEFAULT);
4780 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004781 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05304782 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07004783 }
Leo Chang614d2072013-08-22 14:59:44 -07004784 else if (strncmp(command, "SETMCRATE", 9) == 0)
4785 {
Leo Chang614d2072013-08-22 14:59:44 -07004786 tANI_U8 *value = command;
4787 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07004788 tSirRateUpdateInd *rateUpdate;
4789 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07004790
4791 /* Only valid for SAP mode */
4792 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
4793 {
4794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4795 "%s: SAP mode is not running", __func__);
4796 ret = -EFAULT;
4797 goto exit;
4798 }
4799
4800 /* Move pointer to ahead of SETMCRATE<delimiter> */
4801 /* input value is in units of hundred kbps */
4802 value = value + 10;
4803 /* Convert the value from ascii to integer, decimal base */
4804 ret = kstrtouint(value, 10, &targetRate);
4805
Leo Chang1f98cbd2013-10-17 15:03:52 -07004806 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
4807 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07004808 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07004809 hddLog(VOS_TRACE_LEVEL_ERROR,
4810 "%s: SETMCRATE indication alloc fail", __func__);
4811 ret = -EFAULT;
4812 goto exit;
4813 }
4814 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
4815
4816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4817 "MC Target rate %d", targetRate);
4818 /* Ignore unicast */
4819 rateUpdate->ucastDataRate = -1;
4820 rateUpdate->mcastDataRate24GHz = targetRate;
4821 rateUpdate->mcastDataRate5GHz = targetRate;
4822 rateUpdate->mcastDataRate24GHzTxFlag = 0;
4823 rateUpdate->mcastDataRate5GHzTxFlag = 0;
4824 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
4825 if (eHAL_STATUS_SUCCESS != status)
4826 {
4827 hddLog(VOS_TRACE_LEVEL_ERROR,
4828 "%s: SET_MC_RATE failed", __func__);
4829 vos_mem_free(rateUpdate);
4830 ret = -EFAULT;
4831 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07004832 }
4833 }
Rajeev79dbe4c2013-10-05 11:03:42 +05304834#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08004835 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05304836 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08004837 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05304838 }
4839#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05304840#ifdef WLAN_FEATURE_RMC
4841 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
4842 (WLAN_HDD_IBSS == pAdapter->device_mode))
4843 {
4844 int i = 0;
4845 tANI_U8 *ibss_ie;
4846 tANI_U32 command_len;
4847 tANI_U8 *value = command;
4848 tHalHandle hHal = pHddCtx->hHal;
4849 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4850 tANI_U32 ibss_ie_length;
4851 tANI_U32 len, present;
4852 tANI_U8 *addIE;
4853 tANI_U8 *addIEData;
4854
4855 hddLog(LOG1,
4856 FL(" received command %s"),((char *) value));
4857 /* validate argument of command */
4858 if (strlen(value) <= 21)
4859 {
4860 hddLog(LOGE,
4861 FL("No arguements in command length %zu"), strlen(value));
4862 ret = -EFAULT;
4863 goto exit;
4864 }
4865
4866 /* moving to arguments of commands */
4867 value = value + 21;
4868 command_len = strlen(value);
4869
4870 /* oui_data can't be less than 3 bytes */
4871 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
4872 {
4873 hddLog(LOGE,
4874 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
4875 command_len);
4876 ret = -EFAULT;
4877 goto exit;
4878 }
4879 ibss_ie = vos_mem_malloc(command_len);
4880 if (!ibss_ie) {
4881 hddLog(LOGE,
4882 FL("Could not allocate memory for command length %d"),
4883 command_len);
4884 ret = -ENOMEM;
4885 goto exit;
4886 }
4887 vos_mem_zero(ibss_ie, command_len);
4888
4889 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
4890 command_len);
4891 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
4892 hddLog(LOGE, FL("Could not parse command %s return length %d"),
4893 value, ibss_ie_length);
4894 ret = -EFAULT;
4895 vos_mem_free(ibss_ie);
4896 goto exit;
4897 }
4898
4899 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
4900 while (i < ibss_ie_length)
4901 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
4902
4903 /* Populate Vendor IE in Beacon */
4904 if ((ccmCfgGetInt(hHal,
4905 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
4906 &present)) != eHAL_STATUS_SUCCESS)
4907 {
4908 hddLog(LOGE,
4909 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
4910 ret = -EFAULT;
4911 vos_mem_free(ibss_ie);
4912 goto exit;
4913 }
4914
4915 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4916 if (!addIE) {
4917 hddLog(LOGE,
4918 FL("Could not allocate memory for command length %d"),
4919 command_len);
4920 vos_mem_free(ibss_ie);
4921 ret = -ENOMEM;
4922 goto exit;
4923 }
4924 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
4925
4926 if (present)
4927 {
4928 if ((wlan_cfgGetStrLen(pMac,
4929 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
4930 {
4931 hddLog(LOGE,
4932 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
4933 ret = -EFAULT;
4934 vos_mem_free(ibss_ie);
4935 vos_mem_free(addIE);
4936 goto exit;
4937 }
4938
4939 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
4940 ((len + ibss_ie_length) <=
4941 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
4942 {
4943 if ((ccmCfgGetStr(hHal,
4944 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
4945 != eHAL_STATUS_SUCCESS)
4946 {
4947 hddLog(LOGE,
4948 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
4949 ret = -EFAULT;
4950 vos_mem_free(ibss_ie);
4951 vos_mem_free(addIE);
4952 goto exit;
4953 }
4954 else
4955 {
4956 /* Curruntly only WPA IE is added before Vendor IE
4957 * so we can blindly place the Vendor IE after WPA
4958 * IE. If no WPA IE found replace all with Vendor IE.
4959 */
4960 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
4961 }
4962 }
4963 else
4964 {
4965 hddLog(LOGE,
4966 FL("IE len exceed limit len %d,ibss_ie_length %d "),
4967 len, ibss_ie_length);
4968 ret = -EFAULT;
4969 vos_mem_free(addIE);
4970 vos_mem_free(ibss_ie);
4971 goto exit;
4972 }
4973 }
4974 else {
4975 len = 0;
4976 }
4977
4978 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
4979 len += ibss_ie_length;
4980
4981 if (ccmCfgSetStr(hHal,
4982 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
4983 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4984 {
4985 hddLog(LOGE,
4986 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
4987 ret = -EFAULT;
4988 vos_mem_free(ibss_ie);
4989 vos_mem_free(addIE);
4990 goto exit;
4991 }
4992 vos_mem_free(addIE);
4993 if (ccmCfgSetInt(hHal,
4994 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4995 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
4996 {
4997 hddLog(LOGE,
4998 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
4999 ret = -EFAULT;
5000 vos_mem_free(ibss_ie);
5001 goto exit;
5002 }
5003
5004 /* Populate Vendor IE in probe resp */
5005 if ((ccmCfgGetInt(hHal,
5006 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
5007 &present)) != eHAL_STATUS_SUCCESS)
5008 {
5009 hddLog(LOGE,
5010 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5011 ret = -EFAULT;
5012 vos_mem_free(ibss_ie);
5013 goto exit;
5014 }
5015
5016 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5017 if (!addIEData) {
5018 hddLog(LOGE,
5019 FL("Could not allocate memory for command length %d"),
5020 command_len);
5021 vos_mem_free(ibss_ie);
5022 ret = -ENOMEM;
5023 goto exit;
5024 }
5025 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
5026
5027 if (present) {
5028 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
5029 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
5030 hddLog(LOGE,
5031 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5032 ret = -EFAULT;
5033 vos_mem_free(ibss_ie);
5034 vos_mem_free(addIEData);
5035 goto exit;
5036 }
5037 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
5038 (ibss_ie_length + len) <=
5039 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
5040
5041 if ((ccmCfgGetStr(hHal,
5042 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
5043 != eHAL_STATUS_SUCCESS) {
5044 hddLog(LOGE,
5045 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5046 ret = -EFAULT;
5047 vos_mem_free(ibss_ie);
5048 vos_mem_free(addIEData);
5049 goto exit;
5050 }
5051 else {
5052 /* Curruntly only WPA IE is added before Vendor IE
5053 * so we can blindly place the Vendor IE after WPA
5054 * IE. If no WPA IE found replace all with Vendor IE.
5055 */
5056 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
5057 }
5058 }
5059 else
5060 {
5061 hddLog(LOGE,
5062 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5063 len, ibss_ie_length);
5064 ret = -EFAULT;
5065 vos_mem_free(addIEData);
5066 vos_mem_free(ibss_ie);
5067 goto exit;
5068 }
5069 } /* probe rsp ADD IE present */
5070 else {
5071 /* probe rsp add IE is not present */
5072 len = 0;
5073 }
5074
5075 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
5076 len += ibss_ie_length;
5077
5078 vos_mem_free(ibss_ie);
5079
5080 if (ccmCfgSetStr(hHal,
5081 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5082 (tANI_U8*)(addIEData),
5083 len, NULL,
5084 eANI_BOOLEAN_FALSE)
5085 == eHAL_STATUS_FAILURE) {
5086 hddLog(LOGE,
5087 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
5088 ret = -EFAULT;
5089 vos_mem_free(addIEData);
5090 goto exit;
5091 }
5092 vos_mem_free(addIEData);
5093 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5094 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5095 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5096 {
5097 hddLog(LOGE,
5098 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
5099 ret = -EFAULT;
5100 goto exit;
5101 }
5102 }
5103 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
5104 {
5105 tANI_U8 *value = command;
5106 tANI_U8 ucRmcEnable = 0;
5107 int status;
5108
5109 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5110 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5111 {
5112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5113 "Received SETRMCENABLE command in invalid mode %d "
5114 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
5115 pAdapter->device_mode);
5116 ret = -EINVAL;
5117 goto exit;
5118 }
5119
5120 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
5121 if (status)
5122 {
5123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5124 "Invalid SETRMCENABLE command ");
5125 ret = -EINVAL;
5126 goto exit;
5127 }
5128
5129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5130 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
5131
5132 if (TRUE == ucRmcEnable)
5133 {
5134 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
5135 pAdapter->sessionId );
5136 }
5137 else if(FALSE == ucRmcEnable)
5138 {
5139 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
5140 pAdapter->sessionId );
5141 }
5142 else
5143 {
5144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5145 "Invalid SETRMCENABLE command %d", ucRmcEnable);
5146 ret = -EINVAL;
5147 goto exit;
5148 }
5149
5150 if (VOS_STATUS_SUCCESS != status)
5151 {
5152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5153 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
5154 status);
5155 ret = -EINVAL;
5156 goto exit;
5157 }
5158 }
5159 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
5160 {
5161 tANI_U8 *value = command;
5162 tANI_U32 uActionPeriod = 0;
5163 int status;
5164
5165 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5166 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5167 {
5168 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5169 "Received SETRMC command in invalid mode %d "
5170 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5171 pAdapter->device_mode);
5172 ret = -EINVAL;
5173 goto exit;
5174 }
5175
5176 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
5177 if (status)
5178 {
5179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5180 "Invalid SETRMCACTIONPERIOD command ");
5181 ret = -EINVAL;
5182 goto exit;
5183 }
5184
5185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5186 "%s: uActionPeriod %d ", __func__, uActionPeriod);
5187
5188 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
5189 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
5190 {
5191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5192 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
5193 ret = -EINVAL;
5194 goto exit;
5195 }
5196
5197 }
5198 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
5199 {
5200 /* Peer Info All Command */
5201 int status = eHAL_STATUS_SUCCESS;
5202 hdd_station_ctx_t *pHddStaCtx = NULL;
5203 char *extra = NULL;
5204 int idx = 0, length = 0;
5205 v_MACADDR_t *macAddr;
5206 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
5207
5208 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5209 {
5210 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5211 }
5212 else
5213 {
5214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5215 "%s: pAdapter is not valid for this device mode",
5216 __func__);
5217 ret = -EINVAL;
5218 goto exit;
5219 }
5220
5221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5222 "%s: Received GETIBSSPEERINFOALL Command", __func__);
5223
5224
5225 /* Handle the command */
5226 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
5227 if (VOS_STATUS_SUCCESS == status)
5228 {
5229 /* The variable extra needed to be allocated on the heap since
5230 * amount of memory required to copy the data for 32 devices
5231 * exceeds the size of 1024 bytes of default stack size. On
5232 * 64 bit devices, the default max stack size of 2048 bytes
5233 */
5234 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
5235
5236 if (NULL == extra)
5237 {
5238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5239 "%s:kmalloc failed", __func__);
5240 ret = -EINVAL;
5241 goto exit;
5242 }
5243
5244 /* Copy number of stations */
5245 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
5246 pHddStaCtx->ibss_peer_info.numIBSSPeers);
5247 numOfBytestoPrint = length;
5248 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
5249 {
5250 macAddr =
5251 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
5252 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5253 if (NULL != macAddr)
5254 {
5255 txRateMbps =
5256 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
5257
5258 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
5259 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
5260 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
5261 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
5262 (int)txRateMbps,
5263 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
5264 }
5265 else
5266 {
5267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5268 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
5269 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
5270 }
5271
5272 /*
5273 * VOS_TRACE() macro has limitation of 512 bytes for the print
5274 * buffer. Hence printing the data in two chunks. The first chunk
5275 * will have the data for 16 devices and the second chunk will
5276 * have the rest.
5277 */
5278 if (idx < NUM_OF_STA_DATA_TO_PRINT)
5279 {
5280 numOfBytestoPrint = length;
5281 }
5282 }
5283
5284 /*
5285 * Copy the data back into buffer, if the data to copy is
5286 * morethan 512 bytes than we will split the data and do
5287 * it in two shots
5288 */
5289 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
5290 {
5291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5292 "%s: Copy into user data buffer failed ", __func__);
5293 ret = -EFAULT;
5294 kfree(extra);
5295 goto exit;
5296 }
5297 priv_data.buf[numOfBytestoPrint] = '\0';
5298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5299 "%s", priv_data.buf);
5300
5301 if (length > numOfBytestoPrint)
5302 {
5303 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
5304 extra + numOfBytestoPrint,
5305 length - numOfBytestoPrint + 1))
5306 {
5307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5308 "%s: Copy into user data buffer failed ", __func__);
5309 ret = -EFAULT;
5310 kfree(extra);
5311 goto exit;
5312 }
5313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5314 "%s", &priv_data.buf[numOfBytestoPrint]);
5315 }
5316
5317 /* Free temporary buffer */
5318 kfree(extra);
5319 }
5320
5321 else
5322 {
5323 /* Command failed, log error */
5324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5325 "%s: GETIBSSPEERINFOALL command failed with status code %d",
5326 __func__, status);
5327 ret = -EINVAL;
5328 goto exit;
5329 }
5330 ret = 0;
5331 }
5332 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
5333 {
5334 /* Peer Info <Peer Addr> command */
5335 tANI_U8 *value = command;
5336 VOS_STATUS status;
5337 hdd_station_ctx_t *pHddStaCtx = NULL;
5338 char extra[128] = { 0 };
5339 v_U32_t length = 0;
5340 v_U8_t staIdx = 0;
5341 v_U32_t txRateMbps = 0;
5342 v_MACADDR_t peerMacAddr;
5343
5344 if (WLAN_HDD_IBSS == pAdapter->device_mode)
5345 {
5346 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5347 }
5348 else
5349 {
5350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5351 "%s: pAdapter is not valid for this device mode",
5352 __func__);
5353 ret = -EINVAL;
5354 goto exit;
5355 }
5356
5357 /* if there are no peers, no need to continue with the command */
5358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5359 "%s: Received GETIBSSPEERINFO Command", __func__);
5360
5361 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
5362 {
5363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5364 "%s:No IBSS Peers coalesced", __func__);
5365 ret = -EINVAL;
5366 goto exit;
5367 }
5368
5369 /* Parse the incoming command buffer */
5370 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
5371 if (VOS_STATUS_SUCCESS != status)
5372 {
5373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5374 "%s: Invalid GETIBSSPEERINFO command", __func__);
5375 ret = -EINVAL;
5376 goto exit;
5377 }
5378
5379 /* Get station index for the peer mac address */
5380 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
5381
5382 if (staIdx > HDD_MAX_NUM_IBSS_STA)
5383 {
5384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5385 "%s: Invalid StaIdx %d returned", __func__, staIdx);
5386 ret = -EINVAL;
5387 goto exit;
5388 }
5389
5390 /* Handle the command */
5391 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
5392 if (VOS_STATUS_SUCCESS == status)
5393 {
5394 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
5395 txRateMbps = (txRate * 500 * 1000)/1000000;
5396
5397 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
5398 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
5399
5400 /* Copy the data back into buffer */
5401 if (copy_to_user(priv_data.buf, &extra, length+ 1))
5402 {
5403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5404 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
5405 __func__);
5406 ret = -EFAULT;
5407 goto exit;
5408 }
5409 }
5410 else
5411 {
5412 /* Command failed, log error */
5413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5414 "%s: GETIBSSPEERINFO command failed with status code %d",
5415 __func__, status);
5416 ret = -EINVAL;
5417 goto exit;
5418 }
5419
5420 /* Success ! */
5421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
5422 "%s", priv_data.buf);
5423 ret = 0;
5424 }
5425 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
5426 {
5427 tANI_U8 *value = command;
5428 tANI_U32 uRate = 0;
5429 tTxrateinfoflags txFlags = 0;
5430 tSirRateUpdateInd *rateUpdateParams;
5431 int status;
5432
5433 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
5434 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
5435 {
5436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5437 "Received SETRMCTXRATE command in invalid mode %d "
5438 "SETRMC command is only allowed in IBSS or SOFTAP mode",
5439 pAdapter->device_mode);
5440 ret = -EINVAL;
5441 goto exit;
5442 }
5443
5444 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
5445 if (status)
5446 {
5447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5448 "Invalid SETRMCTXRATE command ");
5449 ret = -EINVAL;
5450 goto exit;
5451 }
5452
5453 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
5454 if (NULL == rateUpdateParams)
5455 {
5456 ret = -EINVAL;
5457 goto exit;
5458 }
5459
5460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5461 "%s: uRate %d ", __func__, uRate);
5462
5463 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
5464
5465 /* -1 implies ignore this param */
5466 rateUpdateParams->ucastDataRate = -1;
5467
5468 /*
5469 * Fill the user specifieed RMC rate param
5470 * and the derived tx flags.
5471 */
5472 rateUpdateParams->rmcDataRate = uRate;
5473 rateUpdateParams->rmcDataRateTxFlag = txFlags;
5474
5475 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
5476 }
5477 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
5478 {
5479 char *value;
5480 tANI_U8 tx_fail_count = 0;
5481 tANI_U16 pid = 0;
5482
5483 value = command;
5484
5485 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
5486
5487 if (0 != ret)
5488 {
5489 hddLog(VOS_TRACE_LEVEL_INFO,
5490 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
5491 __func__);
5492 goto exit;
5493 }
5494
5495 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
5496 __func__, tx_fail_count, pid);
5497
5498 if (0 == tx_fail_count)
5499 {
5500 // Disable TX Fail Indication
5501 if (eHAL_STATUS_SUCCESS ==
5502 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5503 tx_fail_count,
5504 NULL))
5505 {
5506 cesium_pid = 0;
5507 }
5508 else
5509 {
5510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5511 "%s: failed to disable TX Fail Event ", __func__);
5512 ret = -EINVAL;
5513 }
5514 }
5515 else
5516 {
5517 if (eHAL_STATUS_SUCCESS ==
5518 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
5519 tx_fail_count,
5520 (void*)hdd_tx_fail_ind_callback))
5521 {
5522 cesium_pid = pid;
5523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5524 "%s: Registered Cesium pid %u", __func__,
5525 cesium_pid);
5526 }
5527 else
5528 {
5529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5530 "%s: Failed to enable TX Fail Monitoring", __func__);
5531 ret = -EINVAL;
5532 }
5533 }
5534 }
5535
5536#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005537#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005538 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
5539 {
5540 tANI_U8 *value = command;
5541 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
5542 tANI_U8 numChannels = 0;
5543 eHalStatus status = eHAL_STATUS_SUCCESS;
5544
5545 status = hdd_parse_channellist(value, ChannelList, &numChannels);
5546 if (eHAL_STATUS_SUCCESS != status)
5547 {
5548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5549 "%s: Failed to parse channel list information", __func__);
5550 ret = -EINVAL;
5551 goto exit;
5552 }
5553
5554 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
5555 {
5556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5557 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
5558 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
5559 ret = -EINVAL;
5560 goto exit;
5561 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005562 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005563 ChannelList,
5564 numChannels);
5565 if (eHAL_STATUS_SUCCESS != status)
5566 {
5567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5568 "%s: Failed to update channel list information", __func__);
5569 ret = -EINVAL;
5570 goto exit;
5571 }
5572 }
5573 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
5574 {
5575 tANI_U8 *value = command;
5576 char extra[128] = {0};
5577 int len = 0;
5578 tANI_U8 tid = 0;
5579 hdd_station_ctx_t *pHddStaCtx = NULL;
5580 tAniTrafStrmMetrics tsmMetrics;
5581 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5582
5583 /* if not associated, return error */
5584 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5585 {
5586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
5587 ret = -EINVAL;
5588 goto exit;
5589 }
5590
5591 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
5592 value = value + 12;
5593 /* Convert the value from ascii to integer */
5594 ret = kstrtou8(value, 10, &tid);
5595 if (ret < 0)
5596 {
5597 /* If the input value is greater than max value of datatype, then also
5598 kstrtou8 fails */
5599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5600 "%s: kstrtou8 failed range [%d - %d]", __func__,
5601 TID_MIN_VALUE,
5602 TID_MAX_VALUE);
5603 ret = -EINVAL;
5604 goto exit;
5605 }
5606
5607 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
5608 {
5609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5610 "tid value %d is out of range"
5611 " (Min: %d Max: %d)", tid,
5612 TID_MIN_VALUE,
5613 TID_MAX_VALUE);
5614 ret = -EINVAL;
5615 goto exit;
5616 }
5617
5618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5619 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
5620
5621 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
5622 {
5623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5624 "%s: failed to get tsm stats", __func__);
5625 ret = -EFAULT;
5626 goto exit;
5627 }
5628
5629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5630 "UplinkPktQueueDly(%d)\n"
5631 "UplinkPktQueueDlyHist[0](%d)\n"
5632 "UplinkPktQueueDlyHist[1](%d)\n"
5633 "UplinkPktQueueDlyHist[2](%d)\n"
5634 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05305635 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005636 "UplinkPktLoss(%d)\n"
5637 "UplinkPktCount(%d)\n"
5638 "RoamingCount(%d)\n"
5639 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
5640 tsmMetrics.UplinkPktQueueDlyHist[0],
5641 tsmMetrics.UplinkPktQueueDlyHist[1],
5642 tsmMetrics.UplinkPktQueueDlyHist[2],
5643 tsmMetrics.UplinkPktQueueDlyHist[3],
5644 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
5645 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
5646
5647 /* Output TSM stats is of the format
5648 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
5649 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005650 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005651 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
5652 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
5653 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
5654 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
5655 tsmMetrics.RoamingDly);
5656
Ratnam Rachurid53009c2015-08-07 13:59:00 +05305657 len = VOS_MIN(priv_data.total_len, len + 1);
5658 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5660 "%s: failed to copy data to user buffer", __func__);
5661 ret = -EFAULT;
5662 goto exit;
5663 }
5664 }
5665 else if (strncmp(command, "SETCCKMIE", 9) == 0)
5666 {
5667 tANI_U8 *value = command;
5668 tANI_U8 *cckmIe = NULL;
5669 tANI_U8 cckmIeLen = 0;
5670 eHalStatus status = eHAL_STATUS_SUCCESS;
5671
5672 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
5673 if (eHAL_STATUS_SUCCESS != status)
5674 {
5675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5676 "%s: Failed to parse cckm ie data", __func__);
5677 ret = -EINVAL;
5678 goto exit;
5679 }
5680
5681 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
5682 {
5683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5684 "%s: CCKM Ie input length is more than max[%d]", __func__,
5685 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005686 vos_mem_free(cckmIe);
5687 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005688 ret = -EINVAL;
5689 goto exit;
5690 }
5691 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08005692 vos_mem_free(cckmIe);
5693 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07005694 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005695 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
5696 {
5697 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005698 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005699 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005700
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005701 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005702 if (eHAL_STATUS_SUCCESS != status)
5703 {
5704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005705 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005706 ret = -EINVAL;
5707 goto exit;
5708 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07005709 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
5710 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
5711 hdd_indicateEseBcnReportNoResults (pAdapter,
5712 eseBcnReq.bcnReq[0].measurementToken,
5713 0x02, //BIT(1) set for measurement done
5714 0); // no BSS
5715 goto exit;
5716 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005717
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005718 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
5719 if (eHAL_STATUS_SUCCESS != status)
5720 {
5721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5722 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
5723 ret = -EINVAL;
5724 goto exit;
5725 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08005726 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005727#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05305728 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
5729 {
5730 eHalStatus status;
5731 char buf[32], len;
5732 long waitRet;
5733 bcnMissRateContext_t getBcnMissRateCtx;
5734
5735 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5736
5737 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
5738 {
5739 hddLog(VOS_TRACE_LEVEL_WARN,
5740 FL("GETBCNMISSRATE: STA is not in connected state"));
5741 ret = -1;
5742 goto exit;
5743 }
5744
5745 init_completion(&(getBcnMissRateCtx.completion));
5746 getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC;
5747
5748 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
5749 pAdapter->sessionId,
5750 (void *)getBcnMissRateCB,
5751 (void *)(&getBcnMissRateCtx));
5752 if( eHAL_STATUS_SUCCESS != status)
5753 {
5754 hddLog(VOS_TRACE_LEVEL_INFO,
5755 FL("GETBCNMISSRATE: fail to post WDA cmd"));
5756 ret = -EINVAL;
5757 goto exit;
5758 }
5759
5760 waitRet = wait_for_completion_interruptible_timeout
5761 (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME);
5762 if(waitRet <= 0)
5763 {
5764 hddLog(VOS_TRACE_LEVEL_ERROR,
5765 FL("failed to wait on bcnMissRateComp %d"), ret);
5766
5767 //Make magic number to zero so that callback is not called.
5768 spin_lock(&hdd_context_lock);
5769 getBcnMissRateCtx.magic = 0x0;
5770 spin_unlock(&hdd_context_lock);
5771 ret = -EINVAL;
5772 goto exit;
5773 }
5774
5775 hddLog(VOS_TRACE_LEVEL_INFO,
5776 FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate);
5777
5778 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate);
5779 if (copy_to_user(priv_data.buf, &buf, len + 1))
5780 {
5781 hddLog(VOS_TRACE_LEVEL_ERROR,
5782 "%s: failed to copy data to user buffer", __func__);
5783 ret = -EFAULT;
5784 goto exit;
5785 }
5786 ret = len;
5787 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305788#ifdef FEATURE_WLAN_TDLS
5789 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
5790 tANI_U8 *value = command;
5791 int set_value;
5792 /* Move pointer to ahead of TDLSOFFCH*/
5793 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05305794 if (!(sscanf(value, "%d", &set_value))) {
5795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5796 FL("No input identified"));
5797 ret = -EINVAL;
5798 goto exit;
5799 }
5800
Atul Mittal87ec2422014-09-24 13:12:50 +05305801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5802 "%s: Tdls offchannel offset:%d",
5803 __func__, set_value);
5804 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
5805 if (ret < 0)
5806 {
5807 ret = -EINVAL;
5808 goto exit;
5809 }
5810
5811 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
5812 tANI_U8 *value = command;
5813 int set_value;
5814 /* Move pointer to ahead of tdlsoffchnmode*/
5815 value += 18;
c_manjee82323892015-12-08 12:40:34 +05305816 ret = sscanf(value, "%d", &set_value);
5817 if (ret != 1) {
5818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5819 FL("No input identified"));
5820 ret = -EINVAL;
5821 goto exit;
5822 }
Atul Mittal87ec2422014-09-24 13:12:50 +05305823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5824 "%s: Tdls offchannel mode:%d",
5825 __func__, set_value);
5826 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
5827 if (ret < 0)
5828 {
5829 ret = -EINVAL;
5830 goto exit;
5831 }
5832 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
5833 tANI_U8 *value = command;
5834 int set_value;
5835 /* Move pointer to ahead of TDLSOFFCH*/
5836 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05305837 ret = sscanf(value, "%d", &set_value);
5838 if (ret != 1) {
5839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5840 "Wrong value is given for hdd_set_tdls_offchannel");
5841 ret = -EINVAL;
5842 goto exit;
5843 }
5844
Atul Mittal87ec2422014-09-24 13:12:50 +05305845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5846 "%s: Tdls offchannel num: %d",
5847 __func__, set_value);
5848 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
5849 if (ret < 0)
5850 {
5851 ret = -EINVAL;
5852 goto exit;
5853 }
5854 }
5855#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05305856 else if (strncmp(command, "GETFWSTATS", 10) == 0)
5857 {
5858 eHalStatus status;
5859 char *buf = NULL;
5860 char len;
5861 long waitRet;
5862 fwStatsContext_t fwStatsCtx;
Abhishek Singh08aa7762014-12-16 13:59:03 +05305863 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305864 tANI_U8 *ptr = command;
5865 int stats = *(ptr + 11) - '0';
5866
5867 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
5868 if (!IS_FEATURE_FW_STATS_ENABLE)
5869 {
5870 hddLog(VOS_TRACE_LEVEL_INFO,
5871 FL("Get Firmware stats feature not supported"));
5872 ret = -EINVAL;
5873 goto exit;
5874 }
5875
5876 if (FW_STATS_MAX <= stats || 0 >= stats)
5877 {
5878 hddLog(VOS_TRACE_LEVEL_INFO,
5879 FL(" stats %d not supported"),stats);
5880 ret = -EINVAL;
5881 goto exit;
5882 }
5883
5884 init_completion(&(fwStatsCtx.completion));
5885 fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC;
5886 fwStatsCtx.pAdapter = pAdapter;
5887 fwStatsRsp->type = 0;
5888 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Abhishek Singh08aa7762014-12-16 13:59:03 +05305889 &fwStatsCtx, hdd_FWStatisCB);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305890 if (eHAL_STATUS_SUCCESS != status)
5891 {
5892 hddLog(VOS_TRACE_LEVEL_ERROR,
5893 FL(" fail to post WDA cmd status = %d"), status);
5894 ret = -EINVAL;
5895 goto exit;
5896 }
5897 waitRet = wait_for_completion_timeout
5898 (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME);
5899 if (waitRet <= 0)
5900 {
5901 hddLog(VOS_TRACE_LEVEL_ERROR,
5902 FL("failed to wait on GwtFwstats"));
5903 //Make magic number to zero so that callback is not executed.
5904 spin_lock(&hdd_context_lock);
5905 fwStatsCtx.magic = 0x0;
5906 spin_unlock(&hdd_context_lock);
5907 ret = -EINVAL;
5908 goto exit;
5909 }
5910 if (fwStatsRsp->type)
5911 {
5912 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
5913 if (!buf)
5914 {
5915 hddLog(VOS_TRACE_LEVEL_ERROR,
5916 FL(" failed to allocate memory"));
5917 ret = -ENOMEM;
5918 goto exit;
5919 }
5920 switch( fwStatsRsp->type )
5921 {
5922 case FW_UBSP_STATS:
5923 {
5924 len = snprintf(buf, FW_STATE_RSP_LEN,
5925 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05305926 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
5927 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05305928 }
5929 break;
5930 default:
5931 {
5932 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
5933 ret = -EFAULT;
5934 kfree(buf);
5935 goto exit;
5936 }
5937 }
5938 if (copy_to_user(priv_data.buf, buf, len + 1))
5939 {
5940 hddLog(VOS_TRACE_LEVEL_ERROR,
5941 FL(" failed to copy data to user buffer"));
5942 ret = -EFAULT;
5943 kfree(buf);
5944 goto exit;
5945 }
5946 ret = len;
5947 kfree(buf);
5948 }
5949 else
5950 {
5951 hddLog(VOS_TRACE_LEVEL_ERROR,
5952 FL("failed to fetch the stats"));
5953 ret = -EFAULT;
5954 goto exit;
5955 }
5956
5957 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05305958 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
5959 {
5960 /*
5961 * this command wld be called by user-space when it detects WLAN
5962 * ON after airplane mode is set. When APM is set, WLAN turns off.
5963 * But it can be turned back on. Otherwise; when APM is turned back
5964 * off, WLAN wld turn back on. So at that point the command is
5965 * expected to come down. 0 means disable, 1 means enable. The
5966 * constraint is removed when parameter 1 is set or different
5967 * country code is set
5968 */
5969 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
5970 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05305971 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
5972 {
5973 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
5974 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005975 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305976 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5977 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
5978 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05305979 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
5980 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07005981 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005982 }
5983exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305984 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005985 if (command)
5986 {
5987 kfree(command);
5988 }
5989 return ret;
5990}
5991
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07005992#ifdef CONFIG_COMPAT
5993static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
5994{
5995 struct {
5996 compat_uptr_t buf;
5997 int used_len;
5998 int total_len;
5999 } compat_priv_data;
6000 hdd_priv_data_t priv_data;
6001 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006002
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006003 /*
6004 * Note that pAdapter and ifr have already been verified by caller,
6005 * and HDD context has also been validated
6006 */
6007 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
6008 sizeof(compat_priv_data))) {
6009 ret = -EFAULT;
6010 goto exit;
6011 }
6012 priv_data.buf = compat_ptr(compat_priv_data.buf);
6013 priv_data.used_len = compat_priv_data.used_len;
6014 priv_data.total_len = compat_priv_data.total_len;
6015 ret = hdd_driver_command(pAdapter, &priv_data);
6016 exit:
6017 return ret;
6018}
6019#else /* CONFIG_COMPAT */
6020static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6021{
6022 /* will never be invoked */
6023 return 0;
6024}
6025#endif /* CONFIG_COMPAT */
6026
6027static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
6028{
6029 hdd_priv_data_t priv_data;
6030 int ret = 0;
6031
6032 /*
6033 * Note that pAdapter and ifr have already been verified by caller,
6034 * and HDD context has also been validated
6035 */
6036 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
6037 ret = -EFAULT;
6038 } else {
6039 ret = hdd_driver_command(pAdapter, &priv_data);
6040 }
6041 return ret;
6042}
6043
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306044int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006045{
6046 hdd_adapter_t *pAdapter;
6047 hdd_context_t *pHddCtx;
6048 int ret;
6049
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306050 ENTER();
6051
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006052 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6053 if (NULL == pAdapter) {
6054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6055 "%s: HDD adapter context is Null", __func__);
6056 ret = -ENODEV;
6057 goto exit;
6058 }
6059 if (dev != pAdapter->dev) {
6060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6061 "%s: HDD adapter/dev inconsistency", __func__);
6062 ret = -ENODEV;
6063 goto exit;
6064 }
6065
6066 if ((!ifr) || (!ifr->ifr_data)) {
6067 ret = -EINVAL;
6068 goto exit;
6069 }
6070
6071 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6072 ret = wlan_hdd_validate_context(pHddCtx);
6073 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006074 ret = -EBUSY;
6075 goto exit;
6076 }
6077
6078 switch (cmd) {
6079 case (SIOCDEVPRIVATE + 1):
6080 if (is_compat_task())
6081 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
6082 else
6083 ret = hdd_driver_ioctl(pAdapter, ifr);
6084 break;
6085 default:
6086 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
6087 __func__, cmd);
6088 ret = -EINVAL;
6089 break;
6090 }
6091 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306092 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07006093 return ret;
6094}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006095
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306096int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6097{
6098 int ret;
6099
6100 vos_ssr_protect(__func__);
6101 ret = __hdd_ioctl(dev, ifr, cmd);
6102 vos_ssr_unprotect(__func__);
6103
6104 return ret;
6105}
6106
Katya Nigame7b69a82015-04-28 15:24:06 +05306107int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6108{
6109 return 0;
6110}
6111
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006112#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006113/**---------------------------------------------------------------------------
6114
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006115 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006116
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006117 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006118 CCXBEACONREQ<space><Number of fields><space><Measurement token>
6119 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
6120 <space>Scan Mode N<space>Meas Duration N
6121 if the Number of bcn req fields (N) does not match with the actual number of fields passed
6122 then take N.
6123 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
6124 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
6125 This function does not take care of removing duplicate channels from the list
6126
6127 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006128 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006129
6130 \return - 0 for success non-zero for failure
6131
6132 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006133static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
6134 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006135{
6136 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306137 uint8_t input = 0;
6138 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006139 int j = 0, i = 0, v = 0;
6140 char buf[32];
6141
6142 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6143 /*no argument after the command*/
6144 if (NULL == inPtr)
6145 {
6146 return -EINVAL;
6147 }
6148 /*no space after the command*/
6149 else if (SPACE_ASCII_VALUE != *inPtr)
6150 {
6151 return -EINVAL;
6152 }
6153
6154 /*removing empty spaces*/
6155 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6156
6157 /*no argument followed by spaces*/
6158 if ('\0' == *inPtr) return -EINVAL;
6159
6160 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006161 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006162 if (1 != v) return -EINVAL;
6163
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306164 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006165 if ( v < 0) return -EINVAL;
6166
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306167 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
6168 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006169
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05306170 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
6171
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006172
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006173 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006174 {
6175 for (i = 0; i < 4; i++)
6176 {
6177 /*inPtr pointing to the beginning of first space after number of ie fields*/
6178 inPtr = strpbrk( inPtr, " " );
6179 /*no ie data after the number of ie fields argument*/
6180 if (NULL == inPtr) return -EINVAL;
6181
6182 /*removing empty space*/
6183 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
6184
6185 /*no ie data after the number of ie fields argument and spaces*/
6186 if ( '\0' == *inPtr ) return -EINVAL;
6187
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006188 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006189 if (1 != v) return -EINVAL;
6190
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306191 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006192 if (v < 0) return -EINVAL;
6193
6194 switch (i)
6195 {
6196 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306197 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006198 {
6199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306200 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006201 return -EINVAL;
6202 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006203 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006204 break;
6205
6206 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306207 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006208 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6209 {
6210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306211 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006212 return -EINVAL;
6213 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006214 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006215 break;
6216
6217 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08006218 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006219 {
6220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306221 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006222 return -EINVAL;
6223 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006224 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006225 break;
6226
6227 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306228 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
6229 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006230 {
6231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05306232 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006233 return -EINVAL;
6234 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006235 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006236 break;
6237 }
6238 }
6239 }
6240
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006241 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006242 {
6243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306244 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006245 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006246 pEseBcnReq->bcnReq[j].measurementToken,
6247 pEseBcnReq->bcnReq[j].channel,
6248 pEseBcnReq->bcnReq[j].scanMode,
6249 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006250 }
6251
6252 return VOS_STATUS_SUCCESS;
6253}
6254
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006255static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext )
6256{
6257 struct statsContext *pStatsContext = NULL;
6258 hdd_adapter_t *pAdapter = NULL;
6259
6260 if (NULL == pContext)
6261 {
6262 hddLog(VOS_TRACE_LEVEL_ERROR,
6263 "%s: Bad param, pContext [%p]",
6264 __func__, pContext);
6265 return;
6266 }
6267
Jeff Johnson72a40512013-12-19 10:14:15 -08006268 /* there is a race condition that exists between this callback
6269 function and the caller since the caller could time out either
6270 before or while this code is executing. we use a spinlock to
6271 serialize these actions */
6272 spin_lock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006273
6274 pStatsContext = pContext;
6275 pAdapter = pStatsContext->pAdapter;
6276 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
6277 {
6278 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -08006279 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006280 hddLog(VOS_TRACE_LEVEL_WARN,
6281 "%s: Invalid context, pAdapter [%p] magic [%08x]",
6282 __func__, pAdapter, pStatsContext->magic);
6283 return;
6284 }
6285
Jeff Johnson72a40512013-12-19 10:14:15 -08006286 /* context is valid so caller is still waiting */
6287
6288 /* paranoia: invalidate the magic */
6289 pStatsContext->magic = 0;
6290
6291 /* copy over the tsm stats */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006292 pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly;
6293 vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist,
6294 tsmMetrics.UplinkPktQueueDlyHist,
6295 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6296 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6297 pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly;
6298 pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss;
6299 pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount;
6300 pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount;
6301 pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly;
6302
Jeff Johnson72a40512013-12-19 10:14:15 -08006303 /* notify the caller */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006304 complete(&pStatsContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -08006305
6306 /* serialization is complete */
6307 spin_unlock(&hdd_context_lock);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006308}
6309
6310
6311
6312static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
6313 tAniTrafStrmMetrics* pTsmMetrics)
6314{
6315 hdd_station_ctx_t *pHddStaCtx = NULL;
6316 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08006317 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006318 long lrc;
6319 struct statsContext context;
6320 hdd_context_t *pHddCtx = NULL;
6321
6322 if (NULL == pAdapter)
6323 {
6324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
6325 return VOS_STATUS_E_FAULT;
6326 }
6327
6328 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6329 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6330
6331 /* we are connected prepare our callback context */
6332 init_completion(&context.completion);
6333 context.pAdapter = pAdapter;
6334 context.magic = STATS_CONTEXT_MAGIC;
6335
6336 /* query tsm stats */
6337 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB,
6338 pHddStaCtx->conn_info.staId[ 0 ],
6339 pHddStaCtx->conn_info.bssId,
6340 &context, pHddCtx->pvosContext, tid);
6341
6342 if (eHAL_STATUS_SUCCESS != hstatus)
6343 {
Jeff Johnson72a40512013-12-19 10:14:15 -08006344 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
6345 __func__);
6346 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006347 }
6348 else
6349 {
6350 /* request was sent -- wait for the response */
6351 lrc = wait_for_completion_interruptible_timeout(&context.completion,
6352 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006353 if (lrc <= 0)
6354 {
6355 hddLog(VOS_TRACE_LEVEL_ERROR,
6356 "%s: SME %s while retrieving statistics",
6357 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson72a40512013-12-19 10:14:15 -08006358 vstatus = VOS_STATUS_E_TIMEOUT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006359 }
6360 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006361
Jeff Johnson72a40512013-12-19 10:14:15 -08006362 /* either we never sent a request, we sent a request and received a
6363 response or we sent a request and timed out. if we never sent a
6364 request or if we sent a request and got a response, we want to
6365 clear the magic out of paranoia. if we timed out there is a
6366 race condition such that the callback function could be
6367 executing at the same time we are. of primary concern is if the
6368 callback function had already verified the "magic" but had not
6369 yet set the completion variable when a timeout occurred. we
6370 serialize these activities by invalidating the magic while
6371 holding a shared spinlock which will cause us to block if the
6372 callback is currently executing */
6373 spin_lock(&hdd_context_lock);
6374 context.magic = 0;
6375 spin_unlock(&hdd_context_lock);
6376
6377 if (VOS_STATUS_SUCCESS == vstatus)
6378 {
6379 pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly;
6380 vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist,
6381 pAdapter->tsmStats.UplinkPktQueueDlyHist,
6382 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/
6383 sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0]));
6384 pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly;
6385 pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss;
6386 pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount;
6387 pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount;
6388 pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly;
6389 }
6390 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006391}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006392#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006393
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006394#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08006395void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
6396{
6397 eCsrBand band = -1;
6398 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
6399 switch (band)
6400 {
6401 case eCSR_BAND_ALL:
6402 *pBand = WLAN_HDD_UI_BAND_AUTO;
6403 break;
6404
6405 case eCSR_BAND_24:
6406 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
6407 break;
6408
6409 case eCSR_BAND_5G:
6410 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
6411 break;
6412
6413 default:
6414 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
6415 *pBand = -1;
6416 break;
6417 }
6418}
6419
6420/**---------------------------------------------------------------------------
6421
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006422 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
6423
6424 This function parses the send action frame data passed in the format
6425 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
6426
Srinivas Girigowda56076852013-08-20 14:00:50 -07006427 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006428 \param - pTargetApBssid Pointer to target Ap bssid
6429 \param - pChannel Pointer to the Target AP channel
6430 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
6431 \param - pBuf Pointer to data
6432 \param - pBufLen Pointer to data length
6433
6434 \return - 0 for success non-zero for failure
6435
6436 --------------------------------------------------------------------------*/
6437VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
6438 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
6439{
6440 tANI_U8 *inPtr = pValue;
6441 tANI_U8 *dataEnd;
6442 int tempInt;
6443 int j = 0;
6444 int i = 0;
6445 int v = 0;
6446 tANI_U8 tempBuf[32];
6447 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006448 /* 12 hexa decimal digits, 5 ':' and '\0' */
6449 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006450
6451 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6452 /*no argument after the command*/
6453 if (NULL == inPtr)
6454 {
6455 return -EINVAL;
6456 }
6457
6458 /*no space after the command*/
6459 else if (SPACE_ASCII_VALUE != *inPtr)
6460 {
6461 return -EINVAL;
6462 }
6463
6464 /*removing empty spaces*/
6465 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6466
6467 /*no argument followed by spaces*/
6468 if ('\0' == *inPtr)
6469 {
6470 return -EINVAL;
6471 }
6472
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006473 v = sscanf(inPtr, "%17s", macAddress);
6474 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006475 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6477 "Invalid MAC address or All hex inputs are not read (%d)", v);
6478 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006479 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006480
6481 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6482 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6483 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6484 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6485 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6486 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006487
6488 /* point to the next argument */
6489 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6490 /*no argument after the command*/
6491 if (NULL == inPtr) return -EINVAL;
6492
6493 /*removing empty spaces*/
6494 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6495
6496 /*no argument followed by spaces*/
6497 if ('\0' == *inPtr)
6498 {
6499 return -EINVAL;
6500 }
6501
6502 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006503 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006504 if (1 != v) return -EINVAL;
6505
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006506 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05306507 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05306508 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006509
6510 *pChannel = tempInt;
6511
6512 /* point to the next argument */
6513 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6514 /*no argument after the command*/
6515 if (NULL == inPtr) return -EINVAL;
6516 /*removing empty spaces*/
6517 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6518
6519 /*no argument followed by spaces*/
6520 if ('\0' == *inPtr)
6521 {
6522 return -EINVAL;
6523 }
6524
6525 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006526 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006527 if (1 != v) return -EINVAL;
6528
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006529 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08006530 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006531
6532 *pDwellTime = tempInt;
6533
6534 /* point to the next argument */
6535 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6536 /*no argument after the command*/
6537 if (NULL == inPtr) return -EINVAL;
6538 /*removing empty spaces*/
6539 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6540
6541 /*no argument followed by spaces*/
6542 if ('\0' == *inPtr)
6543 {
6544 return -EINVAL;
6545 }
6546
6547 /* find the length of data */
6548 dataEnd = inPtr;
6549 while(('\0' != *dataEnd) )
6550 {
6551 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006552 }
Kiet Lambe150c22013-11-21 16:30:32 +05306553 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006554 if ( *pBufLen <= 0) return -EINVAL;
6555
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07006556 /* Allocate the number of bytes based on the number of input characters
6557 whether it is even or odd.
6558 if the number of input characters are even, then we need N/2 byte.
6559 if the number of input characters are odd, then we need do (N+1)/2 to
6560 compensate rounding off.
6561 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6562 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6563 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006564 if (NULL == *pBuf)
6565 {
6566 hddLog(VOS_TRACE_LEVEL_FATAL,
6567 "%s: vos_mem_alloc failed ", __func__);
6568 return -EINVAL;
6569 }
6570
6571 /* the buffer received from the upper layer is character buffer,
6572 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6573 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6574 and f0 in 3rd location */
6575 for (i = 0, j = 0; j < *pBufLen; j += 2)
6576 {
Kiet Lambe150c22013-11-21 16:30:32 +05306577 if( j+1 == *pBufLen)
6578 {
6579 tempByte = hdd_parse_hex(inPtr[j]);
6580 }
6581 else
6582 {
6583 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6584 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006585 (*pBuf)[i++] = tempByte;
6586 }
6587 *pBufLen = i;
6588 return VOS_STATUS_SUCCESS;
6589}
6590
Srinivas Girigowda100eb322013-03-15 16:48:20 -07006591/**---------------------------------------------------------------------------
6592
Srinivas Girigowdade697412013-02-14 16:31:48 -08006593 \brief hdd_parse_channellist() - HDD Parse channel list
6594
6595 This function parses the channel list passed in the format
6596 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006597 if the Number of channels (N) does not match with the actual number of channels passed
6598 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
6599 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
6600 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
6601 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08006602
6603 \param - pValue Pointer to input channel list
6604 \param - ChannelList Pointer to local output array to record channel list
6605 \param - pNumChannels Pointer to number of roam scan channels
6606
6607 \return - 0 for success non-zero for failure
6608
6609 --------------------------------------------------------------------------*/
6610VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
6611{
6612 tANI_U8 *inPtr = pValue;
6613 int tempInt;
6614 int j = 0;
6615 int v = 0;
6616 char buf[32];
6617
6618 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6619 /*no argument after the command*/
6620 if (NULL == inPtr)
6621 {
6622 return -EINVAL;
6623 }
6624
6625 /*no space after the command*/
6626 else if (SPACE_ASCII_VALUE != *inPtr)
6627 {
6628 return -EINVAL;
6629 }
6630
6631 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006632 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006633
6634 /*no argument followed by spaces*/
6635 if ('\0' == *inPtr)
6636 {
6637 return -EINVAL;
6638 }
6639
6640 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006641 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006642 if (1 != v) return -EINVAL;
6643
Srinivas Girigowdade697412013-02-14 16:31:48 -08006644 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006645 if ((v < 0) ||
6646 (tempInt <= 0) ||
6647 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
6648 {
6649 return -EINVAL;
6650 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006651
6652 *pNumChannels = tempInt;
6653
6654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6655 "Number of channels are: %d", *pNumChannels);
6656
6657 for (j = 0; j < (*pNumChannels); j++)
6658 {
6659 /*inPtr pointing to the beginning of first space after number of channels*/
6660 inPtr = strpbrk( inPtr, " " );
6661 /*no channel list after the number of channels argument*/
6662 if (NULL == inPtr)
6663 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006664 if (0 != j)
6665 {
6666 *pNumChannels = j;
6667 return VOS_STATUS_SUCCESS;
6668 }
6669 else
6670 {
6671 return -EINVAL;
6672 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006673 }
6674
6675 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006676 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08006677
6678 /*no channel list after the number of channels argument and spaces*/
6679 if ( '\0' == *inPtr )
6680 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07006681 if (0 != j)
6682 {
6683 *pNumChannels = j;
6684 return VOS_STATUS_SUCCESS;
6685 }
6686 else
6687 {
6688 return -EINVAL;
6689 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006690 }
6691
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006692 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006693 if (1 != v) return -EINVAL;
6694
Srinivas Girigowdade697412013-02-14 16:31:48 -08006695 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07006696 if ((v < 0) ||
6697 (tempInt <= 0) ||
6698 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6699 {
6700 return -EINVAL;
6701 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08006702 pChannelList[j] = tempInt;
6703
6704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6705 "Channel %d added to preferred channel list",
6706 pChannelList[j] );
6707 }
6708
Srinivas Girigowdade697412013-02-14 16:31:48 -08006709 return VOS_STATUS_SUCCESS;
6710}
6711
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006712
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05306713/**
6714 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
6715 * This function parses the reasoc command data passed in the format
6716 * REASSOC<space><bssid><space><channel>
6717 *
6718 * @pValue: Pointer to input data (its a NUL terminated string)
6719 * @pTargetApBssid: Pointer to target Ap bssid
6720 * @pChannel: Pointer to the Target AP channel
6721 *
6722 * Return: 0 for success non-zero for failure
6723 */
6724static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
6725 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006726{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05306727 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006728 int tempInt;
6729 int v = 0;
6730 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08006731 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006732 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006733
6734 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6735 /*no argument after the command*/
6736 if (NULL == inPtr)
6737 {
6738 return -EINVAL;
6739 }
6740
6741 /*no space after the command*/
6742 else if (SPACE_ASCII_VALUE != *inPtr)
6743 {
6744 return -EINVAL;
6745 }
6746
6747 /*removing empty spaces*/
6748 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6749
6750 /*no argument followed by spaces*/
6751 if ('\0' == *inPtr)
6752 {
6753 return -EINVAL;
6754 }
6755
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006756 v = sscanf(inPtr, "%17s", macAddress);
6757 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006758 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6760 "Invalid MAC address or All hex inputs are not read (%d)", v);
6761 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006762 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006763
6764 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
6765 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
6766 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
6767 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
6768 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
6769 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006770
6771 /* point to the next argument */
6772 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
6773 /*no argument after the command*/
6774 if (NULL == inPtr) return -EINVAL;
6775
6776 /*removing empty spaces*/
6777 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6778
6779 /*no argument followed by spaces*/
6780 if ('\0' == *inPtr)
6781 {
6782 return -EINVAL;
6783 }
6784
6785 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08006786 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006787 if (1 != v) return -EINVAL;
6788
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006789 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006790 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05306791 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006792 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
6793 {
6794 return -EINVAL;
6795 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006796
6797 *pChannel = tempInt;
6798 return VOS_STATUS_SUCCESS;
6799}
6800
6801#endif
6802
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006803#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006804/**---------------------------------------------------------------------------
6805
6806 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
6807
6808 This function parses the SETCCKM IE command
6809 SETCCKMIE<space><ie data>
6810
6811 \param - pValue Pointer to input data
6812 \param - pCckmIe Pointer to output cckm Ie
6813 \param - pCckmIeLen Pointer to output cckm ie length
6814
6815 \return - 0 for success non-zero for failure
6816
6817 --------------------------------------------------------------------------*/
6818VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
6819 tANI_U8 *pCckmIeLen)
6820{
6821 tANI_U8 *inPtr = pValue;
6822 tANI_U8 *dataEnd;
6823 int j = 0;
6824 int i = 0;
6825 tANI_U8 tempByte = 0;
6826
6827 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
6828 /*no argument after the command*/
6829 if (NULL == inPtr)
6830 {
6831 return -EINVAL;
6832 }
6833
6834 /*no space after the command*/
6835 else if (SPACE_ASCII_VALUE != *inPtr)
6836 {
6837 return -EINVAL;
6838 }
6839
6840 /*removing empty spaces*/
6841 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
6842
6843 /*no argument followed by spaces*/
6844 if ('\0' == *inPtr)
6845 {
6846 return -EINVAL;
6847 }
6848
6849 /* find the length of data */
6850 dataEnd = inPtr;
6851 while(('\0' != *dataEnd) )
6852 {
6853 dataEnd++;
6854 ++(*pCckmIeLen);
6855 }
6856 if ( *pCckmIeLen <= 0) return -EINVAL;
6857
6858 /* Allocate the number of bytes based on the number of input characters
6859 whether it is even or odd.
6860 if the number of input characters are even, then we need N/2 byte.
6861 if the number of input characters are odd, then we need do (N+1)/2 to
6862 compensate rounding off.
6863 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
6864 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
6865 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
6866 if (NULL == *pCckmIe)
6867 {
6868 hddLog(VOS_TRACE_LEVEL_FATAL,
6869 "%s: vos_mem_alloc failed ", __func__);
6870 return -EINVAL;
6871 }
6872 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
6873 /* the buffer received from the upper layer is character buffer,
6874 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
6875 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
6876 and f0 in 3rd location */
6877 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
6878 {
6879 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
6880 (*pCckmIe)[i++] = tempByte;
6881 }
6882 *pCckmIeLen = i;
6883
6884 return VOS_STATUS_SUCCESS;
6885}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006886#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006887
Jeff Johnson295189b2012-06-20 16:38:30 -07006888/**---------------------------------------------------------------------------
6889
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07006890 \brief hdd_is_valid_mac_address() - Validate MAC address
6891
6892 This function validates whether the given MAC address is valid or not
6893 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
6894 where X is the hexa decimal digit character and separated by ':'
6895 This algorithm works even if MAC address is not separated by ':'
6896
6897 This code checks given input string mac contains exactly 12 hexadecimal digits.
6898 and a separator colon : appears in the input string only after
6899 an even number of hex digits.
6900
6901 \param - pMacAddr pointer to the input MAC address
6902 \return - 1 for valid and 0 for invalid
6903
6904 --------------------------------------------------------------------------*/
6905
6906v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
6907{
6908 int xdigit = 0;
6909 int separator = 0;
6910 while (*pMacAddr)
6911 {
6912 if (isxdigit(*pMacAddr))
6913 {
6914 xdigit++;
6915 }
6916 else if (':' == *pMacAddr)
6917 {
6918 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
6919 break;
6920
6921 ++separator;
6922 }
6923 else
6924 {
6925 separator = -1;
6926 /* Invalid MAC found */
6927 return 0;
6928 }
6929 ++pMacAddr;
6930 }
6931 return (xdigit == 12 && (separator == 5 || separator == 0));
6932}
6933
6934/**---------------------------------------------------------------------------
6935
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306936 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07006937
6938 \param - dev Pointer to net_device structure
6939
6940 \return - 0 for success non-zero for failure
6941
6942 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05306943int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07006944{
6945 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6946 hdd_context_t *pHddCtx;
6947 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
6948 VOS_STATUS status;
6949 v_BOOL_t in_standby = TRUE;
6950
6951 if (NULL == pAdapter)
6952 {
6953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05306954 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006955 return -ENODEV;
6956 }
6957
6958 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306959 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
6960 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 if (NULL == pHddCtx)
6962 {
6963 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006964 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006965 return -ENODEV;
6966 }
6967
6968 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
6969 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
6970 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006971 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
6972 {
6973 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05306974 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006975 in_standby = FALSE;
6976 break;
6977 }
6978 else
6979 {
6980 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
6981 pAdapterNode = pNext;
6982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 }
6984
6985 if (TRUE == in_standby)
6986 {
6987 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
6988 {
6989 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
6990 "wlan out of power save", __func__);
6991 return -EINVAL;
6992 }
6993 }
6994
Jeff Johnson6a81ca42013-04-05 10:37:08 -07006995 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07006996 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
6997 {
6998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006999 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307001 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007002 netif_tx_start_all_queues(dev);
7003 }
7004
7005 return 0;
7006}
7007
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307008/**---------------------------------------------------------------------------
7009
7010 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
7011
7012 This is called in response to ifconfig up
7013
7014 \param - dev Pointer to net_device structure
7015
7016 \return - 0 for success non-zero for failure
7017
7018 --------------------------------------------------------------------------*/
7019int hdd_open(struct net_device *dev)
7020{
7021 int ret;
7022
7023 vos_ssr_protect(__func__);
7024 ret = __hdd_open(dev);
7025 vos_ssr_unprotect(__func__);
7026
7027 return ret;
7028}
7029
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307030int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007031{
7032 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7033
7034 if(pAdapter == NULL) {
7035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007036 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08007037 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 }
7039
Jeff Johnson295189b2012-06-20 16:38:30 -07007040 return 0;
7041}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307042
7043int hdd_mon_open (struct net_device *dev)
7044{
7045 int ret;
7046
7047 vos_ssr_protect(__func__);
7048 ret = __hdd_mon_open(dev);
7049 vos_ssr_unprotect(__func__);
7050
7051 return ret;
7052}
7053
Katya Nigame7b69a82015-04-28 15:24:06 +05307054int hdd_mon_stop(struct net_device *dev)
7055{
7056 return 0;
7057}
7058
Jeff Johnson295189b2012-06-20 16:38:30 -07007059/**---------------------------------------------------------------------------
7060
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307061 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07007062
7063 \param - dev Pointer to net_device structure
7064
7065 \return - 0 for success non-zero for failure
7066
7067 --------------------------------------------------------------------------*/
7068
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307069int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007070{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307071 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007072 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7073 hdd_context_t *pHddCtx;
7074 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
7075 VOS_STATUS status;
7076 v_BOOL_t enter_standby = TRUE;
7077
7078 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 if (NULL == pAdapter)
7080 {
7081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05307082 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007083 return -ENODEV;
7084 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05307085 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307086 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307087
7088 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7089 ret = wlan_hdd_validate_context(pHddCtx);
7090 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07007091 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05307092 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 }
7094
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307095 /* Nothing to be done if the interface is not opened */
7096 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
7097 {
7098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7099 "%s: NETDEV Interface is not OPENED", __func__);
7100 return -ENODEV;
7101 }
7102
7103 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007104 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307106
7107 /* Disable TX on the interface, after this hard_start_xmit() will not
7108 * be called on that interface
7109 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05307110 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007111 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307112
7113 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 netif_carrier_off(pAdapter->dev);
7115
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307116 /* The interface is marked as down for outside world (aka kernel)
7117 * But the driver is pretty much alive inside. The driver needs to
7118 * tear down the existing connection on the netdev (session)
7119 * cleanup the data pipes and wait until the control plane is stabilized
7120 * for this interface. The call also needs to wait until the above
7121 * mentioned actions are completed before returning to the caller.
7122 * Notice that the hdd_stop_adapter is requested not to close the session
7123 * That is intentional to be able to scan if it is a STA/P2P interface
7124 */
7125 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307126#ifdef FEATURE_WLAN_TDLS
7127 mutex_lock(&pHddCtx->tdls_lock);
7128#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307129 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05307130 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307131#ifdef FEATURE_WLAN_TDLS
7132 mutex_unlock(&pHddCtx->tdls_lock);
7133#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007134 /* SoftAP ifaces should never go in power save mode
7135 making sure same here. */
7136 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
7137 || (WLAN_HDD_MONITOR == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007138 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07007139 )
7140 {
7141 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307142 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7143 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007144 EXIT();
7145 return 0;
7146 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05307147 /* Find if any iface is up. If any iface is up then can't put device to
7148 * sleep/power save mode
7149 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007150 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
7151 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
7152 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007153 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
7154 {
7155 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307156 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07007157 enter_standby = FALSE;
7158 break;
7159 }
7160 else
7161 {
7162 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
7163 pAdapterNode = pNext;
7164 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007165 }
7166
7167 if (TRUE == enter_standby)
7168 {
7169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
7170 "entering standby", __func__);
7171 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
7172 {
7173 /*log and return success*/
7174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
7175 "wlan in power save", __func__);
7176 }
7177 }
7178
7179 EXIT();
7180 return 0;
7181}
7182
7183/**---------------------------------------------------------------------------
7184
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307185 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07007186
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307187 This is called in response to ifconfig down
7188
7189 \param - dev Pointer to net_device structure
7190
7191 \return - 0 for success non-zero for failure
7192-----------------------------------------------------------------------------*/
7193int hdd_stop (struct net_device *dev)
7194{
7195 int ret;
7196
7197 vos_ssr_protect(__func__);
7198 ret = __hdd_stop(dev);
7199 vos_ssr_unprotect(__func__);
7200
7201 return ret;
7202}
7203
7204/**---------------------------------------------------------------------------
7205
7206 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07007207
7208 \param - dev Pointer to net_device structure
7209
7210 \return - void
7211
7212 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307213static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07007214{
7215 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307216 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007217 ENTER();
7218
7219 do
7220 {
7221 if (NULL == pAdapter)
7222 {
7223 hddLog(VOS_TRACE_LEVEL_FATAL,
7224 "%s: NULL pAdapter", __func__);
7225 break;
7226 }
7227
7228 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7229 {
7230 hddLog(VOS_TRACE_LEVEL_FATAL,
7231 "%s: Invalid magic", __func__);
7232 break;
7233 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307234 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7235 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07007236 {
7237 hddLog(VOS_TRACE_LEVEL_FATAL,
7238 "%s: NULL pHddCtx", __func__);
7239 break;
7240 }
7241
7242 if (dev != pAdapter->dev)
7243 {
7244 hddLog(VOS_TRACE_LEVEL_FATAL,
7245 "%s: Invalid device reference", __func__);
7246 /* we haven't validated all cases so let this go for now */
7247 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307248#ifdef FEATURE_WLAN_TDLS
7249 mutex_lock(&pHddCtx->tdls_lock);
7250#endif
c_hpothu002231a2015-02-05 14:58:51 +05307251 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05307252#ifdef FEATURE_WLAN_TDLS
7253 mutex_unlock(&pHddCtx->tdls_lock);
7254#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007255
7256 /* after uninit our adapter structure will no longer be valid */
7257 pAdapter->dev = NULL;
7258 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05307259 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007260 } while (0);
7261
7262 EXIT();
7263}
7264
7265/**---------------------------------------------------------------------------
7266
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307267 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
7268
7269 This is called during the netdev unregister to uninitialize all data
7270associated with the device
7271
7272 \param - dev Pointer to net_device structure
7273
7274 \return - void
7275
7276 --------------------------------------------------------------------------*/
7277static void hdd_uninit (struct net_device *dev)
7278{
7279 vos_ssr_protect(__func__);
7280 __hdd_uninit(dev);
7281 vos_ssr_unprotect(__func__);
7282}
7283
7284/**---------------------------------------------------------------------------
7285
Jeff Johnson295189b2012-06-20 16:38:30 -07007286 \brief hdd_release_firmware() -
7287
7288 This function calls the release firmware API to free the firmware buffer.
7289
7290 \param - pFileName Pointer to the File Name.
7291 pCtx - Pointer to the adapter .
7292
7293
7294 \return - 0 for success, non zero for failure
7295
7296 --------------------------------------------------------------------------*/
7297
7298VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
7299{
7300 VOS_STATUS status = VOS_STATUS_SUCCESS;
7301 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7302 ENTER();
7303
7304
7305 if (!strcmp(WLAN_FW_FILE, pFileName)) {
7306
7307 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
7308
7309 if(pHddCtx->fw) {
7310 release_firmware(pHddCtx->fw);
7311 pHddCtx->fw = NULL;
7312 }
7313 else
7314 status = VOS_STATUS_E_FAILURE;
7315 }
7316 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
7317 if(pHddCtx->nv) {
7318 release_firmware(pHddCtx->nv);
7319 pHddCtx->nv = NULL;
7320 }
7321 else
7322 status = VOS_STATUS_E_FAILURE;
7323
7324 }
7325
7326 EXIT();
7327 return status;
7328}
7329
7330/**---------------------------------------------------------------------------
7331
7332 \brief hdd_request_firmware() -
7333
7334 This function reads the firmware file using the request firmware
7335 API and returns the the firmware data and the firmware file size.
7336
7337 \param - pfileName - Pointer to the file name.
7338 - pCtx - Pointer to the adapter .
7339 - ppfw_data - Pointer to the pointer of the firmware data.
7340 - pSize - Pointer to the file size.
7341
7342 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
7343
7344 --------------------------------------------------------------------------*/
7345
7346
7347VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
7348{
7349 int status;
7350 VOS_STATUS retval = VOS_STATUS_SUCCESS;
7351 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7352 ENTER();
7353
7354 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
7355
7356 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
7357
7358 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7359 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
7360 __func__, pfileName);
7361 retval = VOS_STATUS_E_FAILURE;
7362 }
7363
7364 else {
7365 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
7366 *pSize = pHddCtx->fw->size;
7367 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
7368 __func__, *pSize);
7369 }
7370 }
7371 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
7372
7373 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
7374
7375 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
7376 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
7377 __func__, pfileName);
7378 retval = VOS_STATUS_E_FAILURE;
7379 }
7380
7381 else {
7382 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
7383 *pSize = pHddCtx->nv->size;
7384 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
7385 __func__, *pSize);
7386 }
7387 }
7388
7389 EXIT();
7390 return retval;
7391}
7392/**---------------------------------------------------------------------------
7393 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
7394
7395 This is the function invoked by SME to inform the result of a full power
7396 request issued by HDD
7397
7398 \param - callbackcontext - Pointer to cookie
7399 status - result of request
7400
7401 \return - None
7402
7403--------------------------------------------------------------------------*/
7404void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
7405{
7406 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
7407
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007408 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007409 if(&pHddCtx->full_pwr_comp_var)
7410 {
7411 complete(&pHddCtx->full_pwr_comp_var);
7412 }
7413}
7414
Abhishek Singh00b71972016-01-07 10:51:04 +05307415#ifdef WLAN_FEATURE_RMC
7416static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
7417{
7418 int payload_len;
7419 struct sk_buff *skb;
7420 struct nlmsghdr *nlh;
7421 v_U8_t *data;
7422
7423 payload_len = ETH_ALEN;
7424
7425 if (0 == cesium_pid)
7426 {
7427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
7428 __func__);
7429 return;
7430 }
7431
7432 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
7433 {
7434 hddLog(VOS_TRACE_LEVEL_ERROR,
7435 "%s: nlmsg_new() failed for msg size[%d]",
7436 __func__, NLMSG_SPACE(payload_len));
7437 return;
7438 }
7439
7440 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
7441
7442 if (NULL == nlh)
7443 {
7444 hddLog(VOS_TRACE_LEVEL_ERROR,
7445 "%s: nlmsg_put() failed for msg size[%d]",
7446 __func__, NLMSG_SPACE(payload_len));
7447
7448 kfree_skb(skb);
7449 return;
7450 }
7451
7452 data = nlmsg_data(nlh);
7453 memcpy(data, MacAddr, ETH_ALEN);
7454
7455 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
7456 {
7457 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
7458 __func__, NLMSG_SPACE(payload_len));
7459 }
7460
7461 return;
7462}
7463
7464/**---------------------------------------------------------------------------
7465 \brief hdd_ParseuserParams - return a pointer to the next argument
7466
7467 \return - status
7468
7469--------------------------------------------------------------------------*/
7470static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
7471{
7472 tANI_U8 *pVal;
7473
7474 pVal = strchr(pValue, ' ');
7475
7476 if (NULL == pVal)
7477 {
7478 /* no argument remains */
7479 return -EINVAL;
7480 }
7481 else if (SPACE_ASCII_VALUE != *pVal)
7482 {
7483 /* no space after the current argument */
7484 return -EINVAL;
7485 }
7486
7487 pVal++;
7488
7489 /* remove empty spaces */
7490 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
7491 {
7492 pVal++;
7493 }
7494
7495 /* no argument followed by spaces */
7496 if ('\0' == *pVal)
7497 {
7498 return -EINVAL;
7499 }
7500
7501 *ppArg = pVal;
7502
7503 return 0;
7504}
7505
7506/**----------------------------------------------------------------------------
7507 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
7508
7509 \return - status
7510
7511------------------------------------------------------------------------------*/
7512static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
7513 tANI_U8 *tx_fail_count,
7514 tANI_U16 *pid)
7515{
7516 tANI_U8 *param = NULL;
7517 int ret;
7518
7519 ret = hdd_ParseUserParams(pValue, &param);
7520
7521 if (0 == ret && NULL != param)
7522 {
7523 if (1 != sscanf(param, "%hhu", tx_fail_count))
7524 {
7525 ret = -EINVAL;
7526 goto done;
7527 }
7528 }
7529 else
7530 {
7531 goto done;
7532 }
7533
7534 if (0 == *tx_fail_count)
7535 {
7536 *pid = 0;
7537 goto done;
7538 }
7539
7540 pValue = param;
7541 pValue++;
7542
7543 ret = hdd_ParseUserParams(pValue, &param);
7544
7545 if (0 == ret)
7546 {
7547 if (1 != sscanf(param, "%hu", pid))
7548 {
7549 ret = -EINVAL;
7550 goto done;
7551 }
7552 }
7553 else
7554 {
7555 goto done;
7556 }
7557
7558done:
7559 return ret;
7560}
7561
7562static int hdd_open_cesium_nl_sock()
7563{
7564#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7565 struct netlink_kernel_cfg cfg = {
7566 .groups = WLAN_NLINK_MCAST_GRP_ID,
7567 .input = NULL
7568 };
7569#endif
7570 int ret = 0;
7571
7572#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
7573 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7574#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
7575 THIS_MODULE,
7576#endif
7577 &cfg);
7578#else
7579 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
7580 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
7581#endif
7582
7583 if (cesium_nl_srv_sock == NULL)
7584 {
7585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7586 "NLINK: cesium netlink_kernel_create failed");
7587 ret = -ECONNREFUSED;
7588 }
7589
7590 return ret;
7591}
7592
7593static void hdd_close_cesium_nl_sock()
7594{
7595 if (NULL != cesium_nl_srv_sock)
7596 {
7597 netlink_kernel_release(cesium_nl_srv_sock);
7598 cesium_nl_srv_sock = NULL;
7599 }
7600}
7601#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007602/**---------------------------------------------------------------------------
7603
7604 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
7605
7606 This is the function invoked by SME to inform the result of BMPS
7607 request issued by HDD
7608
7609 \param - callbackcontext - Pointer to cookie
7610 status - result of request
7611
7612 \return - None
7613
7614--------------------------------------------------------------------------*/
7615void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
7616{
7617
7618 struct completion *completion_var = (struct completion*) callbackContext;
7619
Arif Hussain6d2a3322013-11-17 19:50:10 -08007620 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07007621 if(completion_var != NULL)
7622 {
7623 complete(completion_var);
7624 }
7625}
7626
7627/**---------------------------------------------------------------------------
7628
7629 \brief hdd_get_cfg_file_size() -
7630
7631 This function reads the configuration file using the request firmware
7632 API and returns the configuration file size.
7633
7634 \param - pCtx - Pointer to the adapter .
7635 - pFileName - Pointer to the file name.
7636 - pBufSize - Pointer to the buffer size.
7637
7638 \return - 0 for success, non zero for failure
7639
7640 --------------------------------------------------------------------------*/
7641
7642VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
7643{
7644 int status;
7645 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7646
7647 ENTER();
7648
7649 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7650
7651 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7652 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7653 status = VOS_STATUS_E_FAILURE;
7654 }
7655 else {
7656 *pBufSize = pHddCtx->fw->size;
7657 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
7658 release_firmware(pHddCtx->fw);
7659 pHddCtx->fw = NULL;
7660 }
7661
7662 EXIT();
7663 return VOS_STATUS_SUCCESS;
7664}
7665
7666/**---------------------------------------------------------------------------
7667
7668 \brief hdd_read_cfg_file() -
7669
7670 This function reads the configuration file using the request firmware
7671 API and returns the cfg data and the buffer size of the configuration file.
7672
7673 \param - pCtx - Pointer to the adapter .
7674 - pFileName - Pointer to the file name.
7675 - pBuffer - Pointer to the data buffer.
7676 - pBufSize - Pointer to the buffer size.
7677
7678 \return - 0 for success, non zero for failure
7679
7680 --------------------------------------------------------------------------*/
7681
7682VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
7683 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
7684{
7685 int status;
7686 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
7687
7688 ENTER();
7689
7690 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
7691
7692 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
7693 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
7694 return VOS_STATUS_E_FAILURE;
7695 }
7696 else {
7697 if(*pBufSize != pHddCtx->fw->size) {
7698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
7699 "file size", __func__);
7700 release_firmware(pHddCtx->fw);
7701 pHddCtx->fw = NULL;
7702 return VOS_STATUS_E_FAILURE;
7703 }
7704 else {
7705 if(pBuffer) {
7706 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
7707 }
7708 release_firmware(pHddCtx->fw);
7709 pHddCtx->fw = NULL;
7710 }
7711 }
7712
7713 EXIT();
7714
7715 return VOS_STATUS_SUCCESS;
7716}
7717
7718/**---------------------------------------------------------------------------
7719
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307720 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07007721
7722 This function sets the user specified mac address using
7723 the command ifconfig wlanX hw ether <mac adress>.
7724
7725 \param - dev - Pointer to the net device.
7726 - addr - Pointer to the sockaddr.
7727 \return - 0 for success, non zero for failure
7728
7729 --------------------------------------------------------------------------*/
7730
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307731static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07007732{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307733 hdd_adapter_t *pAdapter;
7734 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007735 struct sockaddr *psta_mac_addr = addr;
7736 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307737 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007738
7739 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307740 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7741 if (NULL == pAdapter)
7742 {
7743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7744 "%s: Adapter is NULL",__func__);
7745 return -EINVAL;
7746 }
7747 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7748 ret = wlan_hdd_validate_context(pHddCtx);
7749 if (0 != ret)
7750 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05307751 return ret;
7752 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007753
7754 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07007755 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
7756
7757 EXIT();
7758 return halStatus;
7759}
7760
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307761/**---------------------------------------------------------------------------
7762
7763 \brief hdd_set_mac_address() -
7764
7765 Wrapper function to protect __hdd_set_mac_address() function from ssr
7766
7767 \param - dev - Pointer to the net device.
7768 - addr - Pointer to the sockaddr.
7769 \return - 0 for success, non zero for failure
7770
7771 --------------------------------------------------------------------------*/
7772static int hdd_set_mac_address(struct net_device *dev, void *addr)
7773{
7774 int ret;
7775
7776 vos_ssr_protect(__func__);
7777 ret = __hdd_set_mac_address(dev, addr);
7778 vos_ssr_unprotect(__func__);
7779
7780 return ret;
7781}
7782
Jeff Johnson295189b2012-06-20 16:38:30 -07007783tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
7784{
7785 int i;
7786 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7787 {
Abhishek Singheb183782014-02-06 13:37:21 +05307788 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 break;
7790 }
7791
7792 if( VOS_MAX_CONCURRENCY_PERSONA == i)
7793 return NULL;
7794
7795 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
7796 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
7797}
7798
7799void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
7800{
7801 int i;
7802 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
7803 {
7804 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
7805 {
7806 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
7807 break;
7808 }
7809 }
7810 return;
7811}
7812
7813#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7814 static struct net_device_ops wlan_drv_ops = {
7815 .ndo_open = hdd_open,
7816 .ndo_stop = hdd_stop,
7817 .ndo_uninit = hdd_uninit,
7818 .ndo_start_xmit = hdd_hard_start_xmit,
7819 .ndo_tx_timeout = hdd_tx_timeout,
7820 .ndo_get_stats = hdd_stats,
7821 .ndo_do_ioctl = hdd_ioctl,
7822 .ndo_set_mac_address = hdd_set_mac_address,
7823 .ndo_select_queue = hdd_select_queue,
7824#ifdef WLAN_FEATURE_PACKET_FILTERING
7825#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
7826 .ndo_set_rx_mode = hdd_set_multicast_list,
7827#else
7828 .ndo_set_multicast_list = hdd_set_multicast_list,
7829#endif //LINUX_VERSION_CODE
7830#endif
7831 };
Jeff Johnson295189b2012-06-20 16:38:30 -07007832 static struct net_device_ops wlan_mon_drv_ops = {
7833 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05307834 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 .ndo_uninit = hdd_uninit,
7836 .ndo_start_xmit = hdd_mon_hard_start_xmit,
7837 .ndo_tx_timeout = hdd_tx_timeout,
7838 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05307839 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07007840 .ndo_set_mac_address = hdd_set_mac_address,
7841 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05307842
Jeff Johnson295189b2012-06-20 16:38:30 -07007843#endif
7844
7845void hdd_set_station_ops( struct net_device *pWlanDev )
7846{
7847#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07007848 pWlanDev->netdev_ops = &wlan_drv_ops;
7849#else
7850 pWlanDev->open = hdd_open;
7851 pWlanDev->stop = hdd_stop;
7852 pWlanDev->uninit = hdd_uninit;
7853 pWlanDev->hard_start_xmit = NULL;
7854 pWlanDev->tx_timeout = hdd_tx_timeout;
7855 pWlanDev->get_stats = hdd_stats;
7856 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07007857 pWlanDev->set_mac_address = hdd_set_mac_address;
7858#endif
7859}
7860
Katya Nigam1fd24402015-02-16 14:52:19 +05307861void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
7862{
7863 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
7864 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
7865 #else
7866 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
7867 #endif
7868}
7869
Jeff Johnsoneed415b2013-01-18 16:11:20 -08007870static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07007871{
7872 struct net_device *pWlanDev = NULL;
7873 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007874 /*
7875 * cfg80211 initialization and registration....
7876 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05307877 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
7878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
7879 NET_NAME_UNKNOWN,
7880#endif
7881 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 if(pWlanDev != NULL)
7883 {
7884
7885 //Save the pointer to the net_device in the HDD adapter
7886 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
7887
Jeff Johnson295189b2012-06-20 16:38:30 -07007888 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
7889
7890 pAdapter->dev = pWlanDev;
7891 pAdapter->pHddCtx = pHddCtx;
7892 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05307893 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07007894
Rajeev79dbe4c2013-10-05 11:03:42 +05307895#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05307896 pAdapter->pBatchScanRsp = NULL;
7897 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07007898 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007899 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05307900 mutex_init(&pAdapter->hdd_batch_scan_lock);
7901#endif
7902
Jeff Johnson295189b2012-06-20 16:38:30 -07007903 pAdapter->isLinkUpSvcNeeded = FALSE;
7904 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
7905 //Init the net_device structure
7906 strlcpy(pWlanDev->name, name, IFNAMSIZ);
7907
7908 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
7909 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
7910 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
7911 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
7912
7913 hdd_set_station_ops( pAdapter->dev );
7914
7915 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
7917 pAdapter->wdev.wiphy = pHddCtx->wiphy;
7918 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07007919 /* set pWlanDev's parent to underlying device */
7920 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07007921
7922 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 }
7924
7925 return pAdapter;
7926}
7927
7928VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
7929{
7930 struct net_device *pWlanDev = pAdapter->dev;
7931 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
7932 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
7933 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
7934
7935 if( rtnl_lock_held )
7936 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08007937 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07007938 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
7939 {
7940 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
7941 return VOS_STATUS_E_FAILURE;
7942 }
7943 }
7944 if (register_netdevice(pWlanDev))
7945 {
7946 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
7947 return VOS_STATUS_E_FAILURE;
7948 }
7949 }
7950 else
7951 {
7952 if(register_netdev(pWlanDev))
7953 {
7954 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
7955 return VOS_STATUS_E_FAILURE;
7956 }
7957 }
7958 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
7959
7960 return VOS_STATUS_SUCCESS;
7961}
7962
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007963static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07007964{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007965 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007966
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007967 if (NULL == pAdapter)
7968 {
7969 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
7970 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007972
7973 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7974 {
7975 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
7976 return eHAL_STATUS_NOT_INITIALIZED;
7977 }
7978
7979 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
7980
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007981#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007982 /* need to make sure all of our scheduled work has completed.
7983 * This callback is called from MC thread context, so it is safe to
7984 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007985 *
7986 * Even though this is called from MC thread context, if there is a faulty
7987 * work item in the system, that can hang this call forever. So flushing
7988 * this global work queue is not safe; and now we make sure that
7989 * individual work queues are stopped correctly. But the cancel work queue
7990 * is a GPL only API, so the proprietary version of the driver would still
7991 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007992 */
7993 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07007994#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07007995
7996 /* We can be blocked while waiting for scheduled work to be
7997 * flushed, and the adapter structure can potentially be freed, in
7998 * which case the magic will have been reset. So make sure the
7999 * magic is still good, and hence the adapter structure is still
8000 * valid, before signaling completion */
8001 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
8002 {
8003 complete(&pAdapter->session_close_comp_var);
8004 }
8005
Jeff Johnson295189b2012-06-20 16:38:30 -07008006 return eHAL_STATUS_SUCCESS;
8007}
Manjeet Singh47ee8472016-04-11 11:57:18 +05308008/**
8009 * hdd_close_tx_queues() - close tx queues
8010 * @hdd_ctx: hdd global context
8011 *
8012 * Return: None
8013 */
8014static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
8015{
8016 VOS_STATUS status;
8017 hdd_adapter_t *adapter;
8018 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
8019 /* Not validating hdd_ctx as it's already done by the caller */
8020 ENTER();
8021 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
8022 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
8023 adapter = adapter_node->pAdapter;
8024 if (adapter && adapter->dev) {
8025 netif_tx_disable (adapter->dev);
8026 netif_carrier_off(adapter->dev);
8027 }
8028 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
8029 &next_adapter);
8030 adapter_node = next_adapter;
8031 }
8032 EXIT();
8033}
Jeff Johnson295189b2012-06-20 16:38:30 -07008034
8035VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
8036{
8037 struct net_device *pWlanDev = pAdapter->dev;
8038 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
8039 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8040 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8041 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308042 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008043
Nirav Shah7e3c8132015-06-22 23:51:42 +05308044 spin_lock_init( &pAdapter->sta_hash_lock);
8045 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
8046
Jeff Johnson295189b2012-06-20 16:38:30 -07008047 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008048 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 //Open a SME session for future operation
8050 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07008051 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008052 if ( !HAL_STATUS_SUCCESS( halStatus ) )
8053 {
8054 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008055 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008056 halStatus, halStatus );
8057 status = VOS_STATUS_E_FAILURE;
8058 goto error_sme_open;
8059 }
8060
8061 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05308062 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 &pAdapter->session_open_comp_var,
8064 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308065 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008066 {
8067 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308068 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07008069 status = VOS_STATUS_E_FAILURE;
8070 goto error_sme_open;
8071 }
8072
8073 // Register wireless extensions
8074 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
8075 {
8076 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008077 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 halStatus, halStatus );
8079 status = VOS_STATUS_E_FAILURE;
8080 goto error_register_wext;
8081 }
Katya Nigam1fd24402015-02-16 14:52:19 +05308082
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05308084 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8085 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
8086 #else
8087 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
8088 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008089
8090 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05308091 hddLog(VOS_TRACE_LEVEL_INFO,
8092 "%s: Set HDD connState to eConnectionState_NotConnected",
8093 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008094 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
8095
8096 //Set the default operation channel
8097 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
8098
8099 /* Make the default Auth Type as OPEN*/
8100 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
8101
8102 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
8103 {
8104 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008105 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 status, status );
8107 goto error_init_txrx;
8108 }
8109
8110 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8111
8112 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
8113 {
8114 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008115 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 status, status );
8117 goto error_wmm_init;
8118 }
8119
8120 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8121
8122 return VOS_STATUS_SUCCESS;
8123
8124error_wmm_init:
8125 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8126 hdd_deinit_tx_rx(pAdapter);
8127error_init_txrx:
8128 hdd_UnregisterWext(pWlanDev);
8129error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008130 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008131 {
8132 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008133 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05308134 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008135 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308137 unsigned long rc;
8138
Jeff Johnson295189b2012-06-20 16:38:30 -07008139 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308140 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008141 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07008142 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308143 if (rc <= 0)
8144 hddLog(VOS_TRACE_LEVEL_ERROR,
8145 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 }
8147}
8148error_sme_open:
8149 return status;
8150}
8151
Jeff Johnson295189b2012-06-20 16:38:30 -07008152void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
8153{
8154 hdd_cfg80211_state_t *cfgState;
8155
8156 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
8157
8158 if( NULL != cfgState->buf )
8159 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308160 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07008161 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
8162 rc = wait_for_completion_interruptible_timeout(
8163 &pAdapter->tx_action_cnf_event,
8164 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308165 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008166 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05308167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8168 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
8169 , __func__, rc);
8170
8171 // Inform tx status as FAILURE to upper layer and free cfgState->buf
8172 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008173 }
8174 }
8175 return;
8176}
Jeff Johnson295189b2012-06-20 16:38:30 -07008177
c_hpothu002231a2015-02-05 14:58:51 +05308178void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07008179{
8180 ENTER();
8181 switch ( pAdapter->device_mode )
8182 {
Katya Nigam1fd24402015-02-16 14:52:19 +05308183 case WLAN_HDD_IBSS:
8184 {
8185 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8186 {
8187 hdd_ibss_deinit_tx_rx( pAdapter );
8188 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8189 }
8190 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008191 case WLAN_HDD_INFRA_STATION:
8192 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008193 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008194 {
8195 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8196 {
8197 hdd_deinit_tx_rx( pAdapter );
8198 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8199 }
8200
8201 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8202 {
8203 hdd_wmm_adapter_close( pAdapter );
8204 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8205 }
8206
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 break;
8209 }
8210
8211 case WLAN_HDD_SOFTAP:
8212 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008213 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05308214
8215 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
8216 {
8217 hdd_wmm_adapter_close( pAdapter );
8218 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
8219 }
8220
Jeff Johnson295189b2012-06-20 16:38:30 -07008221 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008222
c_hpothu002231a2015-02-05 14:58:51 +05308223 hdd_unregister_hostapd(pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 hdd_set_conparam( 0 );
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 break;
8226 }
8227
8228 case WLAN_HDD_MONITOR:
8229 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008230 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
8231 {
8232 hdd_deinit_tx_rx( pAdapter );
8233 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
8234 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 break;
8236 }
8237
8238
8239 default:
8240 break;
8241 }
8242
8243 EXIT();
8244}
8245
8246void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
8247{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08008248 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308249
8250 ENTER();
8251 if (NULL == pAdapter)
8252 {
8253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8254 "%s: HDD adapter is Null", __func__);
8255 return;
8256 }
8257
8258 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07008259
Rajeev79dbe4c2013-10-05 11:03:42 +05308260#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308261 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8262 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08008263 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308264 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
8265 )
8266 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008267 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05308268 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08008269 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
8270 {
8271 hdd_deinit_batch_scan(pAdapter);
8272 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308273 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08008274 }
Rajeev79dbe4c2013-10-05 11:03:42 +05308275#endif
8276
Jeff Johnson295189b2012-06-20 16:38:30 -07008277 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
8278 if( rtnl_held )
8279 {
8280 unregister_netdevice(pWlanDev);
8281 }
8282 else
8283 {
8284 unregister_netdev(pWlanDev);
8285 }
8286 // note that the pAdapter is no longer valid at this point
8287 // since the memory has been reclaimed
8288 }
8289
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05308290 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008291}
8292
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008293void hdd_set_pwrparams(hdd_context_t *pHddCtx)
8294{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308295 VOS_STATUS status;
8296 hdd_adapter_t *pAdapter = NULL;
8297 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008298
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308299 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008300
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308301 /*loop through all adapters.*/
8302 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008303 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308304 pAdapter = pAdapterNode->pAdapter;
8305 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
8306 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008307
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308308 { // we skip this registration for modes other than STA and P2P client modes.
8309 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8310 pAdapterNode = pNext;
8311 continue;
8312 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008313
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308314 //Apply Dynamic DTIM For P2P
8315 //Only if ignoreDynamicDtimInP2pMode is not set in ini
8316 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
8317 pHddCtx->cfg_ini->enableModulatedDTIM) &&
8318 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8319 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
8320 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
8321 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
8322 (eConnectionState_Associated ==
8323 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
8324 (pHddCtx->cfg_ini->fIsBmpsEnabled))
8325 {
8326 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008327
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308328 powerRequest.uIgnoreDTIM = 1;
8329 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
8330
8331 if (pHddCtx->cfg_ini->enableModulatedDTIM)
8332 {
8333 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
8334 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
8335 }
8336 else
8337 {
8338 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
8339 }
8340
8341 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
8342 * specified during Enter/Exit BMPS when LCD off*/
8343 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8344 NULL, eANI_BOOLEAN_FALSE);
8345 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8346 NULL, eANI_BOOLEAN_FALSE);
8347
8348 /* switch to the DTIM specified in cfg.ini */
8349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05308350 "Switch to DTIM %d Listen interval %d",
8351 powerRequest.uDTIMPeriod,
8352 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308353 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8354 break;
8355
8356 }
8357
8358 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8359 pAdapterNode = pNext;
8360 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008361}
8362
8363void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
8364{
8365 /*Switch back to DTIM 1*/
8366 tSirSetPowerParamsReq powerRequest = { 0 };
8367
8368 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
8369 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07008370 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08008371
8372 /* Update ignoreDTIM and ListedInterval in CFG with default values */
8373 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
8374 NULL, eANI_BOOLEAN_FALSE);
8375 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
8376 NULL, eANI_BOOLEAN_FALSE);
8377
8378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8379 "Switch to DTIM%d",powerRequest.uListenInterval);
8380 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
8381
8382}
8383
Jeff Johnson295189b2012-06-20 16:38:30 -07008384VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
8385{
8386 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05308387 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
8388 {
8389 hddLog( LOGE, FL("Wlan Unload in progress"));
8390 return VOS_STATUS_E_PERM;
8391 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8393 {
8394 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8395 }
8396
8397 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8398 {
8399 sme_StartAutoBmpsTimer(pHddCtx->hHal);
8400 }
8401
8402 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8403 {
8404 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8405 }
8406
8407 return status;
8408}
8409
8410VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
8411{
8412 hdd_adapter_t *pAdapter = NULL;
8413 eHalStatus halStatus;
8414 VOS_STATUS status = VOS_STATUS_E_INVAL;
8415 v_BOOL_t disableBmps = FALSE;
8416 v_BOOL_t disableImps = FALSE;
8417
8418 switch(session_type)
8419 {
8420 case WLAN_HDD_INFRA_STATION:
8421 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008422 case WLAN_HDD_P2P_CLIENT:
8423 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008424 //Exit BMPS -> Is Sta/P2P Client is already connected
8425 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
8426 if((NULL != pAdapter)&&
8427 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8428 {
8429 disableBmps = TRUE;
8430 }
8431
8432 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
8433 if((NULL != pAdapter)&&
8434 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8435 {
8436 disableBmps = TRUE;
8437 }
8438
8439 //Exit both Bmps and Imps incase of Go/SAP Mode
8440 if((WLAN_HDD_SOFTAP == session_type) ||
8441 (WLAN_HDD_P2P_GO == session_type))
8442 {
8443 disableBmps = TRUE;
8444 disableImps = TRUE;
8445 }
8446
8447 if(TRUE == disableImps)
8448 {
8449 if (pHddCtx->cfg_ini->fIsImpsEnabled)
8450 {
8451 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
8452 }
8453 }
8454
8455 if(TRUE == disableBmps)
8456 {
8457 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
8458 {
8459 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
8460
8461 if(eHAL_STATUS_SUCCESS != halStatus)
8462 {
8463 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008464 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 VOS_ASSERT(0);
8466 return status;
8467 }
8468 }
8469
8470 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
8471 {
8472 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
8473
8474 if(eHAL_STATUS_SUCCESS != halStatus)
8475 {
8476 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008477 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 VOS_ASSERT(0);
8479 return status;
8480 }
8481 }
8482 }
8483
8484 if((TRUE == disableBmps) ||
8485 (TRUE == disableImps))
8486 {
8487 /* Now, get the chip into Full Power now */
8488 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
8489 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
8490 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
8491
8492 if(halStatus != eHAL_STATUS_SUCCESS)
8493 {
8494 if(halStatus == eHAL_STATUS_PMC_PENDING)
8495 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308496 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008497 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308498 ret = wait_for_completion_interruptible_timeout(
8499 &pHddCtx->full_pwr_comp_var,
8500 msecs_to_jiffies(1000));
8501 if (ret <= 0)
8502 {
8503 hddLog(VOS_TRACE_LEVEL_ERROR,
8504 "%s: wait on full_pwr_comp_var failed %ld",
8505 __func__, ret);
8506 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008507 }
8508 else
8509 {
8510 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08008511 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008512 VOS_ASSERT(0);
8513 return status;
8514 }
8515 }
8516
8517 status = VOS_STATUS_SUCCESS;
8518 }
8519
8520 break;
8521 }
8522 return status;
8523}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05308524
8525void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar)
8526{
8527 if (magic == NULL || cmpVar == NULL) {
8528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8529 FL("invalid arguments %p %p"), magic, cmpVar);
8530 return;
8531 }
8532 if (*magic != MON_MODE_MSG_MAGIC) {
8533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8534 FL("maic: %x"), *magic);
8535 return;
8536 }
8537
8538 complete(cmpVar);
8539 return;
8540}
8541
Katya Nigame7b69a82015-04-28 15:24:06 +05308542void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
8543 {
8544 hdd_mon_ctx_t *pMonCtx = NULL;
8545 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
8546
8547 pMonCtx->state = 0;
8548 pMonCtx->ChannelNo = 1;
8549 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05308550 pMonCtx->crcCheckEnabled = 1;
8551 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
8552 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05308553 pMonCtx->numOfMacFilters = 0;
8554 }
8555
Jeff Johnson295189b2012-06-20 16:38:30 -07008556
8557hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08008558 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07008559 tANI_U8 rtnl_held )
8560{
8561 hdd_adapter_t *pAdapter = NULL;
8562 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
8563 VOS_STATUS status = VOS_STATUS_E_FAILURE;
8564 VOS_STATUS exitbmpsStatus;
8565
Arif Hussain6d2a3322013-11-17 19:50:10 -08008566 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008567
Nirav Shah436658f2014-02-28 17:05:45 +05308568 if(macAddr == NULL)
8569 {
8570 /* Not received valid macAddr */
8571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8572 "%s:Unable to add virtual intf: Not able to get"
8573 "valid mac address",__func__);
8574 return NULL;
8575 }
8576
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 //Disable BMPS incase of Concurrency
8578 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
8579
8580 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
8581 {
8582 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308583 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 VOS_ASSERT(0);
8585 return NULL;
8586 }
8587
8588 switch(session_type)
8589 {
8590 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008592 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07008593 {
8594 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8595
8596 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308597 {
8598 hddLog(VOS_TRACE_LEVEL_FATAL,
8599 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308601 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008602
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308603#ifdef FEATURE_WLAN_TDLS
8604 /* A Mutex Lock is introduced while changing/initializing the mode to
8605 * protect the concurrent access for the Adapters by TDLS module.
8606 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308607 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308608#endif
8609
Jeff Johnsone7245742012-09-05 17:12:55 -07008610 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
8611 NL80211_IFTYPE_P2P_CLIENT:
8612 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07008613
Jeff Johnson295189b2012-06-20 16:38:30 -07008614 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308615#ifdef FEATURE_WLAN_TDLS
8616 mutex_unlock(&pHddCtx->tdls_lock);
8617#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308618
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308619 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05308620 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008621 if( VOS_STATUS_SUCCESS != status )
8622 goto err_free_netdev;
8623
8624 status = hdd_register_interface( pAdapter, rtnl_held );
8625 if( VOS_STATUS_SUCCESS != status )
8626 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308627#ifdef FEATURE_WLAN_TDLS
8628 mutex_lock(&pHddCtx->tdls_lock);
8629#endif
c_hpothu002231a2015-02-05 14:58:51 +05308630 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308631#ifdef FEATURE_WLAN_TDLS
8632 mutex_unlock(&pHddCtx->tdls_lock);
8633#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008634 goto err_free_netdev;
8635 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308636
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308637 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308638 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05308639
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308640#ifdef WLAN_NS_OFFLOAD
8641 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308642 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05308643#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008644 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308645 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008646 netif_tx_disable(pAdapter->dev);
8647 //netif_tx_disable(pWlanDev);
8648 netif_carrier_off(pAdapter->dev);
8649
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308650 if (WLAN_HDD_P2P_CLIENT == session_type ||
8651 WLAN_HDD_P2P_DEVICE == session_type)
8652 {
8653 /* Initialize the work queue to defer the
8654 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05308655 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308656 hdd_p2p_roc_work_queue);
8657 }
8658
Jeff Johnson295189b2012-06-20 16:38:30 -07008659 break;
8660 }
8661
Jeff Johnson295189b2012-06-20 16:38:30 -07008662 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008663 case WLAN_HDD_SOFTAP:
8664 {
8665 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
8666 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308667 {
8668 hddLog(VOS_TRACE_LEVEL_FATAL,
8669 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008670 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308671 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008672
Jeff Johnson295189b2012-06-20 16:38:30 -07008673 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
8674 NL80211_IFTYPE_AP:
8675 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008676 pAdapter->device_mode = session_type;
8677
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308678 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 status = hdd_init_ap_mode(pAdapter);
8680 if( VOS_STATUS_SUCCESS != status )
8681 goto err_free_netdev;
8682
Nirav Shah7e3c8132015-06-22 23:51:42 +05308683 status = hdd_sta_id_hash_attach(pAdapter);
8684 if (VOS_STATUS_SUCCESS != status)
8685 {
8686 hddLog(VOS_TRACE_LEVEL_FATAL,
8687 FL("failed to attach hash for session %d"), session_type);
8688 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
8689 goto err_free_netdev;
8690 }
8691
Jeff Johnson295189b2012-06-20 16:38:30 -07008692 status = hdd_register_hostapd( pAdapter, rtnl_held );
8693 if( VOS_STATUS_SUCCESS != status )
8694 {
c_hpothu002231a2015-02-05 14:58:51 +05308695 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07008696 goto err_free_netdev;
8697 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308698 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008699 netif_tx_disable(pAdapter->dev);
8700 netif_carrier_off(pAdapter->dev);
8701
8702 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05308703
8704 if (WLAN_HDD_P2P_GO == session_type)
8705 {
8706 /* Initialize the work queue to
8707 * defer the back to back RoC request */
8708 INIT_DELAYED_WORK(&pAdapter->roc_work,
8709 hdd_p2p_roc_work_queue);
8710 }
Bhargav Shahd0715912015-10-01 18:17:37 +05308711
Jeff Johnson295189b2012-06-20 16:38:30 -07008712 break;
8713 }
8714 case WLAN_HDD_MONITOR:
8715 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008716 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8717 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308718 {
8719 hddLog(VOS_TRACE_LEVEL_FATAL,
8720 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308722 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008723
Katya Nigame7b69a82015-04-28 15:24:06 +05308724 // Register wireless extensions
8725 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
8726 {
8727 hddLog(VOS_TRACE_LEVEL_FATAL,
8728 "hdd_register_wext() failed with status code %08d [x%08x]",
8729 status, status );
8730 status = VOS_STATUS_E_FAILURE;
8731 }
8732
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
8734 pAdapter->device_mode = session_type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008735#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
8736 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
8737#else
8738 pAdapter->dev->open = hdd_mon_open;
8739 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05308740 pAdapter->dev->stop = hdd_mon_stop;
8741 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008742#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05308743 status = hdd_register_interface( pAdapter, rtnl_held );
8744 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308745 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 hdd_init_tx_rx( pAdapter );
8747 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Katya Nigame7b69a82015-04-28 15:24:06 +05308748 //Stop the Interface TX queue.
8749 netif_tx_disable(pAdapter->dev);
8750 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008751 }
8752 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008753 case WLAN_HDD_FTM:
8754 {
8755 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
8756
8757 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308758 {
8759 hddLog(VOS_TRACE_LEVEL_FATAL,
8760 FL("failed to allocate adapter for session %d"), session_type);
8761 return NULL;
8762 }
8763
Jeff Johnson295189b2012-06-20 16:38:30 -07008764 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
8765 * message while loading driver in FTM mode. */
8766 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
8767 pAdapter->device_mode = session_type;
8768 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308769
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308770 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308771 hdd_init_tx_rx( pAdapter );
8772
8773 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308774 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05308775 netif_tx_disable(pAdapter->dev);
8776 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07008777 }
8778 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07008779 default:
8780 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308781 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
8782 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07008783 VOS_ASSERT(0);
8784 return NULL;
8785 }
8786 }
8787
Jeff Johnson295189b2012-06-20 16:38:30 -07008788 if( VOS_STATUS_SUCCESS == status )
8789 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05308790 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07008791 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
8792 if( NULL == pHddAdapterNode )
8793 {
8794 status = VOS_STATUS_E_NOMEM;
8795 }
8796 else
8797 {
8798 pHddAdapterNode->pAdapter = pAdapter;
8799 status = hdd_add_adapter_back ( pHddCtx,
8800 pHddAdapterNode );
8801 }
8802 }
8803
8804 if( VOS_STATUS_SUCCESS != status )
8805 {
8806 if( NULL != pAdapter )
8807 {
8808 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
8809 pAdapter = NULL;
8810 }
8811 if( NULL != pHddAdapterNode )
8812 {
8813 vos_mem_free( pHddAdapterNode );
8814 }
8815
8816 goto resume_bmps;
8817 }
8818
8819 if(VOS_STATUS_SUCCESS == status)
8820 {
8821 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
8822
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07008823 //Initialize the WoWL service
8824 if(!hdd_init_wowl(pAdapter))
8825 {
8826 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
8827 goto err_free_netdev;
8828 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008829 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008830 return pAdapter;
8831
8832err_free_netdev:
8833 free_netdev(pAdapter->dev);
8834 wlan_hdd_release_intf_addr( pHddCtx,
8835 pAdapter->macAddressCurrent.bytes );
8836
8837resume_bmps:
8838 //If bmps disabled enable it
8839 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
8840 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308841 if (pHddCtx->hdd_wlan_suspended)
8842 {
8843 hdd_set_pwrparams(pHddCtx);
8844 }
8845 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008846 }
8847 return NULL;
8848}
8849
8850VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8851 tANI_U8 rtnl_held )
8852{
8853 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
8854 VOS_STATUS status;
8855
8856 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
8857 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308858 {
8859 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
8860 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008861 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308862 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008863
8864 while ( pCurrent->pAdapter != pAdapter )
8865 {
8866 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
8867 if( VOS_STATUS_SUCCESS != status )
8868 break;
8869
8870 pCurrent = pNext;
8871 }
8872 pAdapterNode = pCurrent;
8873 if( VOS_STATUS_SUCCESS == status )
8874 {
8875 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8876 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308877
8878#ifdef FEATURE_WLAN_TDLS
8879
8880 /* A Mutex Lock is introduced while changing/initializing the mode to
8881 * protect the concurrent access for the Adapters by TDLS module.
8882 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308883 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308884#endif
8885
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 hdd_remove_adapter( pHddCtx, pAdapterNode );
8887 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08008888 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008889
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308890#ifdef FEATURE_WLAN_TDLS
8891 mutex_unlock(&pHddCtx->tdls_lock);
8892#endif
8893
Jeff Johnson295189b2012-06-20 16:38:30 -07008894
8895 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +05308896 if ((!vos_concurrent_open_sessions_running()) &&
8897 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
8898 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -07008899 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308900 if (pHddCtx->hdd_wlan_suspended)
8901 {
8902 hdd_set_pwrparams(pHddCtx);
8903 }
8904 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008905 }
8906
8907 return VOS_STATUS_SUCCESS;
8908 }
8909
8910 return VOS_STATUS_E_FAILURE;
8911}
8912
8913VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
8914{
8915 hdd_adapter_list_node_t *pHddAdapterNode;
8916 VOS_STATUS status;
8917
8918 ENTER();
8919
8920 do
8921 {
8922 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
8923 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
8924 {
8925 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
8926 vos_mem_free( pHddAdapterNode );
8927 }
8928 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
8929
8930 EXIT();
8931
8932 return VOS_STATUS_SUCCESS;
8933}
8934
8935void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
8936{
8937 v_U8_t addIE[1] = {0};
8938
8939 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8940 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
8941 eANI_BOOLEAN_FALSE) )
8942 {
8943 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008944 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008945 }
8946
8947 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8948 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8949 eANI_BOOLEAN_FALSE) )
8950 {
8951 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008952 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008953 }
8954
8955 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8956 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8957 eANI_BOOLEAN_FALSE) )
8958 {
8959 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008960 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008961 }
8962}
8963
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308964VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
8965 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -07008966{
8967 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
8968 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308969 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008970 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +05308971 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308972 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +05308973 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008974
Anand N Sunkad26d71b92014-12-24 18:08:22 +05308975 if (pHddCtx->isLogpInProgress) {
8976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8977 "%s:LOGP in Progress. Ignore!!!",__func__);
8978 return VOS_STATUS_E_FAILURE;
8979 }
8980
Jeff Johnson295189b2012-06-20 16:38:30 -07008981 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05308982
Kaushik, Sushant4975a572014-10-21 16:07:48 +05308983 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008984 switch(pAdapter->device_mode)
8985 {
Nirav Shah0cf4d892015-11-05 16:27:27 +05308986 case WLAN_HDD_IBSS:
8987 if ( VOS_TRUE == bCloseSession )
8988 {
8989 status = hdd_sta_id_hash_detach(pAdapter);
8990 if (status != VOS_STATUS_SUCCESS)
8991 hddLog(VOS_TRACE_LEVEL_ERROR,
8992 FL("sta id hash detach failed"));
8993 }
8994
Jeff Johnson295189b2012-06-20 16:38:30 -07008995 case WLAN_HDD_INFRA_STATION:
8996 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07008997 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05308998 {
8999 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +05309000#ifdef FEATURE_WLAN_TDLS
9001 mutex_lock(&pHddCtx->tdls_lock);
9002 wlan_hdd_tdls_exit(pAdapter, TRUE);
9003 mutex_unlock(&pHddCtx->tdls_lock);
9004#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309005 if( hdd_connIsConnected(pstation) ||
9006 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009007 {
9008 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
9009 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9010 pAdapter->sessionId,
9011 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
9012 else
9013 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
9014 pAdapter->sessionId,
9015 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309016 /* Success implies disconnect command got queued up successfully
9017 * Or cmd not queued as scan for SSID is in progress
9018 */
9019 if((eHAL_STATUS_SUCCESS == halStatus) ||
9020 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -07009021 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309022 ret = wait_for_completion_interruptible_timeout(
9023 &pAdapter->disconnect_comp_var,
9024 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +05309025 if (ret <= 0 &&
9026 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309027 {
9028 hddLog(VOS_TRACE_LEVEL_ERROR,
9029 "%s: wait on disconnect_comp_var failed %ld",
9030 __func__, ret);
9031 }
9032 }
9033 else
9034 {
9035 hddLog(LOGE, "%s: failed to post disconnect event to SME",
9036 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009037 }
9038 memset(&wrqu, '\0', sizeof(wrqu));
9039 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9040 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9041 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
9042 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309043 else if(pstation->conn_info.connState ==
9044 eConnectionState_Disconnecting)
9045 {
9046 ret = wait_for_completion_interruptible_timeout(
9047 &pAdapter->disconnect_comp_var,
9048 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9049 if (ret <= 0)
9050 {
9051 hddLog(VOS_TRACE_LEVEL_ERROR,
9052 FL("wait on disconnect_comp_var failed %ld"), ret);
9053 }
9054 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +05309055 else if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -07009056 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +05309057 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +05309059 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
9060 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309061 {
9062 while (pAdapter->is_roc_inprogress)
9063 {
9064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9065 "%s: ROC in progress for session %d!!!",
9066 __func__, pAdapter->sessionId);
9067 // waiting for ROC to expire
9068 msleep(500);
9069 /* In GO present case , if retry exceeds 3,
9070 it means something went wrong. */
9071 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
9072 {
9073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9074 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +05309075 if (eHAL_STATUS_SUCCESS !=
9076 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
9077 pAdapter->sessionId ))
9078 {
9079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9080 FL("Failed to Cancel Remain on Channel"));
9081 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309082 wait_for_completion_interruptible_timeout(
9083 &pAdapter->cancel_rem_on_chan_var,
9084 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9085 break;
9086 }
9087 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309088 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309089 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309090#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309091 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309092#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309093
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309094 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +05309095
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309096 /* It is possible that the caller of this function does not
9097 * wish to close the session
9098 */
9099 if (VOS_TRUE == bCloseSession &&
9100 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009101 {
9102 INIT_COMPLETION(pAdapter->session_close_comp_var);
9103 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309104 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
9105 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009106 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309107 unsigned long ret;
9108
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309110 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309111 &pAdapter->session_close_comp_var,
9112 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309113 if ( 0 >= ret)
9114 {
9115 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309116 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309117 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009118 }
9119 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05309120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 break;
9122
9123 case WLAN_HDD_SOFTAP:
9124 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +05309125 if ( VOS_TRUE == bCloseSession )
9126 {
9127 status = hdd_sta_id_hash_detach(pAdapter);
9128 if (status != VOS_STATUS_SUCCESS)
9129 hddLog(VOS_TRACE_LEVEL_ERROR,
9130 FL("sta id hash detach failed"));
9131 }
9132
Jeff Johnson295189b2012-06-20 16:38:30 -07009133 //Any softap specific cleanup here...
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309134 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
9135 while (pAdapter->is_roc_inprogress) {
9136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9137 "%s: ROC in progress for session %d!!!",
9138 __func__, pAdapter->sessionId);
9139 msleep(500);
9140 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
9141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9142 "%s: ROC completion is not received.!!!", __func__);
9143 WLANSAP_CancelRemainOnChannel(
9144 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
9145 wait_for_completion_interruptible_timeout(
9146 &pAdapter->cancel_rem_on_chan_var,
9147 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
9148 break;
9149 }
9150 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309151
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309152 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +05309153 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009154 mutex_lock(&pHddCtx->sap_lock);
9155 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9156 {
9157 VOS_STATUS status;
9158 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9159
9160 //Stop Bss.
9161 status = WLANSAP_StopBss(pHddCtx->pvosContext);
9162 if (VOS_IS_STATUS_SUCCESS(status))
9163 {
9164 hdd_hostapd_state_t *pHostapdState =
9165 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9166
9167 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9168
9169 if (!VOS_IS_STATUS_SUCCESS(status))
9170 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309171 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
9172 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07009173 }
9174 }
9175 else
9176 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009177 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009178 }
9179 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309180 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009181
9182 if (eHAL_STATUS_FAILURE ==
9183 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
9184 0, NULL, eANI_BOOLEAN_FALSE))
9185 {
9186 hddLog(LOGE,
9187 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009188 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 }
9190
9191 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
9192 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9193 eANI_BOOLEAN_FALSE) )
9194 {
9195 hddLog(LOGE,
9196 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
9197 }
9198
9199 // Reset WNI_CFG_PROBE_RSP Flags
9200 wlan_hdd_reset_prob_rspies(pAdapter);
9201 kfree(pAdapter->sessionCtx.ap.beacon);
9202 pAdapter->sessionCtx.ap.beacon = NULL;
9203 }
9204 mutex_unlock(&pHddCtx->sap_lock);
9205 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009206
Jeff Johnson295189b2012-06-20 16:38:30 -07009207 case WLAN_HDD_MONITOR:
9208 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009209
Jeff Johnson295189b2012-06-20 16:38:30 -07009210 default:
9211 break;
9212 }
9213
9214 EXIT();
9215 return VOS_STATUS_SUCCESS;
9216}
9217
9218VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
9219{
9220 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9221 VOS_STATUS status;
9222 hdd_adapter_t *pAdapter;
9223
9224 ENTER();
9225
9226 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9227
9228 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9229 {
9230 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -07009231
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309232 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009233
9234 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9235 pAdapterNode = pNext;
9236 }
9237
9238 EXIT();
9239
9240 return VOS_STATUS_SUCCESS;
9241}
9242
Rajeev Kumarf999e582014-01-09 17:33:29 -08009243
9244#ifdef FEATURE_WLAN_BATCH_SCAN
9245/**---------------------------------------------------------------------------
9246
9247 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
9248 structures
9249
9250 \param - pAdapter Pointer to HDD adapter
9251
9252 \return - None
9253
9254 --------------------------------------------------------------------------*/
9255void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
9256{
9257 tHddBatchScanRsp *pNode;
9258 tHddBatchScanRsp *pPrev;
9259
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309260 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009261 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +05309262 hddLog(VOS_TRACE_LEVEL_ERROR,
9263 "%s: Adapter context is Null", __func__);
9264 return;
9265 }
9266
9267 pNode = pAdapter->pBatchScanRsp;
9268 while (pNode)
9269 {
9270 pPrev = pNode;
9271 pNode = pNode->pNext;
9272 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -08009273 }
9274
9275 pAdapter->pBatchScanRsp = NULL;
9276 pAdapter->numScanList = 0;
9277 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
9278 pAdapter->prev_batch_id = 0;
9279
9280 return;
9281}
9282#endif
9283
9284
Jeff Johnson295189b2012-06-20 16:38:30 -07009285VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
9286{
9287 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9288 VOS_STATUS status;
9289 hdd_adapter_t *pAdapter;
9290
9291 ENTER();
9292
9293 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9294
9295 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9296 {
9297 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 netif_tx_disable(pAdapter->dev);
9300 netif_carrier_off(pAdapter->dev);
9301
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009302 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
9303
Jeff Johnson295189b2012-06-20 16:38:30 -07009304 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309305
Katya Nigam1fd24402015-02-16 14:52:19 +05309306 if(pAdapter->device_mode == WLAN_HDD_IBSS )
9307 hdd_ibss_deinit_tx_rx(pAdapter);
9308
Nirav Shah7e3c8132015-06-22 23:51:42 +05309309 status = hdd_sta_id_hash_detach(pAdapter);
9310 if (status != VOS_STATUS_SUCCESS)
9311 hddLog(VOS_TRACE_LEVEL_ERROR,
9312 FL("sta id hash detach failed for session id %d"),
9313 pAdapter->sessionId);
9314
Agarwal Ashish6267caa2014-08-06 19:16:21 +05309315 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9316
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309317 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9318 {
9319 hdd_wmm_adapter_close( pAdapter );
9320 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9321 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009322
Siddharth Bhal2db319d2014-12-03 12:37:18 +05309323 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9324 {
9325 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
9326 }
9327
Rajeev Kumarf999e582014-01-09 17:33:29 -08009328#ifdef FEATURE_WLAN_BATCH_SCAN
9329 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9330 {
9331 hdd_deinit_batch_scan(pAdapter);
9332 }
9333#endif
9334
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309335#ifdef FEATURE_WLAN_TDLS
9336 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +05309337 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05309338 mutex_unlock(&pHddCtx->tdls_lock);
9339#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009340 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9341 pAdapterNode = pNext;
9342 }
9343
9344 EXIT();
9345
9346 return VOS_STATUS_SUCCESS;
9347}
9348
9349VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
9350{
9351 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9352 VOS_STATUS status;
9353 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309354 eConnectionState connState;
Jeff Johnson295189b2012-06-20 16:38:30 -07009355
9356 ENTER();
9357
9358 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9359
9360 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9361 {
9362 pAdapter = pAdapterNode->pAdapter;
9363
Kumar Anand82c009f2014-05-29 00:29:42 -07009364 hdd_wmm_init( pAdapter );
9365
Jeff Johnson295189b2012-06-20 16:38:30 -07009366 switch(pAdapter->device_mode)
9367 {
9368 case WLAN_HDD_INFRA_STATION:
9369 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009370 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309371
9372 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
9373
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 hdd_init_station_mode(pAdapter);
9375 /* Open the gates for HDD to receive Wext commands */
9376 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009377 pHddCtx->scan_info.mScanPending = FALSE;
9378 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009379
9380 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +05309381 if (!pHddCtx->isLogpInProgress)
9382 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009383
9384 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309385 if (eConnectionState_Associated == connState ||
9386 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -07009387 {
9388 union iwreq_data wrqu;
9389 memset(&wrqu, '\0', sizeof(wrqu));
9390 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
9391 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
9392 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -07009393 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009394
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +05309396 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +05309397 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009398 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309399 else if (eConnectionState_Connecting == connState)
9400 {
9401 /*
9402 * Indicate connect failure to supplicant if we were in the
9403 * process of connecting
9404 */
9405 cfg80211_connect_result(pAdapter->dev, NULL,
9406 NULL, 0, NULL, 0,
9407 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
9408 GFP_KERNEL);
9409 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009410 break;
9411
9412 case WLAN_HDD_SOFTAP:
9413 /* softAP can handle SSR */
9414 break;
9415
9416 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009417 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -07009419 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 break;
9421
9422 case WLAN_HDD_MONITOR:
9423 /* monitor interface start */
9424 break;
9425 default:
9426 break;
9427 }
9428
9429 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9430 pAdapterNode = pNext;
9431 }
9432
9433 EXIT();
9434
9435 return VOS_STATUS_SUCCESS;
9436}
9437
9438VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
9439{
9440 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9441 hdd_adapter_t *pAdapter;
9442 VOS_STATUS status;
9443 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309444 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009445
9446 ENTER();
9447
9448 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9449
9450 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9451 {
9452 pAdapter = pAdapterNode->pAdapter;
9453
9454 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9455 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9456 {
9457 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9458 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9459
Abhishek Singhf4669da2014-05-26 15:07:49 +05309460 hddLog(VOS_TRACE_LEVEL_INFO,
9461 "%s: Set HDD connState to eConnectionState_NotConnected",
9462 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309463 spin_lock_bh(&pAdapter->lock_for_active_session);
9464 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
9465 {
9466 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
9467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +05309469 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 init_completion(&pAdapter->disconnect_comp_var);
9471 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
9472 eCSR_DISCONNECT_REASON_UNSPECIFIED);
9473
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309474 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009475 &pAdapter->disconnect_comp_var,
9476 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309477 if (0 >= ret)
9478 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
9479 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -07009480
9481 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
9482 pHddCtx->isAmpAllowed = VOS_FALSE;
9483 sme_RoamConnect(pHddCtx->hHal,
9484 pAdapter->sessionId, &(pWextState->roamProfile),
9485 &roamId);
9486 }
9487
9488 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9489 pAdapterNode = pNext;
9490 }
9491
9492 EXIT();
9493
9494 return VOS_STATUS_SUCCESS;
9495}
9496
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009497void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
9498{
9499 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9500 VOS_STATUS status;
9501 hdd_adapter_t *pAdapter;
9502 hdd_station_ctx_t *pHddStaCtx;
9503 hdd_ap_ctx_t *pHddApCtx;
9504 hdd_hostapd_state_t * pHostapdState;
9505 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
9506 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
9507 const char *p2pMode = "DEV";
9508 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009509
9510 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9511 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9512 {
9513 pAdapter = pAdapterNode->pAdapter;
9514 switch (pAdapter->device_mode) {
9515 case WLAN_HDD_INFRA_STATION:
9516 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9517 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9518 staChannel = pHddStaCtx->conn_info.operationChannel;
9519 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
9520 }
9521 break;
9522 case WLAN_HDD_P2P_CLIENT:
9523 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9524 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
9525 p2pChannel = pHddStaCtx->conn_info.operationChannel;
9526 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
9527 p2pMode = "CLI";
9528 }
9529 break;
9530 case WLAN_HDD_P2P_GO:
9531 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9532 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9533 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9534 p2pChannel = pHddApCtx->operatingChannel;
9535 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
9536 }
9537 p2pMode = "GO";
9538 break;
9539 case WLAN_HDD_SOFTAP:
9540 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9541 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9542 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
9543 apChannel = pHddApCtx->operatingChannel;
9544 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
9545 }
9546 break;
9547 default:
9548 break;
9549 }
9550 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9551 pAdapterNode = pNext;
9552 }
9553 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
9554 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
9555 }
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309556 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009557 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
9558 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309559 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009560 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
9561 }
9562 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05309563 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -07009564 apChannel, MAC_ADDR_ARRAY(apBssid));
9565 }
9566
9567 if (p2pChannel > 0 && apChannel > 0) {
9568 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
9569 }
9570}
9571
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009572bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -07009573{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009574 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -07009575}
9576
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009577/* Once SSR is disabled then it cannot be set. */
9578void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -07009579{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -07009580 if (HDD_SSR_DISABLED == isSsrRequired)
9581 return;
9582
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 isSsrRequired = value;
9584}
9585
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +05309586void hdd_set_pre_close( hdd_context_t *pHddCtx)
9587{
9588 sme_PreClose(pHddCtx->hHal);
9589}
9590
Jeff Johnson295189b2012-06-20 16:38:30 -07009591VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
9592 hdd_adapter_list_node_t** ppAdapterNode)
9593{
9594 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309595 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009596 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
9597 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309598 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009599 return status;
9600}
9601
9602VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
9603 hdd_adapter_list_node_t* pAdapterNode,
9604 hdd_adapter_list_node_t** pNextAdapterNode)
9605{
9606 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309607 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
9609 (hdd_list_node_t*) pAdapterNode,
9610 (hdd_list_node_t**)pNextAdapterNode );
9611
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309612 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 return status;
9614}
9615
9616VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
9617 hdd_adapter_list_node_t* pAdapterNode)
9618{
9619 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309620 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009621 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
9622 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309623 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 return status;
9625}
9626
9627VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
9628 hdd_adapter_list_node_t** ppAdapterNode)
9629{
9630 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309631 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
9633 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309634 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 return status;
9636}
9637
9638VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
9639 hdd_adapter_list_node_t* pAdapterNode)
9640{
9641 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309642 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
9644 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309645 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009646 return status;
9647}
9648
9649VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
9650 hdd_adapter_list_node_t* pAdapterNode)
9651{
9652 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309653 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
9655 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +05309656 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 return status;
9658}
9659
9660hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
9661 tSirMacAddr macAddr )
9662{
9663 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9664 hdd_adapter_t *pAdapter;
9665 VOS_STATUS status;
9666
9667 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9668
9669 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9670 {
9671 pAdapter = pAdapterNode->pAdapter;
9672
9673 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
9674 macAddr, sizeof(tSirMacAddr) ) )
9675 {
9676 return pAdapter;
9677 }
9678 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9679 pAdapterNode = pNext;
9680 }
9681
9682 return NULL;
9683
9684}
9685
9686hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
9687{
9688 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9689 hdd_adapter_t *pAdapter;
9690 VOS_STATUS status;
9691
9692 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9693
9694 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9695 {
9696 pAdapter = pAdapterNode->pAdapter;
9697
9698 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
9699 IFNAMSIZ ) )
9700 {
9701 return pAdapter;
9702 }
9703 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9704 pAdapterNode = pNext;
9705 }
9706
9707 return NULL;
9708
9709}
9710
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +05309711hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
9712 tANI_U32 sme_session_id )
9713{
9714 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9715 hdd_adapter_t *pAdapter;
9716 VOS_STATUS vos_status;
9717
9718
9719 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
9720
9721 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
9722 {
9723 pAdapter = pAdapterNode->pAdapter;
9724
9725 if (pAdapter->sessionId == sme_session_id)
9726 return pAdapter;
9727
9728 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
9729 pAdapterNode = pNext;
9730 }
9731
9732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9733 "%s: sme_session_id %d does not exist with host",
9734 __func__, sme_session_id);
9735
9736 return NULL;
9737}
9738
Jeff Johnson295189b2012-06-20 16:38:30 -07009739hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
9740{
9741 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9742 hdd_adapter_t *pAdapter;
9743 VOS_STATUS status;
9744
9745 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9746
9747 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9748 {
9749 pAdapter = pAdapterNode->pAdapter;
9750
9751 if( pAdapter && (mode == pAdapter->device_mode) )
9752 {
9753 return pAdapter;
9754 }
9755 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9756 pAdapterNode = pNext;
9757 }
9758
9759 return NULL;
9760
9761}
9762
9763//Remove this function later
9764hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
9765{
9766 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9767 hdd_adapter_t *pAdapter;
9768 VOS_STATUS status;
9769
9770 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9771
9772 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9773 {
9774 pAdapter = pAdapterNode->pAdapter;
9775
9776 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
9777 {
9778 return pAdapter;
9779 }
9780
9781 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9782 pAdapterNode = pNext;
9783 }
9784
9785 return NULL;
9786
9787}
9788
Jeff Johnson295189b2012-06-20 16:38:30 -07009789/**---------------------------------------------------------------------------
9790
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05309791 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009792
9793 This API returns the operating channel of the requested device mode
9794
9795 \param - pHddCtx - Pointer to the HDD context.
9796 - mode - Device mode for which operating channel is required
9797 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
9798 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
9799 \return - channel number. "0" id the requested device is not found OR it is not connected.
9800 --------------------------------------------------------------------------*/
9801v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
9802{
9803 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
9804 VOS_STATUS status;
9805 hdd_adapter_t *pAdapter;
9806 v_U8_t operatingChannel = 0;
9807
9808 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9809
9810 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9811 {
9812 pAdapter = pAdapterNode->pAdapter;
9813
9814 if( mode == pAdapter->device_mode )
9815 {
9816 switch(pAdapter->device_mode)
9817 {
9818 case WLAN_HDD_INFRA_STATION:
9819 case WLAN_HDD_P2P_CLIENT:
9820 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
9821 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
9822 break;
9823 case WLAN_HDD_SOFTAP:
9824 case WLAN_HDD_P2P_GO:
9825 /*softap connection info */
9826 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9827 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
9828 break;
9829 default:
9830 break;
9831 }
9832
9833 break; //Found the device of interest. break the loop
9834 }
9835
9836 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9837 pAdapterNode = pNext;
9838 }
9839 return operatingChannel;
9840}
9841
9842#ifdef WLAN_FEATURE_PACKET_FILTERING
9843/**---------------------------------------------------------------------------
9844
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309845 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -07009846
9847 This used to set the multicast address list.
9848
9849 \param - dev - Pointer to the WLAN device.
9850 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309851 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -07009852
9853 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309854static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07009855{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309856 hdd_adapter_t *pAdapter;
9857 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309859 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009860 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309861
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309862 ENTER();
9863
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309864 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309865 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 {
9867 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309868 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009869 return;
9870 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309871 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9872 ret = wlan_hdd_validate_context(pHddCtx);
9873 if (0 != ret)
9874 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309875 return;
9876 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009877 if (dev->flags & IFF_ALLMULTI)
9878 {
9879 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009880 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309881 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009882 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309883 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 {
9885 mc_count = netdev_mc_count(dev);
9886 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009887 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
9889 {
9890 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009891 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309892 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 return;
9894 }
9895
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309896 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -07009897
9898 netdev_for_each_mc_addr(ha, dev) {
9899 if (i == mc_count)
9900 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309901 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
9902 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -08009903 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309904 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +05309905 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -07009906 i++;
9907 }
9908 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309909
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +05309910 if (pHddCtx->hdd_wlan_suspended)
9911 {
9912 /*
9913 * Configure the Mcast address list to FW
9914 * If wlan is already in suspend mode
9915 */
9916 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
9917 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309918 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009919 return;
9920}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309921
9922static void hdd_set_multicast_list(struct net_device *dev)
9923{
9924 vos_ssr_protect(__func__);
9925 __hdd_set_multicast_list(dev);
9926 vos_ssr_unprotect(__func__);
9927}
Jeff Johnson295189b2012-06-20 16:38:30 -07009928#endif
9929
9930/**---------------------------------------------------------------------------
9931
9932 \brief hdd_select_queue() -
9933
9934 This function is registered with the Linux OS for network
9935 core to decide which queue to use first.
9936
9937 \param - dev - Pointer to the WLAN device.
9938 - skb - Pointer to OS packet (sk_buff).
9939 \return - ac, Queue Index/access category corresponding to UP in IP header
9940
9941 --------------------------------------------------------------------------*/
9942v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309943 struct sk_buff *skb
9944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
9945 , void *accel_priv
9946#endif
9947#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9948 , select_queue_fallback_t fallback
9949#endif
9950)
Jeff Johnson295189b2012-06-20 16:38:30 -07009951{
9952 return hdd_wmm_select_queue(dev, skb);
9953}
9954
9955
9956/**---------------------------------------------------------------------------
9957
9958 \brief hdd_wlan_initial_scan() -
9959
9960 This function triggers the initial scan
9961
9962 \param - pAdapter - Pointer to the HDD adapter.
9963
9964 --------------------------------------------------------------------------*/
9965void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
9966{
9967 tCsrScanRequest scanReq;
9968 tCsrChannelInfo channelInfo;
9969 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -07009970 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9972
9973 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
9974 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
9975 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
9976
9977 if(sme_Is11dSupported(pHddCtx->hHal))
9978 {
9979 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
9980 if ( HAL_STATUS_SUCCESS( halStatus ) )
9981 {
9982 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
9983 if( !scanReq.ChannelInfo.ChannelList )
9984 {
9985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
9986 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009987 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 return;
9989 }
9990 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
9991 channelInfo.numOfChannels);
9992 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
9993 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08009994 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009995 }
9996
9997 scanReq.scanType = eSIR_PASSIVE_SCAN;
9998 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
9999 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
10000 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
10001 }
10002 else
10003 {
10004 scanReq.scanType = eSIR_ACTIVE_SCAN;
10005 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10006 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
10007 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
10008 }
10009
10010 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
10011 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10012 {
10013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
10014 __func__, halStatus );
10015 }
10016
10017 if(sme_Is11dSupported(pHddCtx->hHal))
10018 vos_mem_free(scanReq.ChannelInfo.ChannelList);
10019}
10020
Jeff Johnson295189b2012-06-20 16:38:30 -070010021/**---------------------------------------------------------------------------
10022
10023 \brief hdd_full_power_callback() - HDD full power callback function
10024
10025 This is the function invoked by SME to inform the result of a full power
10026 request issued by HDD
10027
10028 \param - callbackcontext - Pointer to cookie
10029 \param - status - result of request
10030
10031 \return - None
10032
10033 --------------------------------------------------------------------------*/
10034static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
10035{
Jeff Johnson72a40512013-12-19 10:14:15 -080010036 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010037
10038 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010039 "%s: context = %p, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010040
10041 if (NULL == callbackContext)
10042 {
10043 hddLog(VOS_TRACE_LEVEL_ERROR,
10044 "%s: Bad param, context [%p]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010045 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 return;
10047 }
10048
Jeff Johnson72a40512013-12-19 10:14:15 -080010049 /* there is a race condition that exists between this callback
10050 function and the caller since the caller could time out either
10051 before or while this code is executing. we use a spinlock to
10052 serialize these actions */
10053 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010054
10055 if (POWER_CONTEXT_MAGIC != pContext->magic)
10056 {
10057 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080010058 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 hddLog(VOS_TRACE_LEVEL_WARN,
10060 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010061 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 return;
10063 }
10064
Jeff Johnson72a40512013-12-19 10:14:15 -080010065 /* context is valid so caller is still waiting */
10066
10067 /* paranoia: invalidate the magic */
10068 pContext->magic = 0;
10069
10070 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080010072
10073 /* serialization is complete */
10074 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010075}
10076
Katya Nigamf0511f62015-05-05 16:40:57 +053010077void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
10078{
10079 pMonCtx->typeSubtypeBitmap = 0;
10080 if( type%10 ) /* Management Packets */
10081 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
10082 type/=10;
10083 if( type%10 ) /* Control Packets */
10084 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
10085 type/=10;
10086 if( type%10 ) /* Data Packets */
10087 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
10088}
10089
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010090VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar,
10091 hdd_mon_ctx_t *pMonCtx , void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053010092{
10093 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010094 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010095
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010096 if (MON_MODE_START == pMonCtx->state)
10097 monMsg.type = WDA_MON_START_REQ;
10098 else if (MON_MODE_STOP == pMonCtx->state)
10099 monMsg.type = WDA_MON_STOP_REQ;
10100 else {
10101 hddLog(VOS_TRACE_LEVEL_ERROR,
10102 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053010103 return VOS_STATUS_E_FAILURE;
10104 }
10105
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010106 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
10107 if (pMonModeReq == NULL) {
10108 hddLog(VOS_TRACE_LEVEL_ERROR,
10109 FL("fail to allocate memory for monitor mode req"));
10110 return VOS_STATUS_E_FAILURE;
10111 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010112
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010113 pMonModeReq->magic = magic;
10114 pMonModeReq->cmpVar = cmpVar;
10115 pMonModeReq->data = pMonCtx;
10116 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053010117
Katya Nigamf0511f62015-05-05 16:40:57 +053010118 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010119 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053010120 monMsg.bodyval = 0;
10121
10122 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
10123 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
10124 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010125 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053010126 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010127 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053010128}
10129
Katya Nigame7b69a82015-04-28 15:24:06 +053010130void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
10131{
10132 VOS_STATUS vosStatus;
10133 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010134 long ret;
10135 hdd_mon_ctx_t *pMonCtx = NULL;
10136 v_U32_t magic;
10137 struct completion cmpVar;
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010138
Katya Nigame7b69a82015-04-28 15:24:06 +053010139 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
10140 if(pAdapter == NULL || pVosContext == NULL)
10141 {
10142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
10143 return ;
10144 }
Katya Nigamf0511f62015-05-05 16:40:57 +053010145
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053010146 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
10147 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
10148 pMonCtx->state = MON_MODE_STOP;
10149 magic = MON_MODE_MSG_MAGIC;
10150 init_completion(&cmpVar);
10151 if (VOS_STATUS_SUCCESS !=
10152 wlan_hdd_mon_postMsg(&magic, &cmpVar,
10153 pMonCtx, hdd_monPostMsgCb)) {
10154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10155 FL("failed to post MON MODE REQ"));
10156 pMonCtx->state = MON_MODE_START;
10157 magic = 0;
10158 return;
10159 }
10160 ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT);
10161 magic = 0;
10162 if (ret <= 0 ) {
10163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10164 FL("timeout on monitor mode completion %ld"), ret);
10165 }
10166 }
10167
Katya Nigame7b69a82015-04-28 15:24:06 +053010168 hdd_UnregisterWext(pAdapter->dev);
10169
10170 vos_mon_stop( pVosContext );
10171
10172 vosStatus = vos_sched_close( pVosContext );
10173 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10174 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10175 "%s: Failed to close VOSS Scheduler",__func__);
10176 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10177 }
10178
10179 vosStatus = vos_nv_close();
10180 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10181 {
10182 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10183 "%s: Failed to close NV", __func__);
10184 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10185 }
10186
10187 vos_close(pVosContext);
10188
10189 #ifdef WLAN_KD_READY_NOTIFIER
10190 nl_srv_exit(pHddCtx->ptt_pid);
10191 #else
10192 nl_srv_exit();
10193 #endif
10194
Katya Nigame7b69a82015-04-28 15:24:06 +053010195 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053010196}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010197/**
10198 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
10199 * @ wiphy: the wiphy to validate against
10200 *
10201 * Return: void
10202 */
10203void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
10204{
10205 int i =0;
10206 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
10207 {
10208 if (NULL != wiphy->bands[i] &&
10209 (NULL != wiphy->bands[i]->channels))
10210 {
10211 vos_mem_free(wiphy->bands[i]->channels);
10212 wiphy->bands[i]->channels = NULL;
10213 }
10214 }
10215}
Jeff Johnson295189b2012-06-20 16:38:30 -070010216/**---------------------------------------------------------------------------
10217
10218 \brief hdd_wlan_exit() - HDD WLAN exit function
10219
10220 This is the driver exit point (invoked during rmmod)
10221
10222 \param - pHddCtx - Pointer to the HDD Context
10223
10224 \return - None
10225
10226 --------------------------------------------------------------------------*/
10227void hdd_wlan_exit(hdd_context_t *pHddCtx)
10228{
10229 eHalStatus halStatus;
10230 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
10231 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053010232 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010233 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080010234 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010235 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053010236 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010237
10238 ENTER();
10239
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010240
Katya Nigame7b69a82015-04-28 15:24:06 +053010241 if (VOS_MONITOR_MODE == hdd_get_conparam())
10242 {
10243 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
10244 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053010245 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053010246 }
10247 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080010248 {
10249 // Unloading, restart logic is no more required.
10250 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070010251
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010252#ifdef FEATURE_WLAN_TDLS
10253 /* At the time of driver unloading; if tdls connection is present;
10254 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
10255 * wlan_hdd_tdls_find_peer always checks for valid context;
10256 * as load/unload in progress there can be a race condition.
10257 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
10258 * when tdls state is enabled.
10259 * As soon as driver set load/unload flag; tdls flag also needs
10260 * to be disabled so that hdd_rx_packet_cbk won't call
10261 * wlan_hdd_tdls_find_peer.
10262 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053010263 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
10264 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053010265#endif
10266
c_hpothu5ab05e92014-06-13 17:34:05 +053010267 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10268 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 {
c_hpothu5ab05e92014-06-13 17:34:05 +053010270 pAdapter = pAdapterNode->pAdapter;
10271 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070010272 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053010273 /* Disable TX on the interface, after this hard_start_xmit() will
10274 * not be called on that interface
10275 */
10276 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10277 netif_tx_disable(pAdapter->dev);
10278
10279 /* Mark the interface status as "down" for outside world */
10280 netif_carrier_off(pAdapter->dev);
10281
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010282 /* DeInit the adapter. This ensures that all data packets
10283 * are freed.
10284 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010285#ifdef FEATURE_WLAN_TDLS
10286 mutex_lock(&pHddCtx->tdls_lock);
10287#endif
c_hpothu002231a2015-02-05 14:58:51 +053010288 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053010289#ifdef FEATURE_WLAN_TDLS
10290 mutex_unlock(&pHddCtx->tdls_lock);
10291#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053010292 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
10293
10294 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053010295
c_hpothu5ab05e92014-06-13 17:34:05 +053010296 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
10297 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
10298 {
10299 wlan_hdd_cfg80211_deregister_frames(pAdapter);
10300 hdd_UnregisterWext(pAdapter->dev);
10301 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010302
Jeff Johnson295189b2012-06-20 16:38:30 -070010303 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010304 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10305 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 }
mukul sharmabab477d2015-06-11 17:14:55 +053010307
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010308 // Cancel any outstanding scan requests. We are about to close all
10309 // of our adapters, but an adapter structure is what SME passes back
10310 // to our callback function. Hence if there are any outstanding scan
10311 // requests then there is a race condition between when the adapter
10312 // is closed and when the callback is invoked.We try to resolve that
10313 // race condition here by canceling any outstanding scans before we
10314 // close the adapters.
10315 // Note that the scans may be cancelled in an asynchronous manner,
10316 // so ideally there needs to be some kind of synchronization. Rather
10317 // than introduce a new synchronization here, we will utilize the
10318 // fact that we are about to Request Full Power, and since that is
10319 // synchronized, the expectation is that by the time Request Full
10320 // Power has completed all scans will be cancelled.
10321 if (pHddCtx->scan_info.mScanPending)
10322 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053010323 if(NULL != pAdapter)
10324 {
10325 hddLog(VOS_TRACE_LEVEL_INFO,
10326 FL("abort scan mode: %d sessionId: %d"),
10327 pAdapter->device_mode,
10328 pAdapter->sessionId);
10329 }
10330 hdd_abort_mac_scan(pHddCtx,
10331 pHddCtx->scan_info.sessionId,
10332 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010333 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010334 }
c_hpothu5ab05e92014-06-13 17:34:05 +053010335 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080010336 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010337 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053010338 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
10339 {
10340 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
10341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10342 "%s: in middle of FTM START", __func__);
10343 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
10344 msecs_to_jiffies(20000));
10345 if(!lrc)
10346 {
10347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10348 "%s: timedout on ftmStartCmpVar fatal error", __func__);
10349 }
10350 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080010351 wlan_hdd_ftm_close(pHddCtx);
10352 goto free_hdd_ctx;
10353 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010354
Jeff Johnson295189b2012-06-20 16:38:30 -070010355 /* DeRegister with platform driver as client for Suspend/Resume */
10356 vosStatus = hddDeregisterPmOps(pHddCtx);
10357 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10358 {
10359 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
10360 VOS_ASSERT(0);
10361 }
10362
10363 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
10364 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
10365 {
10366 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
10367 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010368
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070010369 //Stop the traffic monitor timer
10370 if ( VOS_TIMER_STATE_RUNNING ==
10371 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))
10372 {
10373 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
10374 }
10375
10376 // Destroy the traffic monitor timer
10377 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10378 &pHddCtx->tx_rx_trafficTmr)))
10379 {
10380 hddLog(VOS_TRACE_LEVEL_ERROR,
10381 "%s: Cannot deallocate Traffic monitor timer", __func__);
10382 }
10383
Bhargav Shahd0715912015-10-01 18:17:37 +053010384 if (VOS_TIMER_STATE_RUNNING ==
10385 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
10386 vos_timer_stop(&pHddCtx->delack_timer);
10387 }
10388
10389 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
10390 &pHddCtx->delack_timer))) {
10391 hddLog(VOS_TRACE_LEVEL_ERROR,
10392 "%s: Cannot deallocate Bus bandwidth timer", __func__);
10393 }
10394
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053010395 if (VOS_TIMER_STATE_RUNNING ==
10396 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
10397 vos_timer_stop(&pHddCtx->tdls_source_timer);
10398 }
10399
10400 vos_timer_destroy(&pHddCtx->tdls_source_timer);
10401
Jeff Johnson295189b2012-06-20 16:38:30 -070010402 //Disable IMPS/BMPS as we do not want the device to enter any power
10403 //save mode during shutdown
10404 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
10405 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
10406 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
10407
10408 //Ensure that device is in full power as we will touch H/W during vos_Stop
10409 init_completion(&powerContext.completion);
10410 powerContext.magic = POWER_CONTEXT_MAGIC;
10411
10412 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
10413 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
10414
10415 if (eHAL_STATUS_SUCCESS != halStatus)
10416 {
10417 if (eHAL_STATUS_PMC_PENDING == halStatus)
10418 {
10419 /* request was sent -- wait for the response */
10420 lrc = wait_for_completion_interruptible_timeout(
10421 &powerContext.completion,
10422 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070010423 if (lrc <= 0)
10424 {
10425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010426 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 }
10428 }
10429 else
10430 {
10431 hddLog(VOS_TRACE_LEVEL_ERROR,
10432 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010433 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070010434 /* continue -- need to clean up as much as possible */
10435 }
10436 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053010437 if ((eHAL_STATUS_SUCCESS == halStatus) ||
10438 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
10439 {
10440 /* This will issue a dump command which will clean up
10441 BTQM queues and unblock MC thread */
10442 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
10443 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010444
Jeff Johnson72a40512013-12-19 10:14:15 -080010445 /* either we never sent a request, we sent a request and received a
10446 response or we sent a request and timed out. if we never sent a
10447 request or if we sent a request and got a response, we want to
10448 clear the magic out of paranoia. if we timed out there is a
10449 race condition such that the callback function could be
10450 executing at the same time we are. of primary concern is if the
10451 callback function had already verified the "magic" but had not
10452 yet set the completion variable when a timeout occurred. we
10453 serialize these activities by invalidating the magic while
10454 holding a shared spinlock which will cause us to block if the
10455 callback is currently executing */
10456 spin_lock(&hdd_context_lock);
10457 powerContext.magic = 0;
10458 spin_unlock(&hdd_context_lock);
10459
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053010460 /* If Device is shutdown, no point for SME to wait for responses
10461 from device. Pre Close SME */
10462 if(wcnss_device_is_shutdown())
10463 {
10464 sme_PreClose(pHddCtx->hHal);
10465 }
Yue Ma0d4891e2013-08-06 17:01:45 -070010466 hdd_debugfs_exit(pHddCtx);
10467
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010468#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053010469 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010470 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
10471#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053010472 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053010473 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
10474
Jeff Johnson295189b2012-06-20 16:38:30 -070010475 // Unregister the Net Device Notifier
10476 unregister_netdevice_notifier(&hdd_netdev_notifier);
10477
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 hdd_stop_all_adapters( pHddCtx );
10479
Jeff Johnson295189b2012-06-20 16:38:30 -070010480#ifdef WLAN_BTAMP_FEATURE
10481 vosStatus = WLANBAP_Stop(pVosContext);
10482 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10483 {
10484 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10485 "%s: Failed to stop BAP",__func__);
10486 }
10487#endif //WLAN_BTAMP_FEATURE
10488
10489 //Stop all the modules
10490 vosStatus = vos_stop( pVosContext );
10491 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10492 {
10493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10494 "%s: Failed to stop VOSS",__func__);
10495 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053010496 if (isSsrPanicOnFailure())
10497 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 }
10499
Jeff Johnson295189b2012-06-20 16:38:30 -070010500 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010502
10503 //Close the scheduler before calling vos_close to make sure no thread is
10504 // scheduled after the each module close is called i.e after all the data
10505 // structures are freed.
10506 vosStatus = vos_sched_close( pVosContext );
10507 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
10508 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
10509 "%s: Failed to close VOSS Scheduler",__func__);
10510 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10511 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010512#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
10513 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010514 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070010515#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080010516 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010517 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070010518
Mihir Shete7a24b5f2013-12-21 12:18:31 +053010519#ifdef CONFIG_ENABLE_LINUX_REG
10520 vosStatus = vos_nv_close();
10521 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
10522 {
10523 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
10524 "%s: Failed to close NV", __func__);
10525 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
10526 }
10527#endif
10528
Jeff Johnson295189b2012-06-20 16:38:30 -070010529 //Close VOSS
10530 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
10531 vos_close(pVosContext);
10532
Jeff Johnson295189b2012-06-20 16:38:30 -070010533 //Close Watchdog
10534 if(pHddCtx->cfg_ini->fIsLogpEnabled)
10535 vos_watchdog_close(pVosContext);
10536
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010537 //Clean up HDD Nlink Service
10538 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053010539
Manjeet Singh47ee8472016-04-11 11:57:18 +053010540 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053010541 wlan_free_fwr_mem_dump_buffer();
10542 memdump_deinit();
10543
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010544#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053010545 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053010546 {
10547 wlan_logging_sock_deactivate_svc();
10548 }
10549#endif
10550
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010551#ifdef WLAN_KD_READY_NOTIFIER
10552 nl_srv_exit(pHddCtx->ptt_pid);
10553#else
10554 nl_srv_exit();
10555#endif /* WLAN_KD_READY_NOTIFIER */
10556
Abhishek Singh00b71972016-01-07 10:51:04 +053010557#ifdef WLAN_FEATURE_RMC
10558 hdd_close_cesium_nl_sock();
10559#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053010560
Jeff Johnson295189b2012-06-20 16:38:30 -070010561 hdd_close_all_adapters( pHddCtx );
10562
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053010563 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
10564
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053010565free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 /* free the power on lock from platform driver */
10567 if (free_riva_power_on_lock("wlan"))
10568 {
10569 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
10570 __func__);
10571 }
10572
c_hpothu78c7b602014-05-17 17:35:49 +053010573 //Free up dynamically allocated members inside HDD Adapter
10574 if (pHddCtx->cfg_ini)
10575 {
10576 kfree(pHddCtx->cfg_ini);
10577 pHddCtx->cfg_ini= NULL;
10578 }
10579
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010580 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070010581 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053010582 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
10583 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070010584 {
10585 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053010586 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070010587 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010588 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070010589 if (hdd_is_ssr_required())
10590 {
10591 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070010592 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070010593 msleep(5000);
10594 }
10595 hdd_set_ssr_required (VOS_FALSE);
10596}
10597
10598
10599/**---------------------------------------------------------------------------
10600
10601 \brief hdd_update_config_from_nv() - Function to update the contents of
10602 the running configuration with parameters taken from NV storage
10603
10604 \param - pHddCtx - Pointer to the HDD global context
10605
10606 \return - VOS_STATUS_SUCCESS if successful
10607
10608 --------------------------------------------------------------------------*/
10609static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
10610{
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 v_BOOL_t itemIsValid = VOS_FALSE;
10612 VOS_STATUS status;
10613 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
10614 v_U8_t macLoop;
10615
10616 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
10617 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
10618 if(status != VOS_STATUS_SUCCESS)
10619 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010620 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010621 return VOS_STATUS_E_FAILURE;
10622 }
10623
10624 if (itemIsValid == VOS_TRUE)
10625 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010626 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070010627 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
10628 VOS_MAX_CONCURRENCY_PERSONA);
10629 if(status != VOS_STATUS_SUCCESS)
10630 {
10631 /* Get MAC from NV fail, not update CFG info
10632 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080010633 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 return VOS_STATUS_E_FAILURE;
10635 }
10636
10637 /* If first MAC is not valid, treat all others are not valid
10638 * Then all MACs will be got from ini file */
10639 if(vos_is_macaddr_zero(&macFromNV[0]))
10640 {
10641 /* MAC address in NV file is not configured yet */
10642 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
10643 return VOS_STATUS_E_INVAL;
10644 }
10645
10646 /* Get MAC address from NV, update CFG info */
10647 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
10648 {
10649 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
10650 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010651 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070010652 /* This MAC is not valid, skip it
10653 * This MAC will be got from ini file */
10654 }
10655 else
10656 {
10657 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
10658 (v_U8_t *)&macFromNV[macLoop].bytes[0],
10659 VOS_MAC_ADDR_SIZE);
10660 }
10661 }
10662 }
10663 else
10664 {
10665 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
10666 return VOS_STATUS_E_FAILURE;
10667 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010668
Jeff Johnson295189b2012-06-20 16:38:30 -070010669
10670 return VOS_STATUS_SUCCESS;
10671}
10672
10673/**---------------------------------------------------------------------------
10674
10675 \brief hdd_post_voss_start_config() - HDD post voss start config helper
10676
10677 \param - pAdapter - Pointer to the HDD
10678
10679 \return - None
10680
10681 --------------------------------------------------------------------------*/
10682VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
10683{
10684 eHalStatus halStatus;
10685 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010686 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070010687
Jeff Johnson295189b2012-06-20 16:38:30 -070010688
10689 // Send ready indication to the HDD. This will kick off the MAC
10690 // into a 'running' state and should kick off an initial scan.
10691 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
10692 if ( !HAL_STATUS_SUCCESS( halStatus ) )
10693 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010694 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070010695 "code %08d [x%08x]",__func__, halStatus, halStatus );
10696 return VOS_STATUS_E_FAILURE;
10697 }
10698
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010699 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070010700 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
10701 // And RIVA will crash
10702 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
10703 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010704 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
10705 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
10706
10707
Jeff Johnson295189b2012-06-20 16:38:30 -070010708 return VOS_STATUS_SUCCESS;
10709}
10710
Jeff Johnson295189b2012-06-20 16:38:30 -070010711/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010712void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010713{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010714
10715 vos_wake_lock_acquire(&wlan_wake_lock, reason);
10716
Jeff Johnson295189b2012-06-20 16:38:30 -070010717}
10718
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010719void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070010720{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010721
10722 vos_wake_lock_release(&wlan_wake_lock, reason);
10723
Jeff Johnson295189b2012-06-20 16:38:30 -070010724}
10725
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010726void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010727{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010728
10729 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
10730 reason);
10731
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010732}
10733
Jeff Johnson295189b2012-06-20 16:38:30 -070010734/**---------------------------------------------------------------------------
10735
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010736 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
10737 information between Host and Riva
10738
10739 This function gets reported version of FW
10740 It also finds the version of Riva headers used to compile the host
10741 It compares the above two and prints a warning if they are different
10742 It gets the SW and HW version string
10743 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
10744 indicating the features they support through a bitmap
10745
10746 \param - pHddCtx - Pointer to HDD context
10747
10748 \return - void
10749
10750 --------------------------------------------------------------------------*/
10751
10752void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
10753{
10754
10755 tSirVersionType versionCompiled;
10756 tSirVersionType versionReported;
10757 tSirVersionString versionString;
10758 tANI_U8 fwFeatCapsMsgSupported = 0;
10759 VOS_STATUS vstatus;
10760
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080010761 memset(&versionCompiled, 0, sizeof(versionCompiled));
10762 memset(&versionReported, 0, sizeof(versionReported));
10763
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010764 /* retrieve and display WCNSS version information */
10765 do {
10766
10767 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
10768 &versionCompiled);
10769 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10770 {
10771 hddLog(VOS_TRACE_LEVEL_FATAL,
10772 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010773 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010774 break;
10775 }
10776
10777 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
10778 &versionReported);
10779 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10780 {
10781 hddLog(VOS_TRACE_LEVEL_FATAL,
10782 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010783 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010784 break;
10785 }
10786
10787 if ((versionCompiled.major != versionReported.major) ||
10788 (versionCompiled.minor != versionReported.minor) ||
10789 (versionCompiled.version != versionReported.version) ||
10790 (versionCompiled.revision != versionReported.revision))
10791 {
10792 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
10793 "Host expected %u.%u.%u.%u\n",
10794 WLAN_MODULE_NAME,
10795 (int)versionReported.major,
10796 (int)versionReported.minor,
10797 (int)versionReported.version,
10798 (int)versionReported.revision,
10799 (int)versionCompiled.major,
10800 (int)versionCompiled.minor,
10801 (int)versionCompiled.version,
10802 (int)versionCompiled.revision);
10803 }
10804 else
10805 {
10806 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
10807 WLAN_MODULE_NAME,
10808 (int)versionReported.major,
10809 (int)versionReported.minor,
10810 (int)versionReported.version,
10811 (int)versionReported.revision);
10812 }
10813
10814 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
10815 versionString,
10816 sizeof(versionString));
10817 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10818 {
10819 hddLog(VOS_TRACE_LEVEL_FATAL,
10820 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010821 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010822 break;
10823 }
10824
10825 pr_info("%s: WCNSS software version %s\n",
10826 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053010827 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010828
10829 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
10830 versionString,
10831 sizeof(versionString));
10832 if (!VOS_IS_STATUS_SUCCESS(vstatus))
10833 {
10834 hddLog(VOS_TRACE_LEVEL_FATAL,
10835 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010836 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010837 break;
10838 }
10839
10840 pr_info("%s: WCNSS hardware version %s\n",
10841 WLAN_MODULE_NAME, versionString);
10842
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010843 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
10844 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010845 send the message only if it the riva is 1.1
10846 minor numbers for different riva branches:
10847 0 -> (1.0)Mainline Build
10848 1 -> (1.1)Mainline Build
10849 2->(1.04) Stability Build
10850 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010851 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010852 ((versionReported.minor>=1) && (versionReported.version>=1)))
10853 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
10854 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070010855
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010856 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080010857 {
10858#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
10859 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
10860 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
10861#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070010862 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
10863 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
10864 {
10865 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
10866 }
10867
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010868 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080010869 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010870
10871 } while (0);
10872
10873}
Neelansh Mittaledafed22014-09-04 18:54:39 +053010874void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
10875{
10876 struct sk_buff *skb;
10877 struct nlmsghdr *nlh;
10878 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010879 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053010880 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010881
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053010882 if (in_interrupt() || irqs_disabled() || in_atomic())
10883 flags = GFP_ATOMIC;
10884
10885 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053010886
10887 if(skb == NULL) {
10888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10889 "%s: alloc_skb failed", __func__);
10890 return;
10891 }
10892
10893 nlh = (struct nlmsghdr *)skb->data;
10894 nlh->nlmsg_pid = 0; /* from kernel */
10895 nlh->nlmsg_flags = 0;
10896 nlh->nlmsg_seq = 0;
10897 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
10898
10899 ani_hdr = NLMSG_DATA(nlh);
10900 ani_hdr->type = type;
10901
10902 switch(type) {
10903 case WLAN_SVC_SAP_RESTART_IND:
10904 ani_hdr->length = 0;
10905 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
10906 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
10907 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053010908 case WLAN_SVC_WLAN_TP_IND:
10909 ani_hdr->length = len;
10910 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
10911 + len));
10912 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10913 memcpy(nl_data, data, len);
10914 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10915 break;
Bhargav shah23c94942015-10-13 12:48:35 +053010916 case WLAN_MSG_RPS_ENABLE_IND:
10917 ani_hdr->length = len;
10918 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
10919 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
10920 memcpy(nl_data, data, len);
10921 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
10922 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010923 default:
10924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10925 "Attempt to send unknown nlink message %d", type);
10926 kfree_skb(skb);
10927 return;
10928 }
10929
10930 nl_srv_bcast(skb);
10931
10932 return;
10933}
10934
Bhargav Shahd0715912015-10-01 18:17:37 +053010935/**
10936 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
10937 * @pHddCtx: Valid Global HDD context pointer
10938 * @rx_packets: Number of RX packet in perticular time
10939 *
10940 * Based on the RX packet this function calculate next value of tcp delack.
10941 * This function compare rx packet value to high and low threshold limit.
10942 *
10943 * Return: void
10944 */
10945void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
10946{
10947 /* average of rx_packets and prev_rx is taken so that
10948 bus width doesnot fluctuate much */
10949 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
10950 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053010951
Bhargav Shahd0715912015-10-01 18:17:37 +053010952 pHddCtx->prev_rx = rx_packets;
10953 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
10954 next_rx_level = TP_IND_HIGH;
10955 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
10956 next_rx_level = TP_IND_LOW;
10957
10958 hdd_set_delack_value(pHddCtx, next_rx_level);
10959}
10960
10961#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
10962
10963/**
10964 * hdd_tcp_delack_compute_function() - get link status
10965 * @priv: Valid Global HDD context pointer
10966 *
10967 * This function find number of RX packet during timer life span.
10968 * It request tcp delack with number of RX packet and re-configure delack timer
10969 * for tcpDelAckComputeInterval timer interval.
10970 *
10971 * Return: void
10972 */
10973void hdd_tcp_delack_compute_function(void *priv)
10974{
10975 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
10976 hdd_adapter_t *pAdapter = NULL;
10977 v_U32_t rx_packets = 0;
10978 hdd_adapter_list_node_t *pAdapterNode = NULL;
10979 VOS_STATUS status = 0;
10980
10981 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
10982 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
10983 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
10984 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
10985 continue;
10986
10987 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
10988 pAdapter->prev_rx_packets);
10989 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
10990 }
10991
10992 hdd_request_tcp_delack(pHddCtx, rx_packets);
10993
10994 vos_timer_start(&pHddCtx->delack_timer,
10995 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
10996}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070010997
10998/**---------------------------------------------------------------------------
10999
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011000 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
11001
11002 \param - pHddCtx - Pointer to the hdd context
11003
11004 \return - true if hardware supports 5GHz
11005
11006 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053011007boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011008{
11009 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
11010 * then hardware support 5Ghz.
11011 */
11012 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
11013 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011014 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011015 return true;
11016 }
11017 else
11018 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011019 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011020 __func__);
11021 return false;
11022 }
11023}
11024
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011025/**---------------------------------------------------------------------------
11026
11027 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
11028 generate function
11029
11030 This is generate the random mac address for WLAN interface
11031
11032 \param - pHddCtx - Pointer to HDD context
11033 idx - Start interface index to get auto
11034 generated mac addr.
11035 mac_addr - Mac address
11036
11037 \return - 0 for success, < 0 for failure
11038
11039 --------------------------------------------------------------------------*/
11040
11041static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
11042 int idx, v_MACADDR_t mac_addr)
11043{
11044 int i;
11045 unsigned int serialno;
11046 serialno = wcnss_get_serial_number();
11047
11048 if (0 != serialno)
11049 {
11050 /* MAC address has 3 bytes of OUI so we have a maximum of 3
11051 bytes of the serial number that can be used to generate
11052 the other 3 bytes of the MAC address. Mask off all but
11053 the lower 3 bytes (this will also make sure we don't
11054 overflow in the next step) */
11055 serialno &= 0x00FFFFFF;
11056
11057 /* we need a unique address for each session */
11058 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
11059
11060 /* autogen other Mac addresses */
11061 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
11062 {
11063 /* start with the entire default address */
11064 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
11065 /* then replace the lower 3 bytes */
11066 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
11067 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
11068 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
11069
11070 serialno++;
11071 hddLog(VOS_TRACE_LEVEL_ERROR,
11072 "%s: Derived Mac Addr: "
11073 MAC_ADDRESS_STR, __func__,
11074 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
11075 }
11076
11077 }
11078 else
11079 {
11080 hddLog(LOGE, FL("Failed to Get Serial NO"));
11081 return -1;
11082 }
11083 return 0;
11084}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011085
Katya Nigame7b69a82015-04-28 15:24:06 +053011086int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
11087{
11088 VOS_STATUS status;
11089 v_CONTEXT_t pVosContext= NULL;
11090 hdd_adapter_t *pAdapter= NULL;
11091
11092 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11093
11094 if (NULL == pVosContext)
11095 {
11096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11097 "%s: Trying to open VOSS without a PreOpen", __func__);
11098 VOS_ASSERT(0);
11099 return VOS_STATUS_E_FAILURE;
11100 }
11101
11102 status = vos_nv_open();
11103 if (!VOS_IS_STATUS_SUCCESS(status))
11104 {
11105 /* NV module cannot be initialized */
11106 hddLog( VOS_TRACE_LEVEL_FATAL,
11107 "%s: vos_nv_open failed", __func__);
11108 return VOS_STATUS_E_FAILURE;
11109 }
11110
11111 status = vos_init_wiphy_from_nv_bin();
11112 if (!VOS_IS_STATUS_SUCCESS(status))
11113 {
11114 /* NV module cannot be initialized */
11115 hddLog( VOS_TRACE_LEVEL_FATAL,
11116 "%s: vos_init_wiphy failed", __func__);
11117 goto err_vos_nv_close;
11118 }
11119
11120 status = vos_open( &pVosContext, pHddCtx->parent_dev);
11121 if ( !VOS_IS_STATUS_SUCCESS( status ))
11122 {
11123 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
11124 goto err_vos_nv_close;
11125 }
11126
11127 status = vos_mon_start( pVosContext );
11128 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11129 {
11130 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
11131 goto err_vosclose;
11132 }
11133
11134 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
11135 WDA_featureCapsExchange(pVosContext);
11136 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11137
11138 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
11139 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11140 if( pAdapter == NULL )
11141 {
11142 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
11143 goto err_close_adapter;
11144 }
11145
11146 //Initialize the nlink service
11147 if(nl_srv_init() != 0)
11148 {
11149 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11150 goto err_close_adapter;
11151 }
11152 return VOS_STATUS_SUCCESS;
11153
11154err_close_adapter:
11155 hdd_close_all_adapters( pHddCtx );
11156 vos_mon_stop( pVosContext );
11157err_vosclose:
11158 status = vos_sched_close( pVosContext );
11159 if (!VOS_IS_STATUS_SUCCESS(status)) {
11160 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
11161 "%s: Failed to close VOSS Scheduler", __func__);
11162 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
11163 }
11164 vos_close(pVosContext );
11165
11166err_vos_nv_close:
11167 vos_nv_close();
11168
11169return status;
11170}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011171/**---------------------------------------------------------------------------
11172
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011173 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
11174 completed to flush out the scan results
11175
11176 11d scan is done during driver load and is a passive scan on all
11177 channels supported by the device, 11d scans may find some APs on
11178 frequencies which are forbidden to be used in the regulatory domain
11179 the device is operating in. If these APs are notified to the supplicant
11180 it may try to connect to these APs, thus flush out all the scan results
11181 which are present in SME after 11d scan is done.
11182
11183 \return - eHalStatus
11184
11185 --------------------------------------------------------------------------*/
11186static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
11187 tANI_U32 scanId, eCsrScanStatus status)
11188{
11189 ENTER();
11190
11191 sme_ScanFlushResult(halHandle, 0);
11192
11193 EXIT();
11194
11195 return eHAL_STATUS_SUCCESS;
11196}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011197/**---------------------------------------------------------------------------
11198
11199 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
11200 logging is completed successfully.
11201
11202 \return - None
11203
11204 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053011205void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011206{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011207 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011208
11209 if (NULL == pHddCtx)
11210 {
11211 hddLog(VOS_TRACE_LEVEL_ERROR,
11212 "%s: HDD context is NULL",__func__);
11213 return;
11214 }
11215
c_manjeecfd1efb2015-09-25 19:32:34 +053011216 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053011217 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011218 {
11219 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
11220 pHddCtx->mgmt_frame_logging = TRUE;
11221 }
11222 else
11223 {
11224 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
11225 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053011226 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011227 }
11228
c_manjeecfd1efb2015-09-25 19:32:34 +053011229 /*Check feature supported by FW*/
11230 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
11231 {
11232 //Store fwr mem dump size given by firmware.
11233 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
11234 }
11235 else
11236 {
11237 wlan_store_fwr_mem_dump_size(0);
11238 }
11239
11240
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011241}
11242/**---------------------------------------------------------------------------
11243
11244 \brief hdd_init_frame_logging - function to initialize frame logging.
11245 Currently only Mgmt Frames are logged in both TX
11246 and Rx direction and are sent to userspace
11247 application using logger thread when queried.
11248
11249 \return - None
11250
11251 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011252void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011253{
11254 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011255 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011256
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011257 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
11258 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011259 {
11260 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
11261 return;
11262 }
11263
c_manjeecfd1efb2015-09-25 19:32:34 +053011264 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011265 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
11266 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053011267 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
11268 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011269
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011270 if (pHddCtx->cfg_ini->enableFWLogging ||
11271 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011272 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011273 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011274 }
11275
Sushant Kaushik46804902015-07-08 14:46:03 +053011276 if (pHddCtx->cfg_ini->enableMgmtLogging)
11277 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011278 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053011279 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011280 if (pHddCtx->cfg_ini->enableBMUHWtracing)
11281 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011282 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011283 }
c_manjeecfd1efb2015-09-25 19:32:34 +053011284 if(pHddCtx->cfg_ini->enableFwrMemDump &&
11285 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
11286 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011287 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053011288 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011289 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053011290 {
11291 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
11292 return;
11293 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011294 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
11295 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
11296 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
11297 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011298 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011299
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011300 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011301
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011302 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011303 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011304 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053011305 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011306 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
11307 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011308
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011309 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011310
11311 if (eHAL_STATUS_SUCCESS != halStatus)
11312 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053011313 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
11314 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053011315 }
11316
11317 return;
11318}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011319
Bhargav shah23c94942015-10-13 12:48:35 +053011320static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
11321{
11322 hdd_adapter_t *adapter;
11323 hdd_adapter_list_node_t *adapter_node, *next;
11324 VOS_STATUS status = VOS_STATUS_SUCCESS;
11325 struct wlan_rps_data rps_data;
11326 int count;
11327
11328 if(!hdd_ctxt->cfg_ini->rps_mask)
11329 {
11330 return;
11331 }
11332
11333 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
11334 {
11335 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
11336 }
11337
11338 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
11339
11340 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
11341 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
11342 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
11343
11344 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
11345
11346 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
11347 {
11348 adapter = adapter_node->pAdapter;
11349 if (NULL != adapter) {
11350 strlcpy(rps_data.ifname, adapter->dev->name,
11351 sizeof(rps_data.ifname));
11352 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
11353 (void *)&rps_data,sizeof(rps_data));
11354 }
11355 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
11356 adapter_node = next;
11357 }
11358}
11359
Masti, Narayanraddi26378462016-01-05 18:20:28 +053011360void wlan_hdd_schedule_defer_scan(struct work_struct *work)
11361{
11362 scan_context_t *scan_ctx =
11363 container_of(work, scan_context_t, scan_work.work);
11364
11365 if (NULL == scan_ctx)
11366 {
11367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11368 FL("scan_ctx is NULL"));
11369 return;
11370 }
11371
11372 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
11373 return;
11374
11375 scan_ctx->attempt++;
11376
11377 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
11378#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11379 scan_ctx->dev,
11380#endif
11381 scan_ctx->scan_request);
11382}
11383
11384int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
11385 struct wiphy *wiphy,
11386#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11387 struct net_device *dev,
11388#endif
11389 struct cfg80211_scan_request *request)
11390{
11391 scan_context_t *scan_ctx;
11392
11393 ENTER();
11394 if (0 != (wlan_hdd_validate_context(pHddCtx)))
11395 {
11396 return -1;
11397 }
11398
11399 scan_ctx = &pHddCtx->scan_ctxt;
11400
11401 scan_ctx->wiphy = wiphy;
11402#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11403 scan_ctx->dev = dev;
11404#endif
11405
11406 scan_ctx->scan_request = request;
11407
11408 EXIT();
11409 return 0;
11410}
11411
11412void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
11413 struct wiphy *wiphy,
11414#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11415 struct net_device *dev,
11416#endif
11417 struct cfg80211_scan_request *request,
11418 unsigned long delay)
11419{
11420 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
11421 {
11422#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11423 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
11424#else
11425 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
11426#endif
11427 pHddCtx->scan_ctxt.attempt = 0;
11428 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
11429 }
11430 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
11431}
11432
11433void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
11434{
11435 scan_ctx->magic = 0;
11436 scan_ctx->attempt = 0;
11437 scan_ctx->reject = 0;
11438 scan_ctx->scan_request = NULL;
11439
11440 return;
11441}
11442
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053011443/**---------------------------------------------------------------------------
11444
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 \brief hdd_wlan_startup() - HDD init function
11446
11447 This is the driver startup code executed once a WLAN device has been detected
11448
11449 \param - dev - Pointer to the underlying device
11450
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011451 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070011452
11453 --------------------------------------------------------------------------*/
11454
11455int hdd_wlan_startup(struct device *dev )
11456{
11457 VOS_STATUS status;
11458 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011459 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011460 hdd_context_t *pHddCtx = NULL;
11461 v_CONTEXT_t pVosContext= NULL;
11462#ifdef WLAN_BTAMP_FEATURE
11463 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
11464 WLANBAP_ConfigType btAmpConfig;
11465 hdd_config_t *pConfig;
11466#endif
11467 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011469 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011470
11471 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011472 /*
11473 * cfg80211: wiphy allocation
11474 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011475 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070011476
11477 if(wiphy == NULL)
11478 {
11479 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080011480 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011481 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011482 pHddCtx = wiphy_priv(wiphy);
11483
Jeff Johnson295189b2012-06-20 16:38:30 -070011484 //Initialize the adapter context to zeros.
11485 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
11486
Jeff Johnson295189b2012-06-20 16:38:30 -070011487 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011488 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053011489 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011490
11491 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
11492
Siddharth Bhalcd92b782015-06-29 12:25:40 +053011493 /* register for riva power on lock to platform driver
11494 * Locking power early to ensure FW doesn't reset by kernel while
11495 * host driver is busy initializing itself */
11496 if (req_riva_power_on_lock("wlan"))
11497 {
11498 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
11499 __func__);
11500 goto err_free_hdd_context;
11501 }
11502
Jeff Johnson295189b2012-06-20 16:38:30 -070011503 /*Get vos context here bcoz vos_open requires it*/
11504 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11505
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080011506 if(pVosContext == NULL)
11507 {
11508 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
11509 goto err_free_hdd_context;
11510 }
11511
Jeff Johnson295189b2012-06-20 16:38:30 -070011512 //Save the Global VOSS context in adapter context for future.
11513 pHddCtx->pvosContext = pVosContext;
11514
11515 //Save the adapter context in global context for future.
11516 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
11517
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 pHddCtx->parent_dev = dev;
11519
11520 init_completion(&pHddCtx->full_pwr_comp_var);
11521 init_completion(&pHddCtx->standby_comp_var);
11522 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011523 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011524 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053011525 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053011526 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053011527 init_completion(&pHddCtx->mc_sus_event_var);
11528 init_completion(&pHddCtx->tx_sus_event_var);
11529 init_completion(&pHddCtx->rx_sus_event_var);
11530
Amar Singhala49cbc52013-10-08 18:37:44 -070011531
mukul sharma4bd8d2e2015-08-13 20:33:25 +053011532 hdd_init_ll_stats_ctx(pHddCtx);
11533
Amar Singhala49cbc52013-10-08 18:37:44 -070011534#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070011535 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070011536#else
11537 init_completion(&pHddCtx->driver_crda_req);
11538#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011539
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053011540#ifdef WLAN_FEATURE_EXTSCAN
11541 init_completion(&pHddCtx->ext_scan_context.response_event);
11542#endif /* WLAN_FEATURE_EXTSCAN */
11543
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053011544 spin_lock_init(&pHddCtx->schedScan_lock);
11545
Jeff Johnson295189b2012-06-20 16:38:30 -070011546 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
11547
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053011548 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
11549 hdd_processSpoofMacAddrRequest);
11550
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011551#ifdef FEATURE_WLAN_TDLS
11552 /* tdls_lock is initialized before an hdd_open_adapter ( which is
11553 * invoked by other instances also) to protect the concurrent
11554 * access for the Adapters by TDLS module.
11555 */
11556 mutex_init(&pHddCtx->tdls_lock);
11557#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053011558 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053011559 mutex_init(&pHddCtx->wmmLock);
11560
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053011561 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053011562 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011563
Agarwal Ashish1f422872014-07-22 00:11:55 +053011564 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 // Load all config first as TL config is needed during vos_open
11566 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
11567 if(pHddCtx->cfg_ini == NULL)
11568 {
11569 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
11570 goto err_free_hdd_context;
11571 }
11572
11573 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
11574
11575 // Read and parse the qcom_cfg.ini file
11576 status = hdd_parse_config_ini( pHddCtx );
11577 if ( VOS_STATUS_SUCCESS != status )
11578 {
11579 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
11580 __func__, WLAN_INI_FILE);
11581 goto err_config;
11582 }
Arif Hussaind5218912013-12-05 01:10:55 -080011583#ifdef MEMORY_DEBUG
11584 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
11585 vos_mem_init();
11586
11587 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
11588 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
11589#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011590
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053011591 /* INI has been read, initialise the configuredMcastBcastFilter with
11592 * INI value as this will serve as the default value
11593 */
11594 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
11595 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
11596 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053011597
11598 if (false == hdd_is_5g_supported(pHddCtx))
11599 {
11600 //5Ghz is not supported.
11601 if (1 != pHddCtx->cfg_ini->nBandCapability)
11602 {
11603 hddLog(VOS_TRACE_LEVEL_INFO,
11604 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
11605 pHddCtx->cfg_ini->nBandCapability = 1;
11606 }
11607 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053011608
11609 /* If SNR Monitoring is enabled, FW has to parse all beacons
11610 * for calcaluting and storing the average SNR, so set Nth beacon
11611 * filter to 1 to enable FW to parse all the beaocons
11612 */
11613 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
11614 {
11615 /* The log level is deliberately set to WARN as overriding
11616 * nthBeaconFilter to 1 will increase power cosumption and this
11617 * might just prove helpful to detect the power issue.
11618 */
11619 hddLog(VOS_TRACE_LEVEL_WARN,
11620 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
11621 pHddCtx->cfg_ini->nthBeaconFilter = 1;
11622 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011623 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011624 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070011625 */
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080011626 if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070011627 {
Manjunathappa Prakasheec4ddf2014-01-13 18:23:51 -080011628 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
11629 {
11630 hddLog(VOS_TRACE_LEVEL_FATAL,
11631 "%s: wlan_hdd_cfg80211_init return failure", __func__);
11632 goto err_config;
11633 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011635
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011636 // Update VOS trace levels based upon the cfg.ini
11637 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
11638 pHddCtx->cfg_ini->vosTraceEnableBAP);
11639 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
11640 pHddCtx->cfg_ini->vosTraceEnableTL);
11641 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
11642 pHddCtx->cfg_ini->vosTraceEnableWDI);
11643 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
11644 pHddCtx->cfg_ini->vosTraceEnableHDD);
11645 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
11646 pHddCtx->cfg_ini->vosTraceEnableSME);
11647 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
11648 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053011649 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
11650 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011651 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
11652 pHddCtx->cfg_ini->vosTraceEnableWDA);
11653 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
11654 pHddCtx->cfg_ini->vosTraceEnableSYS);
11655 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
11656 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011657 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
11658 pHddCtx->cfg_ini->vosTraceEnableSAP);
11659 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
11660 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080011661
Jeff Johnson295189b2012-06-20 16:38:30 -070011662 // Update WDI trace levels based upon the cfg.ini
11663 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
11664 pHddCtx->cfg_ini->wdiTraceEnableDAL);
11665 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
11666 pHddCtx->cfg_ini->wdiTraceEnableCTL);
11667 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
11668 pHddCtx->cfg_ini->wdiTraceEnableDAT);
11669 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
11670 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011671
Jeff Johnson88ba7742013-02-27 14:36:02 -080011672 if (VOS_FTM_MODE == hdd_get_conparam())
11673 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011674 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
11675 {
11676 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
11677 goto err_free_hdd_context;
11678 }
11679 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053011680 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053011681 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080011683 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011684
Katya Nigame7b69a82015-04-28 15:24:06 +053011685 if( VOS_MONITOR_MODE == hdd_get_conparam())
11686 {
11687 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
11688 {
11689 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
11690 goto err_free_hdd_context;
11691 }
11692 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
11693 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
11694 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11695 return VOS_STATUS_SUCCESS;
11696 }
11697
Jeff Johnson88ba7742013-02-27 14:36:02 -080011698 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 if(pHddCtx->cfg_ini->fIsLogpEnabled)
11700 {
11701 status = vos_watchdog_open(pVosContext,
11702 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
11703
11704 if(!VOS_IS_STATUS_SUCCESS( status ))
11705 {
11706 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011707 goto err_wdclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 }
11709 }
11710
11711 pHddCtx->isLogpInProgress = FALSE;
11712 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
11713
Amar Singhala49cbc52013-10-08 18:37:44 -070011714#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070011715 /* initialize the NV module. This is required so that
11716 we can initialize the channel information in wiphy
11717 from the NV.bin data. The channel information in
11718 wiphy needs to be initialized before wiphy registration */
11719
11720 status = vos_nv_open();
11721 if (!VOS_IS_STATUS_SUCCESS(status))
11722 {
11723 /* NV module cannot be initialized */
11724 hddLog( VOS_TRACE_LEVEL_FATAL,
11725 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053011726 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070011727 }
11728
11729 status = vos_init_wiphy_from_nv_bin();
11730 if (!VOS_IS_STATUS_SUCCESS(status))
11731 {
11732 /* NV module cannot be initialized */
11733 hddLog( VOS_TRACE_LEVEL_FATAL,
11734 "%s: vos_init_wiphy failed", __func__);
11735 goto err_vos_nv_close;
11736 }
11737
Amar Singhala49cbc52013-10-08 18:37:44 -070011738#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011739 //Initialize the nlink service
11740 if(nl_srv_init() != 0)
11741 {
11742 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
11743 goto err_vos_nv_close;
11744 }
11745
11746#ifdef WLAN_KD_READY_NOTIFIER
11747 pHddCtx->kd_nl_init = 1;
11748#endif /* WLAN_KD_READY_NOTIFIER */
11749
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053011750 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053011751 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 if ( !VOS_IS_STATUS_SUCCESS( status ))
11753 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011754 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053011755 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070011756 }
11757
Jeff Johnson295189b2012-06-20 16:38:30 -070011758 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
11759
11760 if ( NULL == pHddCtx->hHal )
11761 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011762 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011763 goto err_vosclose;
11764 }
11765
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011766 status = vos_preStart( pHddCtx->pvosContext );
11767 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11768 {
11769 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011770 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011771 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011772
Arif Hussaineaf68602013-12-30 23:10:44 -080011773 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
11774 {
11775 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
11776 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
11777 __func__, enable_dfs_chan_scan);
11778 }
11779 if (0 == enable_11d || 1 == enable_11d)
11780 {
11781 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
11782 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
11783 __func__, enable_11d);
11784 }
11785
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011786 /* Note that the vos_preStart() sequence triggers the cfg download.
11787 The cfg download must occur before we update the SME config
11788 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 status = hdd_set_sme_config( pHddCtx );
11790
11791 if ( VOS_STATUS_SUCCESS != status )
11792 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011793 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011794 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011795 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011796
Jeff Johnson295189b2012-06-20 16:38:30 -070011797 /* In the integrated architecture we update the configuration from
11798 the INI file and from NV before vOSS has been started so that
11799 the final contents are available to send down to the cCPU */
11800
11801 // Apply the cfg.ini to cfg.dat
11802 if (FALSE == hdd_update_config_dat(pHddCtx))
11803 {
11804 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011805 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011806 }
11807
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011808 // Get mac addr from platform driver
11809 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
11810
11811 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011812 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011813 /* Store the mac addr for first interface */
11814 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
11815
11816 hddLog(VOS_TRACE_LEVEL_ERROR,
11817 "%s: WLAN Mac Addr: "
11818 MAC_ADDRESS_STR, __func__,
11819 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11820
11821 /* Here, passing Arg2 as 1 because we do not want to change the
11822 last 3 bytes (means non OUI bytes) of first interface mac
11823 addr.
11824 */
11825 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
11826 {
11827 hddLog(VOS_TRACE_LEVEL_ERROR,
11828 "%s: Failed to generate wlan interface mac addr "
11829 "using MAC from ini file ", __func__);
11830 }
11831 }
11832 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
11833 {
11834 // Apply the NV to cfg.dat
11835 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070011836#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
11837 /* There was not a valid set of MAC Addresses in NV. See if the
11838 default addresses were modified by the cfg.ini settings. If so,
11839 we'll use them, but if not, we'll autogenerate a set of MAC
11840 addresses based upon the device serial number */
11841
11842 static const v_MACADDR_t default_address =
11843 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070011844
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011845 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
11846 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011847 {
11848 /* cfg.ini has the default address, invoke autogen logic */
11849
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011850 /* Here, passing Arg2 as 0 because we want to change the
11851 last 3 bytes (means non OUI bytes) of all the interfaces
11852 mac addr.
11853 */
11854 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
11855 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011857 hddLog(VOS_TRACE_LEVEL_ERROR,
11858 "%s: Failed to generate wlan interface mac addr "
11859 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
11860 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070011861 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 }
11863 else
11864#endif //WLAN_AUTOGEN_MACADDR_FEATURE
11865 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080011866 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011867 "%s: Invalid MAC address in NV, using MAC from ini file "
11868 MAC_ADDRESS_STR, __func__,
11869 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
11870 }
11871 }
11872 {
11873 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011874
11875 /* Set the MAC Address Currently this is used by HAL to
11876 * add self sta. Remove this once self sta is added as
11877 * part of session open.
11878 */
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
11880 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
11881 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053011882
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 if (!HAL_STATUS_SUCCESS( halStatus ))
11884 {
11885 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
11886 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011887 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011888 }
11889 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011890
11891 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
11892 Note: Firmware image will be read and downloaded inside vos_start API */
11893 status = vos_start( pHddCtx->pvosContext );
11894 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11895 {
11896 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053011897 if (isSsrPanicOnFailure())
11898 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011899 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070011900 }
11901
Leo Chang6cec3e22014-01-21 15:33:49 -080011902#ifdef FEATURE_WLAN_CH_AVOID
11903 /* Plug in avoid channel notification callback
11904 * This should happen before ADD_SELF_STA
11905 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053011906
11907 /* check the Channel Avoidance is enabled */
11908 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
11909 {
11910 sme_AddChAvoidCallback(pHddCtx->hHal,
11911 hdd_hostapd_ch_avoid_cb);
11912 }
Leo Chang6cec3e22014-01-21 15:33:49 -080011913#endif /* FEATURE_WLAN_CH_AVOID */
11914
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070011915 /* Exchange capability info between Host and FW and also get versioning info from FW */
11916 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011917
Agarwal Ashishad9281b2014-06-10 14:57:30 +053011918#ifdef CONFIG_ENABLE_LINUX_REG
11919 status = wlan_hdd_init_channels(pHddCtx);
11920 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11921 {
11922 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
11923 __func__);
11924 goto err_vosstop;
11925 }
11926#endif
11927
Jeff Johnson295189b2012-06-20 16:38:30 -070011928 status = hdd_post_voss_start_config( pHddCtx );
11929 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11930 {
11931 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
11932 __func__);
11933 goto err_vosstop;
11934 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011935
11936#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053011937 wlan_hdd_cfg80211_update_reg_info( wiphy );
11938
11939 /* registration of wiphy dev with cfg80211 */
11940 if (0 > wlan_hdd_cfg80211_register(wiphy))
11941 {
11942 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11943 goto err_vosstop;
11944 }
Amar Singhala49cbc52013-10-08 18:37:44 -070011945#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011946
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011947#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011948 /* registration of wiphy dev with cfg80211 */
11949 if (0 > wlan_hdd_cfg80211_register(wiphy))
11950 {
11951 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
11952 goto err_vosstop;
11953 }
11954
Agarwal Ashish6db9d532014-09-30 18:19:10 +053011955 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053011956 if ( !VOS_IS_STATUS_SUCCESS( status ) )
11957 {
11958 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
11959 __func__);
11960 goto err_unregister_wiphy;
11961 }
11962#endif
11963
c_hpothu4a298be2014-12-22 21:12:51 +053011964 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
11965
Jeff Johnson295189b2012-06-20 16:38:30 -070011966 if (VOS_STA_SAP_MODE == hdd_get_conparam())
11967 {
11968 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
11969 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11970 }
11971 else
11972 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
11974 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
11975 if (pAdapter != NULL)
11976 {
Katya Nigama7d81d72014-11-12 12:44:34 +053011977 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011979 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
11980 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
11981 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070011982
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011983 /* Generate the P2P Device Address. This consists of the device's
11984 * primary MAC address with the locally administered bit set.
11985 */
11986 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070011987 }
11988 else
11989 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053011990 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
11991 if (p2p_dev_addr != NULL)
11992 {
11993 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
11994 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
11995 }
11996 else
11997 {
11998 hddLog(VOS_TRACE_LEVEL_FATAL,
11999 "%s: Failed to allocate mac_address for p2p_device",
12000 __func__);
12001 goto err_close_adapter;
12002 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012003 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012004
12005 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
12006 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
12007 if ( NULL == pP2pAdapter )
12008 {
12009 hddLog(VOS_TRACE_LEVEL_FATAL,
12010 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012011 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012012 goto err_close_adapter;
12013 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012014 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012015 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012016
12017 if( pAdapter == NULL )
12018 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012019 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
12020 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012021 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012022
Arif Hussain66559122013-11-21 10:11:40 -080012023 if (country_code)
12024 {
12025 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080012026 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080012027 hdd_checkandupdate_dfssetting(pAdapter, country_code);
12028#ifndef CONFIG_ENABLE_LINUX_REG
12029 hdd_checkandupdate_phymode(pAdapter, country_code);
12030#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080012031 ret = sme_ChangeCountryCode(pHddCtx->hHal,
12032 (void *)(tSmeChangeCountryCallback)
12033 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080012034 country_code,
12035 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012036 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080012037 if (eHAL_STATUS_SUCCESS == ret)
12038 {
Arif Hussaincb607082013-12-20 11:57:42 -080012039 ret = wait_for_completion_interruptible_timeout(
12040 &pAdapter->change_country_code,
12041 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
12042
12043 if (0 >= ret)
12044 {
12045 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12046 "%s: SME while setting country code timed out", __func__);
12047 }
Arif Hussain66559122013-11-21 10:11:40 -080012048 }
12049 else
12050 {
Arif Hussaincb607082013-12-20 11:57:42 -080012051 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12052 "%s: SME Change Country code from module param fail ret=%d",
12053 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080012054 }
12055 }
12056
Jeff Johnson295189b2012-06-20 16:38:30 -070012057#ifdef WLAN_BTAMP_FEATURE
12058 vStatus = WLANBAP_Open(pVosContext);
12059 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12060 {
12061 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12062 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070012063 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012064 }
12065
12066 vStatus = BSL_Init(pVosContext);
12067 if(!VOS_IS_STATUS_SUCCESS(vStatus))
12068 {
12069 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12070 "%s: Failed to Init BSL",__func__);
12071 goto err_bap_close;
12072 }
12073 vStatus = WLANBAP_Start(pVosContext);
12074 if (!VOS_IS_STATUS_SUCCESS(vStatus))
12075 {
12076 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12077 "%s: Failed to start TL",__func__);
12078 goto err_bap_close;
12079 }
12080
12081 pConfig = pHddCtx->cfg_ini;
12082 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
12083 status = WLANBAP_SetConfig(&btAmpConfig);
12084
12085#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070012086
Mihir Shete9c238772014-10-15 14:35:16 +053012087 /*
12088 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
12089 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
12090 * which is greater than 0xf. So the below check is safe to make
12091 * sure that there is no entry for UapsdMask in the ini
12092 */
12093 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
12094 {
12095 if(IS_DYNAMIC_WMM_PS_ENABLED)
12096 {
12097 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
12098 __func__);
12099 pHddCtx->cfg_ini->UapsdMask =
12100 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
12101 }
12102 else
12103 {
12104 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
12105 __func__);
12106 pHddCtx->cfg_ini->UapsdMask =
12107 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
12108 }
12109 }
12110
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070012111#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
12112 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
12113 {
12114 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
12115 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
12116 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
12117 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
12118 }
12119#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012120
Agarwal Ashish4b87f922014-06-18 03:03:21 +053012121 wlan_hdd_tdls_init(pHddCtx);
12122
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012123 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
12124
12125 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
12126 wlan_hdd_schedule_defer_scan);
12127
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053012128 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
12129
Jeff Johnson295189b2012-06-20 16:38:30 -070012130 /* Register with platform driver as client for Suspend/Resume */
12131 status = hddRegisterPmOps(pHddCtx);
12132 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12133 {
12134 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
12135#ifdef WLAN_BTAMP_FEATURE
12136 goto err_bap_stop;
12137#else
Jeff Johnsone7245742012-09-05 17:12:55 -070012138 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070012139#endif //WLAN_BTAMP_FEATURE
12140 }
12141
Yue Ma0d4891e2013-08-06 17:01:45 -070012142 /* Open debugfs interface */
12143 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
12144 {
12145 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12146 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070012147 }
12148
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 /* Register TM level change handler function to the platform */
12150 status = hddDevTmRegisterNotifyCallback(pHddCtx);
12151 if ( !VOS_IS_STATUS_SUCCESS( status ) )
12152 {
12153 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
12154 goto err_unregister_pmops;
12155 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012156
Jeff Johnson295189b2012-06-20 16:38:30 -070012157 // register net device notifier for device change notification
12158 ret = register_netdevice_notifier(&hdd_netdev_notifier);
12159
12160 if(ret < 0)
12161 {
12162 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012163 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070012164 }
12165
Jeff Johnson295189b2012-06-20 16:38:30 -070012166 //Initialize the BTC service
12167 if(btc_activate_service(pHddCtx) != 0)
12168 {
12169 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012170 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012171 }
12172
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012173#ifdef FEATURE_OEM_DATA_SUPPORT
12174 //Initialize the OEM service
12175 if (oem_activate_service(pHddCtx) != 0)
12176 {
12177 hddLog(VOS_TRACE_LEVEL_FATAL,
12178 "%s: oem_activate_service failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012179 goto err_reg_netdev;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053012180 }
12181#endif
12182
Jeff Johnson295189b2012-06-20 16:38:30 -070012183#ifdef PTT_SOCK_SVC_ENABLE
12184 //Initialize the PTT service
12185 if(ptt_sock_activate_svc(pHddCtx) != 0)
12186 {
12187 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012188 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 }
12190#endif
12191
Abhishek Singh00b71972016-01-07 10:51:04 +053012192#ifdef WLAN_FEATURE_RMC
12193 if (hdd_open_cesium_nl_sock() < 0)
12194 {
12195 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
12196 goto err_reg_netdev;
12197 }
12198#endif
12199
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012200#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12201 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
12202 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053012203 if(wlan_logging_sock_activate_svc(
12204 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053012205 pHddCtx->cfg_ini->wlanLoggingNumBuf,
12206 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
12207 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053012208 {
12209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
12210 " failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012211 goto err_reg_netdev;
Deepthi Gowri78083a32014-11-04 12:55:51 +053012212 }
12213 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
12214 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053012215 if (!pHddCtx->cfg_ini->gEnableDebugLog)
12216 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053012217 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
12218 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012219 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012220
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012221 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
12222 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053012223 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053012224 pHddCtx->cfg_ini->enableContFWLogging ||
12225 pHddCtx->cfg_ini->enableFwrMemDump )
12226 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012227 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012228 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012229 }
12230 else
12231 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053012232 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012233 }
12234
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012235#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053012236
12237
Sushant Kaushik215778f2015-05-21 14:05:36 +053012238 if (vos_is_multicast_logging())
12239 wlan_logging_set_log_level();
12240
Jeff Johnson295189b2012-06-20 16:38:30 -070012241 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070012244 /* Action frame registered in one adapter which will
12245 * applicable to all interfaces
12246 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053012247 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012248 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012249
12250 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053012251 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012252
Jeff Johnsone7245742012-09-05 17:12:55 -070012253#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12254 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012255 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070012256 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012257
Jeff Johnsone7245742012-09-05 17:12:55 -070012258#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012259 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012260 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012261 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012262
Jeff Johnsone7245742012-09-05 17:12:55 -070012263
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012264 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
12265 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012266
Katya Nigam5c306ea2014-06-19 15:39:54 +053012267 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012269 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053012270
12271#ifdef FEATURE_WLAN_SCAN_PNO
12272 /*SME must send channel update configuration to RIVA*/
12273 sme_UpdateChannelConfig(pHddCtx->hHal);
12274#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053012275 /* Send the update default channel list to the FW*/
12276 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053012277
12278 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053012279 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
12280 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053012281 sme_SetDefDot11Mode(pHddCtx->hHal);
12282
Abhishek Singha306a442013-11-07 18:39:01 +053012283#ifndef CONFIG_ENABLE_LINUX_REG
12284 /*updating wiphy so that regulatory user hints can be processed*/
12285 if (wiphy)
12286 {
12287 regulatory_hint(wiphy, "00");
12288 }
12289#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012290 // Initialize the restart logic
12291 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053012292
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012293 //Register the traffic monitor timer now
12294 if ( pHddCtx->cfg_ini->dynSplitscan)
12295 {
12296 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
12297 VOS_TIMER_TYPE_SW,
12298 hdd_tx_rx_pkt_cnt_stat_timer_handler,
12299 (void *)pHddCtx);
12300 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053012301 wlan_hdd_cfg80211_nan_init(pHddCtx);
12302
Bhargav Shahd0715912015-10-01 18:17:37 +053012303 mutex_init(&pHddCtx->cur_rx_level_lock);
12304 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
12305 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012306 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
12307 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053012308
Dino Mycle6fb96c12014-06-10 11:52:40 +053012309#ifdef WLAN_FEATURE_EXTSCAN
12310 sme_EXTScanRegisterCallback(pHddCtx->hHal,
12311 wlan_hdd_cfg80211_extscan_callback,
12312 pHddCtx);
12313#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012314
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053012315#ifdef FEATURE_OEM_DATA_SUPPORT
12316 sme_OemDataRegisterCallback(pHddCtx->hHal,
12317 wlan_hdd_cfg80211_oemdata_callback,
12318 pHddCtx);
12319#endif /* FEATURE_OEM_DATA_SUPPORT */
12320
Gupta, Kapil7c34b322015-09-30 13:12:35 +053012321 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012322#ifdef WLAN_NS_OFFLOAD
12323 // Register IPv6 notifier to notify if any change in IP
12324 // So that we can reconfigure the offload parameters
12325 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
12326 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12327 if (ret)
12328 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012330 }
12331 else
12332 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012333 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012334 }
12335#endif
12336
12337 // Register IPv4 notifier to notify if any change in IP
12338 // So that we can reconfigure the offload parameters
12339 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
12340 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12341 if (ret)
12342 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012344 }
12345 else
12346 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012347 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012348 }
c_manjeecfd1efb2015-09-25 19:32:34 +053012349 /*Fw mem dump procfs initialization*/
12350 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053012351 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012352
Jeff Johnson295189b2012-06-20 16:38:30 -070012353 goto success;
12354
Jeff Johnson295189b2012-06-20 16:38:30 -070012355err_reg_netdev:
12356 unregister_netdevice_notifier(&hdd_netdev_notifier);
12357
Jeff Johnson295189b2012-06-20 16:38:30 -070012358err_unregister_pmops:
12359 hddDevTmUnregisterNotifyCallback(pHddCtx);
12360 hddDeregisterPmOps(pHddCtx);
12361
Yue Ma0d4891e2013-08-06 17:01:45 -070012362 hdd_debugfs_exit(pHddCtx);
12363
Jeff Johnson295189b2012-06-20 16:38:30 -070012364#ifdef WLAN_BTAMP_FEATURE
12365err_bap_stop:
12366 WLANBAP_Stop(pVosContext);
12367#endif
12368
12369#ifdef WLAN_BTAMP_FEATURE
12370err_bap_close:
12371 WLANBAP_Close(pVosContext);
12372#endif
12373
Jeff Johnson295189b2012-06-20 16:38:30 -070012374err_close_adapter:
12375 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012376#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053012377err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053012378#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053012379 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012380 hdd_wlan_free_wiphy_channels(wiphy);
12381
Jeff Johnson295189b2012-06-20 16:38:30 -070012382err_vosstop:
12383 vos_stop(pVosContext);
12384
Amar Singhala49cbc52013-10-08 18:37:44 -070012385err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070012386 status = vos_sched_close( pVosContext );
12387 if (!VOS_IS_STATUS_SUCCESS(status)) {
12388 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12389 "%s: Failed to close VOSS Scheduler", __func__);
12390 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
12391 }
Amar Singhala49cbc52013-10-08 18:37:44 -070012392 vos_close(pVosContext );
12393
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053012394err_nl_srv:
12395#ifdef WLAN_KD_READY_NOTIFIER
12396 nl_srv_exit(pHddCtx->ptt_pid);
12397#else
12398 nl_srv_exit();
12399#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070012400err_vos_nv_close:
12401
c_hpothue6a36282014-03-19 12:27:38 +053012402#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070012403 vos_nv_close();
12404
c_hpothu70f8d812014-03-22 22:59:23 +053012405#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012406
12407err_wdclose:
12408 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12409 vos_watchdog_close(pVosContext);
12410
Jeff Johnson295189b2012-06-20 16:38:30 -070012411err_config:
12412 kfree(pHddCtx->cfg_ini);
12413 pHddCtx->cfg_ini= NULL;
12414
12415err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012416 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053012417 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 wiphy_free(wiphy) ;
12419 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012420 VOS_BUG(1);
12421
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080012422 if (hdd_is_ssr_required())
12423 {
12424 /* WDI timeout had happened during load, so SSR is needed here */
12425 subsystem_restart("wcnss");
12426 msleep(5000);
12427 }
12428 hdd_set_ssr_required (VOS_FALSE);
12429
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012430 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012431
12432success:
12433 EXIT();
12434 return 0;
12435}
12436
12437/**---------------------------------------------------------------------------
12438
Jeff Johnson32d95a32012-09-10 13:15:23 -070012439 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070012440
Jeff Johnson32d95a32012-09-10 13:15:23 -070012441 This is the driver entry point - called in different timeline depending
12442 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070012443
12444 \param - None
12445
12446 \return - 0 for success, non zero for failure
12447
12448 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070012449static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012450{
12451 VOS_STATUS status;
12452 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012453 struct device *dev = NULL;
12454 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012455#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12456 int max_retries = 0;
12457#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012458#ifdef HAVE_CBC_DONE
12459 int max_cbc_retries = 0;
12460#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012461
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012462#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12463 wlan_logging_sock_init_svc();
12464#endif
12465
Jeff Johnson295189b2012-06-20 16:38:30 -070012466 ENTER();
12467
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012468 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070012469
12470 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
12471 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
12472
Jeff Johnson295189b2012-06-20 16:38:30 -070012473#ifdef ANI_BUS_TYPE_PCI
12474
12475 dev = wcnss_wlan_get_device();
12476
12477#endif // ANI_BUS_TYPE_PCI
12478
12479#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012480
12481#ifdef HAVE_WCNSS_CAL_DOWNLOAD
12482 /* wait until WCNSS driver downloads NV */
12483 while (!wcnss_device_ready() && 5 >= ++max_retries) {
12484 msleep(1000);
12485 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012486
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012487 if (max_retries >= 5) {
12488 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012489 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012490#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12491 wlan_logging_sock_deinit_svc();
12492#endif
12493
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070012494 return -ENODEV;
12495 }
12496#endif
12497
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053012498#ifdef HAVE_CBC_DONE
12499 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
12500 msleep(1000);
12501 }
12502 if (max_cbc_retries >= 10) {
12503 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
12504 }
12505#endif
12506
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 dev = wcnss_wlan_get_device();
12508#endif // ANI_BUS_TYPE_PLATFORM
12509
12510
12511 do {
12512 if (NULL == dev) {
12513 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
12514 ret_status = -1;
12515 break;
12516 }
12517
Jeff Johnson295189b2012-06-20 16:38:30 -070012518#ifdef TIMER_MANAGER
12519 vos_timer_manager_init();
12520#endif
12521
12522 /* Preopen VOSS so that it is ready to start at least SAL */
12523 status = vos_preOpen(&pVosContext);
12524
12525 if (!VOS_IS_STATUS_SUCCESS(status))
12526 {
12527 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
12528 ret_status = -1;
12529 break;
12530 }
12531
Sushant Kaushik02beb352015-06-04 15:15:01 +053012532 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053012533 hdd_register_debug_callback();
12534
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012535#ifndef MODULE
12536 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
12537 */
12538 hdd_set_conparam((v_UINT_t)con_mode);
12539#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012540
12541 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012542 if (hdd_wlan_startup(dev))
12543 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080012545 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 vos_preClose( &pVosContext );
12547 ret_status = -1;
12548 break;
12549 }
12550
Jeff Johnson295189b2012-06-20 16:38:30 -070012551 } while (0);
12552
12553 if (0 != ret_status)
12554 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012555#ifdef TIMER_MANAGER
12556 vos_timer_exit();
12557#endif
12558#ifdef MEMORY_DEBUG
12559 vos_mem_exit();
12560#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012561 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012562#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12563 wlan_logging_sock_deinit_svc();
12564#endif
12565
Jeff Johnson295189b2012-06-20 16:38:30 -070012566 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
12567 }
12568 else
12569 {
12570 //Send WLAN UP indication to Nlink Service
12571 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
12572
12573 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070012574 }
12575
12576 EXIT();
12577
12578 return ret_status;
12579}
12580
Jeff Johnson32d95a32012-09-10 13:15:23 -070012581/**---------------------------------------------------------------------------
12582
12583 \brief hdd_module_init() - Init Function
12584
12585 This is the driver entry point (invoked when module is loaded using insmod)
12586
12587 \param - None
12588
12589 \return - 0 for success, non zero for failure
12590
12591 --------------------------------------------------------------------------*/
12592#ifdef MODULE
12593static int __init hdd_module_init ( void)
12594{
12595 return hdd_driver_init();
12596}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012597#else /* #ifdef MODULE */
12598static int __init hdd_module_init ( void)
12599{
12600 /* Driver initialization is delayed to fwpath_changed_handler */
12601 return 0;
12602}
Jeff Johnson32d95a32012-09-10 13:15:23 -070012603#endif /* #ifdef MODULE */
12604
Jeff Johnson295189b2012-06-20 16:38:30 -070012605
12606/**---------------------------------------------------------------------------
12607
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012608 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070012609
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012610 This is the driver exit point (invoked when module is unloaded using rmmod
12611 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070012612
12613 \param - None
12614
12615 \return - None
12616
12617 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012618static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070012619{
12620 hdd_context_t *pHddCtx = NULL;
12621 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053012622 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053012623 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012624
12625 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
12626
12627 //Get the global vos context
12628 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12629
12630 if(!pVosContext)
12631 {
12632 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
12633 goto done;
12634 }
12635
12636 //Get the HDD context.
12637 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
12638
12639 if(!pHddCtx)
12640 {
12641 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
12642 }
Katya Nigame7b69a82015-04-28 15:24:06 +053012643 else if (VOS_MONITOR_MODE == hdd_get_conparam())
12644 {
12645 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
12646 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12647 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
12648 hdd_wlan_exit(pHddCtx);
12649 vos_preClose( &pVosContext );
12650 goto done;
12651 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 else
12653 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053012654 /* We wait for active entry threads to exit from driver
12655 * by waiting until rtnl_lock is available.
12656 */
12657 rtnl_lock();
12658 rtnl_unlock();
12659
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012660 INIT_COMPLETION(pHddCtx->ssr_comp_var);
12661 if ((pHddCtx->isLogpInProgress) && (FALSE ==
12662 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
12663 {
Siddharth Bhala204f572015-01-17 02:03:36 +053012664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012665 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053012666 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
12667 msecs_to_jiffies(30000));
12668 if(!rc)
12669 {
12670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12671 "%s:SSR timedout, fatal error", __func__);
12672 VOS_BUG(0);
12673 }
12674 }
12675
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053012676 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
12677 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012678
c_hpothu8adb97b2014-12-08 19:38:20 +053012679 /* Driver Need to send country code 00 in below condition
12680 * 1) If gCountryCodePriority is set to 1; and last country
12681 * code set is through 11d. This needs to be done in case
12682 * when NV country code is 00.
12683 * This Needs to be done as when kernel store last country
12684 * code and if stored country code is not through 11d,
12685 * in sme_HandleChangeCountryCodeByUser we will disable 11d
12686 * in next load/unload as soon as we get any country through
12687 * 11d. In sme_HandleChangeCountryCodeByUser
12688 * pMsg->countryCode will be last countryCode and
12689 * pMac->scan.countryCode11d will be country through 11d so
12690 * due to mismatch driver will disable 11d.
12691 *
12692 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053012693
c_hpothu8adb97b2014-12-08 19:38:20 +053012694 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012695 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053012696 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053012697 {
12698 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053012699 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053012700 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
12701 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053012702
c_hpothu8adb97b2014-12-08 19:38:20 +053012703 //Do all the cleanup before deregistering the driver
12704 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 }
12706
Jeff Johnson295189b2012-06-20 16:38:30 -070012707 vos_preClose( &pVosContext );
12708
12709#ifdef TIMER_MANAGER
12710 vos_timer_exit();
12711#endif
12712#ifdef MEMORY_DEBUG
12713 vos_mem_exit();
12714#endif
12715
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012716#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12717 wlan_logging_sock_deinit_svc();
12718#endif
12719
Jeff Johnson295189b2012-06-20 16:38:30 -070012720done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012721 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012722
Jeff Johnson295189b2012-06-20 16:38:30 -070012723 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
12724}
12725
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012726/**---------------------------------------------------------------------------
12727
12728 \brief hdd_module_exit() - Exit function
12729
12730 This is the driver exit point (invoked when module is unloaded using rmmod)
12731
12732 \param - None
12733
12734 \return - None
12735
12736 --------------------------------------------------------------------------*/
12737static void __exit hdd_module_exit(void)
12738{
12739 hdd_driver_exit();
12740}
12741
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012742#ifdef MODULE
12743static int fwpath_changed_handler(const char *kmessage,
12744 struct kernel_param *kp)
12745{
Jeff Johnson76052702013-04-16 13:55:05 -070012746 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012747}
12748
12749static int con_mode_handler(const char *kmessage,
12750 struct kernel_param *kp)
12751{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070012752 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012753}
12754#else /* #ifdef MODULE */
12755/**---------------------------------------------------------------------------
12756
Jeff Johnson76052702013-04-16 13:55:05 -070012757 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012758
Jeff Johnson76052702013-04-16 13:55:05 -070012759 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012760 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070012761 - invoked when module parameter fwpath is modified from userspace to signal
12762 initializing the WLAN driver or when con_mode is modified from userspace
12763 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012764
12765 \return - 0 for success, non zero for failure
12766
12767 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012768static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012769{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012770 int ret_status;
12771
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012772 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012773 ret_status = hdd_driver_init();
12774 wlan_hdd_inited = ret_status ? 0 : 1;
12775 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012776 }
12777
12778 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070012779
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012780 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070012781
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070012782 ret_status = hdd_driver_init();
12783 wlan_hdd_inited = ret_status ? 0 : 1;
12784 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070012785}
12786
Jeff Johnson295189b2012-06-20 16:38:30 -070012787/**---------------------------------------------------------------------------
12788
Jeff Johnson76052702013-04-16 13:55:05 -070012789 \brief fwpath_changed_handler() - Handler Function
12790
12791 Handle changes to the fwpath parameter
12792
12793 \return - 0 for success, non zero for failure
12794
12795 --------------------------------------------------------------------------*/
12796static int fwpath_changed_handler(const char *kmessage,
12797 struct kernel_param *kp)
12798{
12799 int ret;
12800
12801 ret = param_set_copystring(kmessage, kp);
12802 if (0 == ret)
12803 ret = kickstart_driver();
12804 return ret;
12805}
12806
12807/**---------------------------------------------------------------------------
12808
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012809 \brief con_mode_handler() -
12810
12811 Handler function for module param con_mode when it is changed by userspace
12812 Dynamically linked - do nothing
12813 Statically linked - exit and init driver, as in rmmod and insmod
12814
Jeff Johnson76052702013-04-16 13:55:05 -070012815 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012816
Jeff Johnson76052702013-04-16 13:55:05 -070012817 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012818
12819 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070012820static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012821{
Jeff Johnson76052702013-04-16 13:55:05 -070012822 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012823
Jeff Johnson76052702013-04-16 13:55:05 -070012824 ret = param_set_int(kmessage, kp);
12825 if (0 == ret)
12826 ret = kickstart_driver();
12827 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012828}
12829#endif /* #ifdef MODULE */
12830
12831/**---------------------------------------------------------------------------
12832
Jeff Johnson295189b2012-06-20 16:38:30 -070012833 \brief hdd_get_conparam() -
12834
12835 This is the driver exit point (invoked when module is unloaded using rmmod)
12836
12837 \param - None
12838
12839 \return - tVOS_CON_MODE
12840
12841 --------------------------------------------------------------------------*/
12842tVOS_CON_MODE hdd_get_conparam ( void )
12843{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012844#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012846#else
12847 return (tVOS_CON_MODE)curr_con_mode;
12848#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012849}
12850void hdd_set_conparam ( v_UINT_t newParam )
12851{
12852 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070012853#ifndef MODULE
12854 curr_con_mode = con_mode;
12855#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012856}
12857/**---------------------------------------------------------------------------
12858
12859 \brief hdd_softap_sta_deauth() - function
12860
12861 This to take counter measure to handle deauth req from HDD
12862
12863 \param - pAdapter - Pointer to the HDD
12864
12865 \param - enable - boolean value
12866
12867 \return - None
12868
12869 --------------------------------------------------------------------------*/
12870
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012871VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
12872 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070012873{
Jeff Johnson295189b2012-06-20 16:38:30 -070012874 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012875 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Jeff Johnson295189b2012-06-20 16:38:30 -070012876
12877 ENTER();
12878
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070012879 hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)",
12880 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012881
12882 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012883 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012884 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012885
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012886 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070012887
12888 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080012889 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070012890}
12891
12892/**---------------------------------------------------------------------------
12893
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012894 \brief hdd_del_all_sta() - function
12895
12896 This function removes all the stations associated on stopping AP/P2P GO.
12897
12898 \param - pAdapter - Pointer to the HDD
12899
12900 \return - None
12901
12902 --------------------------------------------------------------------------*/
12903
12904int hdd_del_all_sta(hdd_adapter_t *pAdapter)
12905{
12906 v_U16_t i;
12907 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012908 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12909 ptSapContext pSapCtx = NULL;
12910 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12911 if(pSapCtx == NULL){
12912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12913 FL("psapCtx is NULL"));
12914 return 1;
12915 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012916 ENTER();
12917
12918 hddLog(VOS_TRACE_LEVEL_INFO,
12919 "%s: Delete all STAs associated.",__func__);
12920 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12921 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
12922 )
12923 {
12924 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
12925 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012926 if ((pSapCtx->aStaInfo[i].isUsed) &&
12927 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012928 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012929 struct tagCsrDelStaParams delStaParams;
12930
12931 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012932 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053012933 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
12934 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053012935 &delStaParams);
12936 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012937 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012938 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053012939 }
12940 }
12941 }
12942
12943 EXIT();
12944 return 0;
12945}
12946
12947/**---------------------------------------------------------------------------
12948
Jeff Johnson295189b2012-06-20 16:38:30 -070012949 \brief hdd_softap_sta_disassoc() - function
12950
12951 This to take counter measure to handle deauth req from HDD
12952
12953 \param - pAdapter - Pointer to the HDD
12954
12955 \param - enable - boolean value
12956
12957 \return - None
12958
12959 --------------------------------------------------------------------------*/
12960
12961void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
12962{
12963 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12964
12965 ENTER();
12966
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012967 hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012968
12969 //Ignore request to disassoc bcmc station
12970 if( pDestMacAddress[0] & 0x1 )
12971 return;
12972
12973 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
12974}
12975
12976void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
12977{
12978 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12979
12980 ENTER();
12981
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012982 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070012983
12984 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
12985}
12986
Jeff Johnson295189b2012-06-20 16:38:30 -070012987/**---------------------------------------------------------------------------
12988 *
12989 * \brief hdd_get__concurrency_mode() -
12990 *
12991 *
12992 * \param - None
12993 *
12994 * \return - CONCURRENCY MODE
12995 *
12996 * --------------------------------------------------------------------------*/
12997tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
12998{
12999 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
13000 hdd_context_t *pHddCtx;
13001
13002 if (NULL != pVosContext)
13003 {
13004 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
13005 if (NULL != pHddCtx)
13006 {
13007 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
13008 }
13009 }
13010
13011 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013012 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013013 return VOS_STA;
13014}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013015v_BOOL_t
13016wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
13017{
13018 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013019
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013020 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
13021 if (pAdapter == NULL)
13022 {
13023 hddLog(VOS_TRACE_LEVEL_INFO,
13024 FL("GO doesn't exist"));
13025 return TRUE;
13026 }
13027 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
13028 {
13029 hddLog(VOS_TRACE_LEVEL_INFO,
13030 FL("GO started"));
13031 return TRUE;
13032 }
13033 else
13034 /* wait till GO changes its interface to p2p device */
13035 hddLog(VOS_TRACE_LEVEL_INFO,
13036 FL("Del_bss called, avoid apps suspend"));
13037 return FALSE;
13038
13039}
Jeff Johnson295189b2012-06-20 16:38:30 -070013040/* Decide whether to allow/not the apps power collapse.
13041 * Allow apps power collapse if we are in connected state.
13042 * if not, allow only if we are in IMPS */
13043v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
13044{
13045 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080013046 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013047 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070013048 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13049 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13050 hdd_adapter_t *pAdapter = NULL;
13051 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080013052 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013053
Jeff Johnson295189b2012-06-20 16:38:30 -070013054 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13055 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013056
Yathish9f22e662012-12-10 14:21:35 -080013057 concurrent_state = hdd_get_concurrency_mode();
13058
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013059 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
13060 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
13061 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080013062#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013063
Yathish9f22e662012-12-10 14:21:35 -080013064 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053013065 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080013066 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
13067 return TRUE;
13068#endif
13069
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 /*loop through all adapters. TBD fix for Concurrency */
13071 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13072 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13073 {
13074 pAdapter = pAdapterNode->pAdapter;
13075 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13076 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13077 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080013078 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053013079 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053013080 && pmcState != STOPPED && pmcState != STANDBY &&
13081 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013082 (eANI_BOOLEAN_TRUE == scanRspPending) ||
13083 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070013084 {
Mukul Sharma4be88422015-03-09 20:29:07 +053013085 if(pmcState == FULL_POWER &&
13086 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
13087 {
13088 /*
13089 * When SCO indication comes from Coex module , host will
13090 * enter in to full power mode, but this should not prevent
13091 * apps processor power collapse.
13092 */
13093 hddLog(LOG1,
13094 FL("Allow apps power collapse"
13095 "even when sco indication is set"));
13096 return TRUE;
13097 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080013098 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080013099 "pmcState = %d scanRspPending = %d inMiddleOfRoaming = %d",
13100 __func__, pmcState, scanRspPending, inMiddleOfRoaming );
Jeff Johnson295189b2012-06-20 16:38:30 -070013101 return FALSE;
13102 }
13103 }
13104 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13105 pAdapterNode = pNext;
13106 }
13107 return TRUE;
13108}
13109
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080013110/* Decides whether to send suspend notification to Riva
13111 * if any adapter is in BMPS; then it is required */
13112v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
13113{
13114 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
13115 hdd_config_t *pConfig = pHddCtx->cfg_ini;
13116
13117 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
13118 {
13119 return TRUE;
13120 }
13121 return FALSE;
13122}
13123
Jeff Johnson295189b2012-06-20 16:38:30 -070013124void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13125{
13126 switch(mode)
13127 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013128 case VOS_STA_MODE:
13129 case VOS_P2P_CLIENT_MODE:
13130 case VOS_P2P_GO_MODE:
13131 case VOS_STA_SAP_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070013132 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013133 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070013134 break;
13135 default:
13136 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070013137 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013138 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13139 "Number of open sessions for mode %d = %d"),
13140 pHddCtx->concurrency_mode, mode,
13141 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013142}
13143
13144
13145void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13146{
13147 switch(mode)
13148 {
Chilam Ngc4244af2013-04-01 15:37:32 -070013149 case VOS_STA_MODE:
13150 case VOS_P2P_CLIENT_MODE:
13151 case VOS_P2P_GO_MODE:
13152 case VOS_STA_SAP_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053013153 pHddCtx->no_of_open_sessions[mode]--;
13154 if (!(pHddCtx->no_of_open_sessions[mode]))
13155 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013156 break;
13157 default:
13158 break;
13159 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013160 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
13161 "Number of open sessions for mode %d = %d"),
13162 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
13163
13164}
13165/**---------------------------------------------------------------------------
13166 *
13167 * \brief wlan_hdd_incr_active_session()
13168 *
13169 * This function increments the number of active sessions
13170 * maintained per device mode
13171 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
13172 * Incase of SAP/P2P GO upon bss start it is incremented
13173 *
13174 * \param pHddCtx - HDD Context
13175 * \param mode - device mode
13176 *
13177 * \return - None
13178 *
13179 * --------------------------------------------------------------------------*/
13180void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13181{
13182 switch (mode) {
13183 case VOS_STA_MODE:
13184 case VOS_P2P_CLIENT_MODE:
13185 case VOS_P2P_GO_MODE:
13186 case VOS_STA_SAP_MODE:
13187 pHddCtx->no_of_active_sessions[mode]++;
13188 break;
13189 default:
13190 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13191 break;
13192 }
13193 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13194 mode,
13195 pHddCtx->no_of_active_sessions[mode]);
13196}
13197
13198/**---------------------------------------------------------------------------
13199 *
13200 * \brief wlan_hdd_decr_active_session()
13201 *
13202 * This function decrements the number of active sessions
13203 * maintained per device mode
13204 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
13205 * Incase of SAP/P2P GO upon bss stop it is decremented
13206 *
13207 * \param pHddCtx - HDD Context
13208 * \param mode - device mode
13209 *
13210 * \return - None
13211 *
13212 * --------------------------------------------------------------------------*/
13213void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
13214{
Bhargav Shahd0715912015-10-01 18:17:37 +053013215
Agarwal Ashish51325b52014-06-16 16:50:49 +053013216 switch (mode) {
13217 case VOS_STA_MODE:
13218 case VOS_P2P_CLIENT_MODE:
13219 case VOS_P2P_GO_MODE:
13220 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053013221 if (pHddCtx->no_of_active_sessions[mode] > 0)
13222 pHddCtx->no_of_active_sessions[mode]--;
13223 else
13224 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
13225 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053013226 break;
13227 default:
13228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
13229 break;
13230 }
13231 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
13232 mode,
13233 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070013234}
13235
Jeff Johnsone7245742012-09-05 17:12:55 -070013236/**---------------------------------------------------------------------------
13237 *
13238 * \brief wlan_hdd_restart_init
13239 *
13240 * This function initalizes restart timer/flag. An internal function.
13241 *
13242 * \param - pHddCtx
13243 *
13244 * \return - None
13245 *
13246 * --------------------------------------------------------------------------*/
13247
13248static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
13249{
13250 /* Initialize */
13251 pHddCtx->hdd_restart_retries = 0;
13252 atomic_set(&pHddCtx->isRestartInProgress, 0);
13253 vos_timer_init(&pHddCtx->hdd_restart_timer,
13254 VOS_TIMER_TYPE_SW,
13255 wlan_hdd_restart_timer_cb,
13256 pHddCtx);
13257}
13258/**---------------------------------------------------------------------------
13259 *
13260 * \brief wlan_hdd_restart_deinit
13261 *
13262 * This function cleans up the resources used. An internal function.
13263 *
13264 * \param - pHddCtx
13265 *
13266 * \return - None
13267 *
13268 * --------------------------------------------------------------------------*/
13269
13270static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
13271{
13272
13273 VOS_STATUS vos_status;
13274 /* Block any further calls */
13275 atomic_set(&pHddCtx->isRestartInProgress, 1);
13276 /* Cleanup */
13277 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
13278 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013279 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013280 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
13281 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013282 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070013283
13284}
13285
13286/**---------------------------------------------------------------------------
13287 *
13288 * \brief wlan_hdd_framework_restart
13289 *
13290 * This function uses a cfg80211 API to start a framework initiated WLAN
13291 * driver module unload/load.
13292 *
13293 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
13294 *
13295 *
13296 * \param - pHddCtx
13297 *
13298 * \return - VOS_STATUS_SUCCESS: Success
13299 * VOS_STATUS_E_EMPTY: Adapter is Empty
13300 * VOS_STATUS_E_NOMEM: No memory
13301
13302 * --------------------------------------------------------------------------*/
13303
13304static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
13305{
13306 VOS_STATUS status = VOS_STATUS_SUCCESS;
13307 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013308 int len = (sizeof (struct ieee80211_mgmt));
13309 struct ieee80211_mgmt *mgmt = NULL;
13310
13311 /* Prepare the DEAUTH managment frame with reason code */
13312 mgmt = kzalloc(len, GFP_KERNEL);
13313 if(mgmt == NULL)
13314 {
13315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13316 "%s: memory allocation failed (%d bytes)", __func__, len);
13317 return VOS_STATUS_E_NOMEM;
13318 }
13319 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070013320
13321 /* Iterate over all adapters/devices */
13322 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013323 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
13324 {
13325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13326 FL("fail to get adapter: %p %d"), pAdapterNode, status);
13327 goto end;
13328 }
13329
Jeff Johnsone7245742012-09-05 17:12:55 -070013330 do
13331 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013332 if(pAdapterNode->pAdapter &&
13333 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070013334 {
13335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13336 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
13337 pAdapterNode->pAdapter->dev->name,
13338 pAdapterNode->pAdapter->device_mode,
13339 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013340 /*
13341 * CFG80211 event to restart the driver
13342 *
13343 * 'cfg80211_send_unprot_deauth' sends a
13344 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
13345 * of SME(Linux Kernel) state machine.
13346 *
13347 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
13348 * the driver.
13349 *
13350 */
Abhishek Singh00b71972016-01-07 10:51:04 +053013351
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013352#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
13353 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
13354#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013355 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053013356#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013357 }
13358 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13359 pAdapterNode = pNext;
13360 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
13361
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053013362 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070013363 /* Free the allocated management frame */
13364 kfree(mgmt);
13365
Jeff Johnsone7245742012-09-05 17:12:55 -070013366 /* Retry until we unload or reach max count */
13367 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
13368 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
13369
13370 return status;
13371
13372}
13373/**---------------------------------------------------------------------------
13374 *
13375 * \brief wlan_hdd_restart_timer_cb
13376 *
13377 * Restart timer callback. An internal function.
13378 *
13379 * \param - User data:
13380 *
13381 * \return - None
13382 *
13383 * --------------------------------------------------------------------------*/
13384
13385void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
13386{
13387 hdd_context_t *pHddCtx = usrDataForCallback;
13388 wlan_hdd_framework_restart(pHddCtx);
13389 return;
13390
13391}
13392
13393
13394/**---------------------------------------------------------------------------
13395 *
13396 * \brief wlan_hdd_restart_driver
13397 *
13398 * This function sends an event to supplicant to restart the WLAN driver.
13399 *
13400 * This function is called from vos_wlanRestart.
13401 *
13402 * \param - pHddCtx
13403 *
13404 * \return - VOS_STATUS_SUCCESS: Success
13405 * VOS_STATUS_E_EMPTY: Adapter is Empty
13406 * VOS_STATUS_E_ALREADY: Request already in progress
13407
13408 * --------------------------------------------------------------------------*/
13409VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
13410{
13411 VOS_STATUS status = VOS_STATUS_SUCCESS;
13412
13413 /* A tight check to make sure reentrancy */
13414 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
13415 {
Mihir Shetefd528652014-06-23 19:07:50 +053013416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070013417 "%s: WLAN restart is already in progress", __func__);
13418
13419 return VOS_STATUS_E_ALREADY;
13420 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070013421 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080013422#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053013423 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070013424#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070013425
Jeff Johnsone7245742012-09-05 17:12:55 -070013426 return status;
13427}
13428
Bhargav Shahd0715912015-10-01 18:17:37 +053013429/**
13430 * hdd_get_total_sessions() - provide total number of active sessions
13431 * @pHddCtx: Valid Global HDD context pointer
13432 *
13433 * This function iterates through pAdaptors and find the number of all active
13434 * sessions. This active sessions includes connected sta, p2p client and number
13435 * of client connected to sap/p2p go.
13436 *
13437 * Return: Total number of active sessions.
13438 */
13439v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
13440{
13441 v_U8_t active_session = 0;
13442 hdd_station_ctx_t *pHddStaCtx;
13443 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13444 hdd_adapter_t *pAdapter;
13445 VOS_STATUS status;
13446
13447 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
13448 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13449 pAdapter = pAdapterNode->pAdapter;
13450 switch (pAdapter->device_mode) {
13451 case VOS_STA_MODE:
13452 case VOS_P2P_CLIENT_MODE:
13453 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13454 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13455 active_session += 1;
13456 break;
13457 case VOS_STA_SAP_MODE:
13458 case VOS_P2P_GO_MODE:
13459 active_session += hdd_softap_get_connected_sta(pAdapter);
13460 break;
13461 default:
13462 break;
13463 }
13464
13465 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
13466 pAdapterNode = pNext;
13467 }
13468
13469 return active_session;
13470}
13471
13472/**
13473 * hdd_set_delack_value() - Set delack value
13474 * @pHddCtx: Valid Global HDD context pointer
13475 * @next_rx_level: Value to set for delack
13476 *
13477 * This function compare present value and next value of delack. If the both
13478 * are diffrent then it sets next value .
13479 *
13480 * Return: void.
13481 */
13482void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
13483{
13484 if (pHddCtx->cur_rx_level != next_rx_level) {
13485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13486 "%s: TCP DELACK trigger level %d",
13487 __func__, next_rx_level);
13488 mutex_lock(&pHddCtx->cur_rx_level_lock);
13489 pHddCtx->cur_rx_level = next_rx_level;
13490 mutex_unlock(&pHddCtx->cur_rx_level_lock);
13491 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
13492 sizeof(next_rx_level));
13493 }
13494}
13495
13496/**
13497 * hdd_set_default_stop_delack_timer() - Start delack timer
13498 * @pHddCtx: Valid Global HDD context pointer
13499 *
13500 * This function stop delack timer and set delack value to default..
13501 *
13502 * Return: void.
13503 */
13504
13505void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
13506{
13507 if (VOS_TIMER_STATE_RUNNING !=
13508 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13510 "%s: Can not stop timer", __func__);
13511 return;
13512 }
13513
13514 vos_timer_stop(&pHddCtx->delack_timer);
13515 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
13516}
13517
13518/**
13519 * hdd_start_delack_timer() - Start delack timer
13520 * @pHddCtx: Valid Global HDD context pointer
13521 *
13522 * This function starts the delack timer for tcpDelAckComputeInterval time
13523 * interval.The default timer value is 2 second.
13524 *
13525 * Return: void.
13526 */
13527void hdd_start_delack_timer(hdd_context_t *pHddCtx)
13528{
13529 if (VOS_TIMER_STATE_RUNNING ==
13530 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
13531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13532 "%s: Timer is already running", __func__);
13533 return;
13534 }
13535
13536 vos_timer_start(&pHddCtx->delack_timer,
13537 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
13538}
13539
13540/**
13541 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
13542 * @pHddCtx: Valid Global HDD context pointer
13543 *
13544 * This function updates the prev_rx_packets count from the corresponding
13545 * pAdapter states. This prev_rx_packets will diffed with the packet count
13546 * at the end of delack timer. That can give number of RX packet is spacific
13547 * time.
13548 *
13549 * Return: void.
13550 */
13551void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
13552{
13553 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13554 hdd_adapter_t *pAdapter;
13555 VOS_STATUS status;
13556
13557 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13558 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
13559 pAdapter = pAdapterNode->pAdapter;
13560 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
13561 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13562 pAdapterNode = pNext;
13563 }
13564}
13565
13566/**
13567 * hdd_manage_delack_timer() - start\stop delack timer
13568 * @pHddCtx: Valid Global HDD context pointer
13569 *
13570 * This function check the number of concerent session present, it starts the
13571 * delack timer if only one session is present.
13572 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
13573 *
13574 * Return: void.
13575 */
13576void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
13577{
13578 uint8_t sessions;
13579
13580 if (!pHddCtx->cfg_ini->enable_delack) {
13581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
13582 "%s: TCP DELACK is not enabled", __func__);
13583 return;
13584 }
13585
13586 /* Blindly stop timer of BTCOEX and TDLS Session is up */
13587 if (pHddCtx->mode != 0) {
13588 hdd_set_default_stop_delack_timer(pHddCtx);
13589 return;
13590 }
13591
13592 sessions = hdd_get_total_sessions(pHddCtx);
13593 if (sessions == 1) {
13594 hdd_update_prev_rx_packet_count(pHddCtx);
13595 hdd_start_delack_timer(pHddCtx);
13596 } else {
13597 hdd_set_default_stop_delack_timer(pHddCtx);
13598 }
13599}
13600
Mihir Shetee1093ba2014-01-21 20:13:32 +053013601/**---------------------------------------------------------------------------
13602 *
13603 * \brief wlan_hdd_init_channels
13604 *
13605 * This function is used to initialize the channel list in CSR
13606 *
13607 * This function is called from hdd_wlan_startup
13608 *
13609 * \param - pHddCtx: HDD context
13610 *
13611 * \return - VOS_STATUS_SUCCESS: Success
13612 * VOS_STATUS_E_FAULT: Failure reported by SME
13613
13614 * --------------------------------------------------------------------------*/
13615static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
13616{
13617 eHalStatus status;
13618
13619 status = sme_InitChannels(pHddCtx->hHal);
13620 if (HAL_STATUS_SUCCESS(status))
13621 {
13622 return VOS_STATUS_SUCCESS;
13623 }
13624 else
13625 {
13626 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
13627 __func__, status);
13628 return VOS_STATUS_E_FAULT;
13629 }
13630}
13631
Mihir Shete04206452014-11-20 17:50:58 +053013632#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013633VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013634{
13635 eHalStatus status;
13636
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013637 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013638 if (HAL_STATUS_SUCCESS(status))
13639 {
13640 return VOS_STATUS_SUCCESS;
13641 }
13642 else
13643 {
13644 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
13645 __func__, status);
13646 return VOS_STATUS_E_FAULT;
13647 }
13648}
Mihir Shete04206452014-11-20 17:50:58 +053013649#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070013650/*
13651 * API to find if there is any STA or P2P-Client is connected
13652 */
13653VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
13654{
13655 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
13656}
Jeff Johnsone7245742012-09-05 17:12:55 -070013657
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013658
13659/*
13660 * API to find if the firmware will send logs using DXE channel
13661 */
13662v_U8_t hdd_is_fw_logging_enabled(void)
13663{
13664 hdd_context_t *pHddCtx;
13665
13666 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13667 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13668
Sachin Ahuja084313e2015-05-21 17:57:10 +053013669 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053013670}
13671
Agarwal Ashish57e84372014-12-05 18:26:53 +053013672/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053013673 * API to find if the firmware will send trace logs using DXE channel
13674 */
13675v_U8_t hdd_is_fw_ev_logging_enabled(void)
13676{
13677 hdd_context_t *pHddCtx;
13678
13679 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
13680 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
13681
13682 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
13683}
13684/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053013685 * API to find if there is any session connected
13686 */
13687VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
13688{
13689 return sme_is_any_session_connected(pHddCtx->hHal);
13690}
13691
13692
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013693int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
13694{
13695 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13696 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053013697 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053013698 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013699
13700 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053013701 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013702 if (pScanInfo->mScanPending)
13703 {
c_hpothua3d45d52015-01-05 14:11:17 +053013704 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
13705 eCSR_SCAN_ABORT_DEFAULT);
13706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13707 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013708
c_hpothua3d45d52015-01-05 14:11:17 +053013709 /* If there is active scan command lets wait for the completion else
13710 * there is no need to wait as scan command might be in the SME pending
13711 * command list.
13712 */
13713 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
13714 {
c_hpothua3d45d52015-01-05 14:11:17 +053013715 status = wait_for_completion_interruptible_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013716 &pScanInfo->abortscan_event_var,
13717 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053013718 if (0 >= status)
13719 {
13720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053013721 "%s: Timeout or Interrupt occurred while waiting for abort"
13722 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053013723 return -ETIMEDOUT;
13724 }
13725 }
13726 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
13727 {
13728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13729 FL("hdd_abort_mac_scan failed"));
13730 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013731 }
13732 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053013733 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053013734}
13735
Abhishek Singh7d624e12015-11-30 14:29:27 +053013736/**
13737 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
13738 * user space
13739 * @frame_ind: Management frame data to be informed.
13740 *
13741 * This function is used to indicate management frame to
13742 * user space
13743 *
13744 * Return: None
13745 *
13746 */
13747void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
13748{
13749 hdd_context_t *hdd_ctx = NULL;
13750 hdd_adapter_t *adapter = NULL;
13751 v_CONTEXT_t vos_context = NULL;
13752
13753 /* Get the global VOSS context.*/
13754 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13755 if (!vos_context) {
13756 hddLog(LOGE, FL("Global VOS context is Null"));
13757 return;
13758 }
13759 /* Get the HDD context.*/
13760 hdd_ctx =
13761 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
13762
13763 if (0 != wlan_hdd_validate_context(hdd_ctx))
13764 {
13765 return;
13766 }
13767 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
13768 frame_ind->sessionId);
13769
13770 if ((NULL != adapter) &&
13771 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
13772 __hdd_indicate_mgmt_frame(adapter,
13773 frame_ind->frameLen,
13774 frame_ind->frameBuf,
13775 frame_ind->frameType,
13776 frame_ind->rxChan,
13777 frame_ind->rxRssi);
13778 return;
13779
13780}
13781
c_hpothu225aa7c2014-10-22 17:45:13 +053013782VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
13783{
13784 hdd_adapter_t *pAdapter;
13785 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13786 VOS_STATUS vosStatus;
13787
13788 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13789 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13790 {
13791 pAdapter = pAdapterNode->pAdapter;
13792 if (NULL != pAdapter)
13793 {
13794 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
13795 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
13796 WLAN_HDD_P2P_GO == pAdapter->device_mode)
13797 {
13798 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
13799 pAdapter->device_mode);
13800 if (VOS_STATUS_SUCCESS !=
13801 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
13802 {
13803 hddLog(LOGE, FL("failed to abort ROC"));
13804 return VOS_STATUS_E_FAILURE;
13805 }
13806 }
13807 }
13808 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13809 pAdapterNode = pNext;
13810 }
13811 return VOS_STATUS_SUCCESS;
13812}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053013813
Mihir Shete0be28772015-02-17 18:42:14 +053013814hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
13815{
13816 hdd_adapter_t *pAdapter;
13817 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13818 hdd_cfg80211_state_t *cfgState;
13819 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
13820 VOS_STATUS vosStatus;
13821
13822 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
13823 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
13824 {
13825 pAdapter = pAdapterNode->pAdapter;
13826 if (NULL != pAdapter)
13827 {
13828 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
13829 pRemainChanCtx = cfgState->remain_on_chan_ctx;
13830 if (pRemainChanCtx)
13831 break;
13832 }
13833 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
13834 pAdapterNode = pNext;
13835 }
13836 return pRemainChanCtx;
13837}
13838
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053013839/**
13840 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
13841 *
13842 * @pHddCtx: HDD context within host driver
13843 * @dfsScanMode: dfsScanMode passed from ioctl
13844 *
13845 */
13846
13847VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
13848 tANI_U8 dfsScanMode)
13849{
13850 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
13851 hdd_adapter_t *pAdapter;
13852 VOS_STATUS vosStatus;
13853 hdd_station_ctx_t *pHddStaCtx;
13854 eHalStatus status = eHAL_STATUS_SUCCESS;
13855
13856 if(!pHddCtx)
13857 {
13858 hddLog(LOGE, FL("HDD context is Null"));
13859 return eHAL_STATUS_FAILURE;
13860 }
13861
13862 if (pHddCtx->scan_info.mScanPending)
13863 {
13864 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
13865 pHddCtx->scan_info.sessionId);
13866 hdd_abort_mac_scan(pHddCtx,
13867 pHddCtx->scan_info.sessionId,
13868 eCSR_SCAN_ABORT_DEFAULT);
13869 }
13870
13871 if (!dfsScanMode)
13872 {
13873 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
13874 while ((NULL != pAdapterNode) &&
13875 (VOS_STATUS_SUCCESS == vosStatus))
13876 {
13877 pAdapter = pAdapterNode->pAdapter;
13878
13879 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
13880 {
13881 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13882
13883 if(!pHddStaCtx)
13884 {
13885 hddLog(LOGE, FL("HDD STA context is Null"));
13886 return eHAL_STATUS_FAILURE;
13887 }
13888
13889 /* if STA is already connected on DFS channel,
13890 disconnect immediately*/
13891 if (hdd_connIsConnected(pHddStaCtx) &&
13892 (NV_CHANNEL_DFS ==
13893 vos_nv_getChannelEnabledState(
13894 pHddStaCtx->conn_info.operationChannel)))
13895 {
13896 status = sme_RoamDisconnect(pHddCtx->hHal,
13897 pAdapter->sessionId,
13898 eCSR_DISCONNECT_REASON_UNSPECIFIED);
13899 hddLog(LOG1, FL("Client connected on DFS channel %d,"
13900 "sme_RoamDisconnect returned with status: %d"
13901 "for sessionid: %d"), pHddStaCtx->conn_info.
13902 operationChannel, status, pAdapter->sessionId);
13903 }
13904 }
13905
13906 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
13907 &pNext);
13908 pAdapterNode = pNext;
13909 }
13910 }
13911
13912 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
13913 sme_UpdateDFSRoamMode(pHddCtx->hHal,
13914 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
13915
13916 status = sme_HandleDFSChanScan(pHddCtx->hHal);
13917 if (!HAL_STATUS_SUCCESS(status))
13918 {
13919 hddLog(LOGE,
13920 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
13921 return status;
13922 }
13923
13924 return status;
13925}
13926
Nirav Shah7e3c8132015-06-22 23:51:42 +053013927static int hdd_log2_ceil(unsigned value)
13928{
13929 /* need to switch to unsigned math so that negative values
13930 * will right-shift towards 0 instead of -1
13931 */
13932 unsigned tmp = value;
13933 int log2 = -1;
13934
13935 if (value == 0)
13936 return 0;
13937
13938 while (tmp) {
13939 log2++;
13940 tmp >>= 1;
13941 }
13942 if (1U << log2 != value)
13943 log2++;
13944
13945 return log2;
13946}
13947
13948/**
13949 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
13950 * @pAdapter: adapter handle
13951 *
13952 * Return: vos status
13953 */
13954VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
13955{
13956 int hash_elem, log2, i;
13957
13958 spin_lock_bh( &pAdapter->sta_hash_lock);
13959 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
13960 spin_unlock_bh( &pAdapter->sta_hash_lock);
13961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13962 "%s: hash already attached for session id %d",
13963 __func__, pAdapter->sessionId);
13964 return VOS_STATUS_SUCCESS;
13965 }
13966 spin_unlock_bh( &pAdapter->sta_hash_lock);
13967
13968 hash_elem = WLAN_MAX_STA_COUNT;
13969 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
13970 log2 = hdd_log2_ceil(hash_elem);
13971 hash_elem = 1 << log2;
13972
13973 pAdapter->sta_id_hash.mask = hash_elem - 1;
13974 pAdapter->sta_id_hash.idx_bits = log2;
13975 pAdapter->sta_id_hash.bins =
13976 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
13977 if (!pAdapter->sta_id_hash.bins) {
13978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13979 "%s: malloc failed for session %d",
13980 __func__, pAdapter->sessionId);
13981 return VOS_STATUS_E_NOMEM;
13982 }
13983
13984 for (i = 0; i < hash_elem; i++)
13985 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
13986
13987 spin_lock_bh( &pAdapter->sta_hash_lock);
13988 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
13989 spin_unlock_bh( &pAdapter->sta_hash_lock);
13990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13991 "%s: Station ID Hash attached for session id %d",
13992 __func__, pAdapter->sessionId);
13993
13994 return VOS_STATUS_SUCCESS;
13995}
13996
13997/**
13998 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
13999 * @pAdapter: adapter handle
14000 *
14001 * Return: vos status
14002 */
14003VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
14004{
14005 int hash_elem, i;
14006 v_SIZE_t size;
14007
14008 spin_lock_bh( &pAdapter->sta_hash_lock);
14009 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14010 spin_unlock_bh( &pAdapter->sta_hash_lock);
14011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14012 "%s: hash not initialized for session id %d",
14013 __func__, pAdapter->sessionId);
14014 return VOS_STATUS_SUCCESS;
14015 }
14016
14017 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
14018 spin_unlock_bh( &pAdapter->sta_hash_lock);
14019
14020 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
14021
14022 /* free all station info*/
14023 for (i = 0; i < hash_elem; i++) {
14024 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
14025 if (size != 0) {
14026 VOS_STATUS status;
14027 hdd_staid_hash_node_t *sta_info_node = NULL;
14028 hdd_staid_hash_node_t *next_node = NULL;
14029 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
14030 (hdd_list_node_t**) &sta_info_node );
14031
14032 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14033 {
14034 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
14035 &sta_info_node->node);
14036 vos_mem_free(sta_info_node);
14037
14038 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
14039 (hdd_list_node_t*)sta_info_node,
14040 (hdd_list_node_t**)&next_node);
14041 sta_info_node = next_node;
14042 }
14043 }
14044 }
14045
14046 vos_mem_free(pAdapter->sta_id_hash.bins);
14047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14048 "%s: Station ID Hash detached for session id %d",
14049 __func__, pAdapter->sessionId);
14050 return VOS_STATUS_SUCCESS;
14051}
14052
14053/**
14054 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
14055 * @pAdapter: adapter handle
14056 * @mac_addr_in: input mac address
14057 *
14058 * Return: index derived from mac address
14059 */
14060int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
14061 v_MACADDR_t *mac_addr_in)
14062{
14063 uint16 index;
14064 struct hdd_align_mac_addr_t * mac_addr =
14065 (struct hdd_align_mac_addr_t *)mac_addr_in;
14066
14067 index = mac_addr->bytes_ab ^
14068 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
14069 index ^= index >> pAdapter->sta_id_hash.idx_bits;
14070 index &= pAdapter->sta_id_hash.mask;
14071 return index;
14072}
14073
14074/**
14075 * hdd_sta_id_hash_add_entry() - add entry in hash
14076 * @pAdapter: adapter handle
14077 * @sta_id: station id
14078 * @mac_addr: mac address
14079 *
14080 * Return: vos status
14081 */
14082VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
14083 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14084{
14085 uint16 index;
14086 hdd_staid_hash_node_t *sta_info_node = NULL;
14087
Nirav Shah7e3c8132015-06-22 23:51:42 +053014088 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14089 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
14090 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053014091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14092 "%s: malloc failed", __func__);
14093 return VOS_STATUS_E_NOMEM;
14094 }
14095
14096 sta_info_node->sta_id = sta_id;
14097 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
14098
Nirav Shah303ed5c2015-08-24 10:29:25 +053014099 spin_lock_bh( &pAdapter->sta_hash_lock);
14100 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14101 spin_unlock_bh( &pAdapter->sta_hash_lock);
14102 vos_mem_free(sta_info_node);
14103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14104 "%s: hash is not initialized for session id %d",
14105 __func__, pAdapter->sessionId);
14106 return VOS_STATUS_E_FAILURE;
14107 }
14108
Nirav Shah7e3c8132015-06-22 23:51:42 +053014109 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
14110 (hdd_list_node_t*) sta_info_node );
14111 spin_unlock_bh( &pAdapter->sta_hash_lock);
14112 return VOS_STATUS_SUCCESS;
14113}
14114
14115/**
14116 * hdd_sta_id_hash_remove_entry() - remove entry from hash
14117 * @pAdapter: adapter handle
14118 * @sta_id: station id
14119 * @mac_addr: mac address
14120 *
14121 * Return: vos status
14122 */
14123VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
14124 v_U8_t sta_id, v_MACADDR_t *mac_addr)
14125{
14126 uint16 index;
14127 VOS_STATUS status;
14128 hdd_staid_hash_node_t *sta_info_node = NULL;
14129 hdd_staid_hash_node_t *next_node = NULL;
14130
14131 spin_lock_bh( &pAdapter->sta_hash_lock);
14132 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14133 spin_unlock_bh( &pAdapter->sta_hash_lock);
14134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14135 "%s: hash is not initialized for session id %d",
14136 __func__, pAdapter->sessionId);
14137 return VOS_STATUS_E_FAILURE;
14138 }
14139
14140 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
14141 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14142 (hdd_list_node_t**) &sta_info_node );
14143
14144 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14145 {
14146 if (sta_info_node->sta_id == sta_id) {
14147 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
14148 &sta_info_node->node);
14149 vos_mem_free(sta_info_node);
14150 break;
14151 }
14152 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14153 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
14154 sta_info_node = next_node;
14155 }
14156 spin_unlock_bh( &pAdapter->sta_hash_lock);
14157 return status;
14158}
14159
14160/**
14161 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
14162 * @pAdapter: adapter handle
14163 * @mac_addr_in: mac address
14164 *
14165 * Return: station id
14166 */
14167int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
14168 v_MACADDR_t *mac_addr_in)
14169{
14170 uint8 is_found = 0;
14171 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
14172 uint16 index;
14173 VOS_STATUS status;
14174 hdd_staid_hash_node_t *sta_info_node = NULL;
14175 hdd_staid_hash_node_t *next_node = NULL;
14176
14177 spin_lock_bh( &pAdapter->sta_hash_lock);
14178 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
14179 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053014180 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053014181 FL("hash is not initialized for session id %d"),
14182 pAdapter->sessionId);
14183 return HDD_WLAN_INVALID_STA_ID;
14184 }
14185
14186 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
14187 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
14188 (hdd_list_node_t**) &sta_info_node );
14189
14190 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
14191 {
14192 if (vos_mem_compare(&sta_info_node->mac_addr,
14193 mac_addr_in, sizeof(v_MACADDR_t))) {
14194 is_found = 1;
14195 sta_id = sta_info_node->sta_id;
14196 break;
14197 }
14198 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
14199 (hdd_list_node_t*)sta_info_node,
14200 (hdd_list_node_t**)&next_node);
14201 sta_info_node = next_node;
14202 }
14203 spin_unlock_bh( &pAdapter->sta_hash_lock);
14204 return sta_id;
14205}
14206
c_manjeecfd1efb2015-09-25 19:32:34 +053014207/*FW memory dump feature*/
14208/**
14209 * This structure hold information about the /proc file
14210 *
14211 */
14212static struct proc_dir_entry *proc_file, *proc_dir;
14213
14214/**
14215 * memdump_read() - perform read operation in memory dump proc file
14216 *
14217 * @file - handle for the proc file.
14218 * @buf - pointer to user space buffer.
14219 * @count - number of bytes to be read.
14220 * @pos - offset in the from buffer.
14221 *
14222 * This function performs read operation for the memory dump proc file.
14223 *
14224 * Return: number of bytes read on success, error code otherwise.
14225 */
14226static ssize_t memdump_read(struct file *file, char __user *buf,
14227 size_t count, loff_t *pos)
14228{
14229 int status;
14230 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
14231 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053014232 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053014233 ENTER();
14234
14235 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
14236 status = wlan_hdd_validate_context(hdd_ctx);
14237 if (0 != status) {
14238 return -EINVAL;
14239 }
14240
14241 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
14242 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
14243 return -EINVAL;
14244 }
14245
14246 /* run fs_read_handler in an atomic context*/
14247 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053014248 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
14249 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053014250 {
14251 /*Free the fwr mem dump buffer */
14252 wlan_free_fwr_mem_dump_buffer();
14253 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053014254 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053014255 }
14256 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
14257 vos_ssr_unprotect(__func__);
14258 EXIT();
14259 return ret_count;
14260}
14261
14262/**
14263 * struct memdump_fops - file operations for memory dump feature
14264 * @read - read function for memory dump operation.
14265 *
14266 * This structure initialize the file operation handle for memory
14267 * dump feature
14268 */
14269static const struct file_operations memdump_fops = {
14270 read: memdump_read
14271};
14272
14273/*
14274* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
14275* To be passed by HDD to WDA and called upon receiving of response
14276* from firmware
14277* @fwMemDumpReqContext : memory dump request context
14278* @dump_rsp : dump response from HAL
14279* Returns none
14280*/
14281void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext,
14282 tAniFwrDumpRsp *dump_rsp)
14283{
c_manjeef1495642015-10-13 18:35:01 +053014284 struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext;
c_manjeecfd1efb2015-09-25 19:32:34 +053014285
c_manjeef1495642015-10-13 18:35:01 +053014286 ENTER();
14287 spin_lock(&hdd_context_lock);
14288 if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) {
14289 spin_unlock(&hdd_context_lock);
14290 return;
14291 }
14292 /* report the status to requesting function and free mem.*/
c_manjeecfd1efb2015-09-25 19:32:34 +053014293 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
c_manjeef1495642015-10-13 18:35:01 +053014294 hddLog(LOGE, FL("fw dump request declined by fwr"));
14295 //set the request completion variable
14296 complete(&(pHddFwMemDumpCtx->req_completion));
c_manjeecfd1efb2015-09-25 19:32:34 +053014297 //Free the allocated fwr dump
14298 wlan_free_fwr_mem_dump_buffer();
14299 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeecfd1efb2015-09-25 19:32:34 +053014300 }
c_manjeef1495642015-10-13 18:35:01 +053014301 else {
14302 hddLog(LOG1, FL("fw dump request accepted by fwr"));
14303 /* register the HDD callback which will be called by SVC */
14304 wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx);
14305 }
14306 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014307 EXIT();
14308
14309}
14310
14311/**
14312 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
14313 *
14314 * This function removes file/dir under proc file system that was
14315 * processing firmware memory dump
14316 *
14317 * Return: None
14318 */
14319static void memdump_procfs_remove(void)
14320{
14321 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14322 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
14323 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14324 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14325 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
14326}
14327
14328/**
14329 * memdump_procfs_init() - Initialize procfs for memory dump
14330 *
14331 * @vos_ctx - Global vos context.
14332 *
14333 * This function create file under proc file system to be used later for
14334 * processing firmware memory dump
14335 *
14336 * Return: 0 on success, error code otherwise.
14337 */
14338static int memdump_procfs_init(void *vos_ctx)
14339{
14340 hdd_context_t *hdd_ctx;
14341
14342 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14343 if (!hdd_ctx) {
14344 hddLog(LOGE , FL("Invalid HDD context"));
14345 return -EINVAL;
14346 }
14347
14348 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
14349 if (proc_dir == NULL) {
14350 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
14351 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14352 PROCFS_MEMDUMP_DIR);
14353 return -ENOMEM;
14354 }
14355
14356 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
14357 S_IRUSR | S_IWUSR, proc_dir,
14358 &memdump_fops, hdd_ctx);
14359 if (proc_file == NULL) {
14360 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
14361 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
14362 PROCFS_MEMDUMP_NAME);
14363 return -ENOMEM;
14364 }
14365
14366 hddLog(LOG1 , FL("/proc/%s/%s created"),
14367 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
14368
14369 return 0;
14370}
14371
14372/**
14373 * memdump_init() - Initialization function for memory dump feature
14374 *
14375 * This function creates proc file for memdump feature and registers
14376 * HDD callback function with SME.
14377 *
14378 * Return - 0 on success, error otherwise
14379 */
14380int memdump_init(void)
14381{
14382 hdd_context_t *hdd_ctx;
14383 void *vos_ctx;
14384 int status = 0;
14385
14386 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14387 if (!vos_ctx) {
14388 hddLog(LOGE, FL("Invalid VOS context"));
14389 return -EINVAL;
14390 }
14391
14392 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14393 if (!hdd_ctx) {
14394 hddLog(LOGE , FL("Invalid HDD context"));
14395 return -EINVAL;
14396 }
14397
14398 status = memdump_procfs_init(vos_ctx);
14399 if (status) {
14400 hddLog(LOGE , FL("Failed to create proc file"));
14401 return status;
14402 }
14403
14404 return 0;
14405}
14406
14407/**
14408 * memdump_deinit() - De initialize memdump feature
14409 *
14410 * This function removes proc file created for memdump feature.
14411 *
14412 * Return: None
14413 */
14414int memdump_deinit(void)
14415{
14416 hdd_context_t *hdd_ctx;
14417 void *vos_ctx;
14418
14419 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14420 if (!vos_ctx) {
14421 hddLog(LOGE, FL("Invalid VOS context"));
14422 return -EINVAL;
14423 }
14424
14425 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
14426 if(!hdd_ctx) {
14427 hddLog(LOGE , FL("Invalid HDD context"));
14428 return -EINVAL;
14429 }
14430
14431 memdump_procfs_remove();
14432 return 0;
14433}
14434
14435/**
14436 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
14437 * Return: HAL status
14438 */
14439
14440int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
14441{
14442 tAniFwrDumpReq fw_mem_dump_req={0};
c_manjeef1495642015-10-13 18:35:01 +053014443 struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014444 eHalStatus status = eHAL_STATUS_FAILURE;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014445 int ret=0, result;
c_manjeecfd1efb2015-09-25 19:32:34 +053014446 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053014447
c_manjeecfd1efb2015-09-25 19:32:34 +053014448 /*Check whether a dump request is already going on
14449 *Caution this function will free previously held memory if new dump request is allowed*/
14450 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
14451 hddLog(LOGE, FL("Fw memdump already in progress"));
14452 return -EBUSY;
14453 }
14454 //Allocate memory for fw mem dump buffer
14455 ret = wlan_fwr_mem_dump_buffer_allocation();
14456 if(ret == -EFAULT)
14457 {
14458 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
14459 return ret;
14460 }
14461 if (0 != ret) {
14462 hddLog(LOGE, FL("Fwr mem Allocation failed"));
14463 return -ENOMEM;
14464 }
c_manjeef1495642015-10-13 18:35:01 +053014465 init_completion(&fw_mem_dump_ctx.req_completion);
14466 fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC;
14467 fw_mem_dump_ctx.status = false;
14468
c_manjeecfd1efb2015-09-25 19:32:34 +053014469 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
c_manjeef1495642015-10-13 18:35:01 +053014470 fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx;
c_manjeecfd1efb2015-09-25 19:32:34 +053014471 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
14472 if(eHAL_STATUS_SUCCESS != status)
14473 {
14474 hddLog(VOS_TRACE_LEVEL_ERROR,
14475 "%s: fw_mem_dump_req failed ", __func__);
14476 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053014477 ret = -EFAULT;
14478 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053014479 }
c_manjeef1495642015-10-13 18:35:01 +053014480 /*wait for fw mem dump completion to send event to userspace*/
Abhishek Singh4eca9822015-12-09 18:07:34 +053014481 result =
14482 wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion,
14483 msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS));
14484 if (0 >= result )
c_manjeef1495642015-10-13 18:35:01 +053014485 {
14486 hddLog(VOS_TRACE_LEVEL_ERROR,
Abhishek Singh4eca9822015-12-09 18:07:34 +053014487 "%s: fw_mem_dump_req timeout %d ", __func__,result);
14488 ret = -ETIMEDOUT;
c_manjeef1495642015-10-13 18:35:01 +053014489 }
14490cleanup:
14491 spin_lock(&hdd_context_lock);
14492 fw_mem_dump_ctx.magic = 0;
Abhishek Singh4eca9822015-12-09 18:07:34 +053014493 if(!ret && !fw_mem_dump_ctx.status)
14494 ret = -EFAULT;
c_manjeef1495642015-10-13 18:35:01 +053014495 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014496
c_manjeef1495642015-10-13 18:35:01 +053014497 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053014498 return ret;
c_manjeef1495642015-10-13 18:35:01 +053014499}
14500
14501/**
14502 * HDD callback which will be called by SVC to indicate mem dump completion.
14503 */
14504void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx)
14505{
14506 if (!pHddFwMemDumpCtx) {
14507 hddLog(VOS_TRACE_LEVEL_ERROR,
14508 "%s: HDD context not valid ", __func__);
14509 return;
14510 }
14511 spin_lock(&hdd_context_lock);
14512 /* check the req magic and set status */
14513 if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC)
14514 {
14515 pHddFwMemDumpCtx->status = true;
14516 //signal the completion
14517 complete(&(pHddFwMemDumpCtx->req_completion));
14518 }
14519 else
14520 {
14521 hddLog(VOS_TRACE_LEVEL_ERROR,
14522 "%s: fw mem dump request possible timeout ", __func__);
14523 }
14524 spin_unlock(&hdd_context_lock);
c_manjeecfd1efb2015-09-25 19:32:34 +053014525}
14526
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053014527void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
14528{
14529 if (NULL == pAdapter)
14530 {
14531 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
14532 return;
14533 }
14534 init_completion(&pAdapter->session_open_comp_var);
14535 init_completion(&pAdapter->session_close_comp_var);
14536 init_completion(&pAdapter->disconnect_comp_var);
14537 init_completion(&pAdapter->linkup_event_var);
14538 init_completion(&pAdapter->cancel_rem_on_chan_var);
14539 init_completion(&pAdapter->rem_on_chan_ready_event);
14540 init_completion(&pAdapter->pno_comp_var);
14541#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14542 init_completion(&pAdapter->offchannel_tx_event);
14543#endif
14544 init_completion(&pAdapter->tx_action_cnf_event);
14545#ifdef FEATURE_WLAN_TDLS
14546 init_completion(&pAdapter->tdls_add_station_comp);
14547 init_completion(&pAdapter->tdls_del_station_comp);
14548 init_completion(&pAdapter->tdls_mgmt_comp);
14549 init_completion(&pAdapter->tdls_link_establish_req_comp);
14550#endif
14551
14552#ifdef WLAN_FEATURE_RMC
14553 init_completion(&pAdapter->ibss_peer_info_comp);
14554#endif /* WLAN_FEATURE_RMC */
14555 init_completion(&pAdapter->ula_complete);
14556 init_completion(&pAdapter->change_country_code);
14557
14558#ifdef FEATURE_WLAN_BATCH_SCAN
14559 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
14560 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
14561#endif
14562
14563 return;
14564}
c_manjeecfd1efb2015-09-25 19:32:34 +053014565
14566
Jeff Johnson295189b2012-06-20 16:38:30 -070014567//Register the module init/exit functions
14568module_init(hdd_module_init);
14569module_exit(hdd_module_exit);
14570
14571MODULE_LICENSE("Dual BSD/GPL");
14572MODULE_AUTHOR("Qualcomm Atheros, Inc.");
14573MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
14574
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014575module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
14576 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014577
Jeff Johnson76052702013-04-16 13:55:05 -070014578module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070014579 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080014580
14581module_param(enable_dfs_chan_scan, int,
14582 S_IRUSR | S_IRGRP | S_IROTH);
14583
14584module_param(enable_11d, int,
14585 S_IRUSR | S_IRGRP | S_IROTH);
14586
14587module_param(country_code, charp,
14588 S_IRUSR | S_IRGRP | S_IROTH);