blob: 41f91f02ae545b716adfd362e81d449591a94b93 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05302 * Copyright (c) 2012-2018 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"
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +0530123#include "wlan_hdd_request_manager.h"
Jeff Johnson295189b2012-06-20 16:38:30 -0700124
125#ifdef MODULE
126#define WLAN_MODULE_NAME module_name(THIS_MODULE)
127#else
128#define WLAN_MODULE_NAME "wlan"
129#endif
130
131#ifdef TIMER_MANAGER
132#define TIMER_MANAGER_STR " +TIMER_MANAGER"
133#else
134#define TIMER_MANAGER_STR ""
135#endif
136
137#ifdef MEMORY_DEBUG
138#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
139#else
140#define MEMORY_DEBUG_STR ""
141#endif
Kaushik, Sushant7005e372014-04-08 11:36:54 +0530142#define MAX_WAIT_FOR_ROC_COMPLETION 3
Jeff Johnson295189b2012-06-20 16:38:30 -0700143/* the Android framework expects this param even though we don't use it */
144#define BUF_LEN 20
Jeff Johnson76052702013-04-16 13:55:05 -0700145static char fwpath_buffer[BUF_LEN];
146static struct kparam_string fwpath = {
147 .string = fwpath_buffer,
148 .maxlen = BUF_LEN,
149};
Arif Hussain66559122013-11-21 10:11:40 -0800150
151static char *country_code;
152static int enable_11d = -1;
153static int enable_dfs_chan_scan = -1;
154
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);
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530251void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable);
Jeff Johnsone7245742012-09-05 17:12:55 -0700252
Jeff Johnson295189b2012-06-20 16:38:30 -0700253v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +0530254 struct sk_buff *skb
255#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
256 , void *accel_priv
257#endif
258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
259 , select_queue_fallback_t fallback
260#endif
261);
Jeff Johnson295189b2012-06-20 16:38:30 -0700262
263#ifdef WLAN_FEATURE_PACKET_FILTERING
264static void hdd_set_multicast_list(struct net_device *dev);
265#endif
266
267void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter);
268
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800269#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -0800270void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand);
271static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels);
Srinivas Girigowda100eb322013-03-15 16:48:20 -0700272static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid,
273 tANI_U8 *pChannel, tANI_U8 *pDwellTime,
274 tANI_U8 **pBuf, tANI_U8 *pBufLen);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +0530275static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
276 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel);
Srinivas Girigowdade697412013-02-14 16:31:48 -0800277#endif
Ratheesh S P21280412015-05-19 14:21:52 +0530278
279/* Store WLAN driver info in a global variable such that crash debugger
280 can extract it from driver debug symbol and crashdump for post processing */
281tANI_U8 g_wlan_driver[ ] = "pronto_driver";
282
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800283#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700284VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen);
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800285#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -0700286
Mihir Shetee1093ba2014-01-21 20:13:32 +0530287static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx);
Sushant Kaushik8bc7df22014-04-09 17:55:29 +0530288const char * hdd_device_modetoString(v_U8_t device_mode)
289{
290 switch(device_mode)
291 {
292 CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION );
293 CASE_RETURN_STRING( WLAN_HDD_SOFTAP );
294 CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT );
295 CASE_RETURN_STRING( WLAN_HDD_P2P_GO );
296 CASE_RETURN_STRING( WLAN_HDD_MONITOR);
297 CASE_RETURN_STRING( WLAN_HDD_FTM );
298 CASE_RETURN_STRING( WLAN_HDD_IBSS );
299 CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE );
300 default:
301 return "device_mode Unknown";
302 }
303}
Mihir Shetee1093ba2014-01-21 20:13:32 +0530304
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530305static int __hdd_netdev_notifier_call(struct notifier_block * nb,
Jeff Johnson295189b2012-06-20 16:38:30 -0700306 unsigned long state,
307 void *ndev)
308{
309 struct net_device *dev = ndev;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -0700310 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson27cee452013-03-27 11:10:24 -0700311 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -0700312#ifdef WLAN_BTAMP_FEATURE
313 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -0700314#endif
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530315 long result;
Jeff Johnson295189b2012-06-20 16:38:30 -0700316
317 //Make sure that this callback corresponds to our device.
Jeff Johnson27cee452013-03-27 11:10:24 -0700318 if ((strncmp(dev->name, "wlan", 4)) &&
Amar Singhal4c723bd2013-03-25 18:14:15 -0700319 (strncmp(dev->name, "p2p", 3)))
320 return NOTIFY_DONE;
321
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 if (!dev->ieee80211_ptr)
Jeff Johnson27cee452013-03-27 11:10:24 -0700323 return NOTIFY_DONE;
Jeff Johnson295189b2012-06-20 16:38:30 -0700324
Jeff Johnson27cee452013-03-27 11:10:24 -0700325 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 {
Jeff Johnsona8a1a482012-12-12 16:49:33 -0800327 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700328 VOS_ASSERT(0);
329 return NOTIFY_DONE;
330 }
331
Jeff Johnson27cee452013-03-27 11:10:24 -0700332 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
333 if (NULL == pHddCtx)
334 {
335 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__);
336 VOS_ASSERT(0);
337 return NOTIFY_DONE;
338 }
Sameer Thalappil14067972014-01-23 14:54:54 -0800339 if (pHddCtx->isLogpInProgress)
340 return NOTIFY_DONE;
341
Jeff Johnson27cee452013-03-27 11:10:24 -0700342
343 hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu",
344 __func__, dev->name, state);
Jeff Johnson295189b2012-06-20 16:38:30 -0700345
346 switch (state) {
347 case NETDEV_REGISTER:
348 break;
349
350 case NETDEV_UNREGISTER:
351 break;
352
353 case NETDEV_UP:
354 break;
355
356 case NETDEV_DOWN:
357 break;
358
359 case NETDEV_CHANGE:
Jeff Johnsone7245742012-09-05 17:12:55 -0700360 if(TRUE == pAdapter->isLinkUpSvcNeeded)
361 complete(&pAdapter->linkup_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -0700362 break;
363
364 case NETDEV_GOING_DOWN:
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530365 result = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +0530366 if (result < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530367 {
368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
369 "%s: Timeout occurred while waiting for abortscan %ld",
370 __func__, result);
Jeff Johnson295189b2012-06-20 16:38:30 -0700371 }
372 else
373 {
374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +0530375 "%s: Scan Abort Successful" , __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700376 }
377#ifdef WLAN_BTAMP_FEATURE
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700379 status = WLANBAP_StopAmp();
380 if(VOS_STATUS_SUCCESS != status )
381 {
382 pHddCtx->isAmpAllowed = VOS_TRUE;
383 hddLog(VOS_TRACE_LEVEL_FATAL,
384 "%s: Failed to stop AMP", __func__);
385 }
386 else
387 {
388 //a state m/c implementation in PAL is TBD to avoid this delay
389 msleep(500);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700390 if ( pHddCtx->isAmpAllowed )
391 {
392 WLANBAP_DeregisterFromHCI();
393 pHddCtx->isAmpAllowed = VOS_FALSE;
394 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700395 }
396#endif //WLAN_BTAMP_FEATURE
397 break;
398
399 default:
400 break;
401 }
402
403 return NOTIFY_DONE;
404}
405
Mukul Sharmaa78cf6b2015-02-24 16:59:01 +0530406static int hdd_netdev_notifier_call(struct notifier_block * nb,
407 unsigned long state,
408 void *ndev)
409{
410 int ret;
411 vos_ssr_protect(__func__);
412 ret = __hdd_netdev_notifier_call( nb, state, ndev);
413 vos_ssr_unprotect(__func__);
414 return ret;
415}
416
Jeff Johnson295189b2012-06-20 16:38:30 -0700417struct notifier_block hdd_netdev_notifier = {
418 .notifier_call = hdd_netdev_notifier_call,
419};
420
421/*---------------------------------------------------------------------------
422 * Function definitions
423 *-------------------------------------------------------------------------*/
Jeff Johnson295189b2012-06-20 16:38:30 -0700424void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx);
425void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -0700426//variable to hold the insmod parameters
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700427static int con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -0700428#ifndef MODULE
429/* current con_mode - used only for statically linked driver
430 * con_mode is changed by userspace to indicate a mode change which will
431 * result in calling the module exit and init functions. The module
432 * exit function will clean up based on the value of con_mode prior to it
433 * being changed by userspace. So curr_con_mode records the current con_mode
434 * for exit when con_mode becomes the next mode for init
435 */
Madan Mohan Koyyalamudidfd6aa82012-10-18 20:18:43 -0700436static int curr_con_mode;
Jeff Johnson295189b2012-06-20 16:38:30 -0700437#endif
438
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +0530439#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
440/**
441 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
442 * @hdd_ctx: hdd global context
443 *
444 * Return: none
445 */
446static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
447{
448 uint8_t i;
449
450 mutex_init(&hdd_ctx->op_ctx.op_lock);
451 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
452 {
453 hdd_ctx->op_ctx.op_table[i].request_id = 0;
454 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
455 }
456}
457#else
458static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx)
459{
460}
461#endif
462
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -0800463/**---------------------------------------------------------------------------
464
465 \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable
466
467 Called immediately after the cfg.ini is read in order to configure
468 the desired trace levels.
469
470 \param - moduleId - module whose trace level is being configured
471 \param - bitmask - bitmask of log levels to be enabled
472
473 \return - void
474
475 --------------------------------------------------------------------------*/
476static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
477{
478 wpt_tracelevel level;
479
480 /* if the bitmask is the default value, then a bitmask was not
481 specified in cfg.ini, so leave the logging level alone (it
482 will remain at the "compiled in" default value) */
483 if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
484 {
485 return;
486 }
487
488 /* a mask was specified. start by disabling all logging */
489 vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
490
491 /* now cycle through the bitmask until all "set" bits are serviced */
492 level = VOS_TRACE_LEVEL_FATAL;
493 while (0 != bitmask)
494 {
495 if (bitmask & 1)
496 {
497 vos_trace_setValue(moduleId, level, 1);
498 }
499 level++;
500 bitmask >>= 1;
501 }
502}
503
504
Jeff Johnson295189b2012-06-20 16:38:30 -0700505/**---------------------------------------------------------------------------
506
507 \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable
508
509 Called immediately after the cfg.ini is read in order to configure
510 the desired trace levels in the WDI.
511
512 \param - moduleId - module whose trace level is being configured
513 \param - bitmask - bitmask of log levels to be enabled
514
515 \return - void
516
517 --------------------------------------------------------------------------*/
518static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask)
519{
520 wpt_tracelevel level;
521
522 /* if the bitmask is the default value, then a bitmask was not
523 specified in cfg.ini, so leave the logging level alone (it
524 will remain at the "compiled in" default value) */
525 if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask)
526 {
527 return;
528 }
529
530 /* a mask was specified. start by disabling all logging */
531 wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0);
532
533 /* now cycle through the bitmask until all "set" bits are serviced */
534 level = eWLAN_PAL_TRACE_LEVEL_FATAL;
535 while (0 != bitmask)
536 {
537 if (bitmask & 1)
538 {
539 wpalTraceSetLevel(moduleId, level, 1);
540 }
541 level++;
542 bitmask >>= 1;
543 }
544}
Jeff Johnson295189b2012-06-20 16:38:30 -0700545
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530546/*
547 * FUNCTION: wlan_hdd_validate_context
548 * This function is used to check the HDD context
549 */
550int wlan_hdd_validate_context(hdd_context_t *pHddCtx)
551{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530552
553 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
554 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530556 "%s: HDD context is Null", __func__);
557 return -ENODEV;
558 }
559
560 if (pHddCtx->isLogpInProgress)
561 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu8adb97b2014-12-08 19:38:20 +0530563 "%s: LOGP %s. Ignore!!", __func__,
564 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)
565 ?"failed":"in Progress");
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530566 return -EAGAIN;
567 }
568
Mihir Shete18156292014-03-11 15:38:30 +0530569 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530570 {
Mahesh A Saptasagar886997a2015-03-04 13:15:51 +0530571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530572 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
573 return -EAGAIN;
574 }
575 return 0;
576}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700577#ifdef CONFIG_ENABLE_LINUX_REG
578void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx)
579{
580 hdd_adapter_t *pAdapter = NULL;
581 hdd_station_ctx_t *pHddStaCtx = NULL;
582 eCsrPhyMode phyMode;
583 hdd_config_t *cfg_param = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +0530584
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700585 if (NULL == pHddCtx)
586 {
587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
588 "HDD Context is null !!");
589 return ;
590 }
591
592 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
593 if (NULL == pAdapter)
594 {
595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
596 "pAdapter is null !!");
597 return ;
598 }
599
600 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
601 if (NULL == pHddStaCtx)
602 {
603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
604 "pHddStaCtx is null !!");
605 return ;
606 }
607
608 cfg_param = pHddCtx->cfg_ini;
609 if (NULL == cfg_param)
610 {
611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
612 "cfg_params not available !!");
613 return ;
614 }
615
616 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
617
618 if (!pHddCtx->isVHT80Allowed)
619 {
620 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
621 (eCSR_DOT11_MODE_11ac == phyMode) ||
622 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
623 {
624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
625 "Setting phymode to 11n!!");
626 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
627 }
628 }
629 else
630 {
631 /*New country Supports 11ac as well resetting value back from .ini*/
632 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
633 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
634 return ;
635 }
636
637 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
638 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
639 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
640 {
641 VOS_STATUS vosStatus;
642
643 // need to issue a disconnect to CSR.
644 INIT_COMPLETION(pAdapter->disconnect_comp_var);
645 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
646 pAdapter->sessionId,
647 eCSR_DISCONNECT_REASON_UNSPECIFIED );
648
649 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530650 {
651 long ret;
652
653 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700654 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530655 if (0 >= ret)
656 hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"),
657 ret);
658 }
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700659
660 }
661}
662#else
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530663void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code)
664{
665 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
666 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
667 hdd_config_t *cfg_param;
668 eCsrPhyMode phyMode;
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530669 long ret;
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530670
671 if (NULL == pHddCtx)
672 {
673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
674 "HDD Context is null !!");
675 return ;
676 }
677
678 cfg_param = pHddCtx->cfg_ini;
679
680 if (NULL == cfg_param)
681 {
682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
683 "cfg_params not available !!");
684 return ;
685 }
686
687 phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter));
688
689 if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code))
690 {
691 if ((eCSR_DOT11_MODE_AUTO == phyMode) ||
692 (eCSR_DOT11_MODE_11ac == phyMode) ||
693 (eCSR_DOT11_MODE_11ac_ONLY == phyMode))
694 {
695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
696 "Setting phymode to 11n!!");
697 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n);
698 }
699 }
700 else
701 {
702 /*New country Supports 11ac as well resetting value back from .ini*/
703 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
704 hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode));
705 return ;
706 }
707
708 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
709 ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) ||
710 (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode)))
711 {
712 VOS_STATUS vosStatus;
713
714 // need to issue a disconnect to CSR.
715 INIT_COMPLETION(pAdapter->disconnect_comp_var);
716 vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
717 pAdapter->sessionId,
718 eCSR_DISCONNECT_REASON_UNSPECIFIED );
719
720 if (VOS_STATUS_SUCCESS == vosStatus)
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530721 {
722 ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530723 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +0530724 if (ret <= 0)
725 {
726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
727 "wait on disconnect_comp_var is failed %ld", ret);
728 }
729 }
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530730
731 }
732}
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -0700733#endif //CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +0530734
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700735void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code)
736{
737 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
738 hdd_config_t *cfg_param;
739
740 if (NULL == pHddCtx)
741 {
742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
743 "HDD Context is null !!");
744 return ;
745 }
746
747 cfg_param = pHddCtx->cfg_ini;
748
749 if (NULL == cfg_param)
750 {
751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
752 "cfg_params not available !!");
753 return ;
754 }
755
Agarwal Ashish738843c2014-09-25 12:27:56 +0530756 if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) ||
757 pHddCtx->disable_dfs_flag == TRUE)
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700758 {
759 /*New country doesn't support DFS */
760 sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
761 }
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -0700762
763}
764
Abhishek Singh00b71972016-01-07 10:51:04 +0530765#ifdef WLAN_FEATURE_RMC
766static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable)
767{
768 tANI_U8 *inPtr = pValue;
769 int tempInt;
770 int v = 0;
771 char buf[32];
772 *pRmcEnable = 0;
773
774 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
775 /*no argument after the command*/
776 if (NULL == inPtr)
777 {
778 return 0;
779 }
780
781 /*no space after the command*/
782 else if (SPACE_ASCII_VALUE != *inPtr)
783 {
784 return 0;
785 }
786
787 /*removing empty spaces*/
788 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
789
790 /*no argument followed by spaces*/
791 if ('\0' == *inPtr)
792 {
793 return 0;
794 }
795
796 /* getting the first argument which enables or disables RMC
797 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530798 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530799 v = kstrtos32(buf, 10, &tempInt);
800 if ( v < 0)
801 {
802 return -EINVAL;
803 }
804
805 *pRmcEnable = tempInt;
806
807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
808 "ucRmcEnable: %d", *pRmcEnable);
809
810 return 0;
811}
812
813/* Function header left blank Intentionally */
814static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue,
815 tANI_U32 *pActionPeriod)
816{
817 tANI_U8 *inPtr = pValue;
818 int tempInt;
819 int v = 0;
820 char buf[32];
821 *pActionPeriod = 0;
822
823 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
824 /*no argument after the command*/
825 if (NULL == inPtr)
826 {
827 return -EINVAL;
828 }
829
830 /*no space after the command*/
831 else if (SPACE_ASCII_VALUE != *inPtr)
832 {
833 return -EINVAL;
834 }
835
836 /*removing empty spaces*/
837 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
838
839 /*no argument followed by spaces*/
840 if ('\0' == *inPtr)
841 {
842 return 0;
843 }
844
845 /* getting the first argument which enables or disables RMC
846 * for input IP v4 address*/
Ashish Kumar Dhanotiya54d31a32017-08-04 17:12:44 +0530847 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530848 v = kstrtos32(buf, 10, &tempInt);
849 if ( v < 0)
850 {
851 return -EINVAL;
852 }
853
854 /* Range checking for passed paramter */
855 if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN ||
856 tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX)
857 {
858 return -EINVAL;
859 }
860
861 *pActionPeriod = tempInt;
862
863 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
864 "uActionPeriod: %d", *pActionPeriod);
865
866 return 0;
867}
Dundi Ravitejae110a042018-04-18 13:11:37 +0530868
869/**
870 * hdd_set_vowifi_mode() - Process VOWIFI command.
871 * @hdd_ctx: context handler
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530872 * @enable: Value to be sent as a part of the VOWIFI command
873 *
Dundi Ravitejae110a042018-04-18 13:11:37 +0530874 * Invoke the SME api if station is connected in 2.4 GHz band.
875 * Also start split scan if VOWIFIMODE and dynamic split scan
876 * both are enabled.
877
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530878 * Return: void
879 */
880void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable)
881{
882 tANI_U8 sta_chan;
883
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530884 if (!hdd_ctx->cfg_ini) {
885 hddLog(LOGE, "cfg_ini got NULL");
886 return;
887 }
888
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530889 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
890
Dundi Ravitejae110a042018-04-18 13:11:37 +0530891 if (CSR_IS_CHANNEL_24GHZ(sta_chan))
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530892 sme_set_vowifi_mode(hdd_ctx->hHal, enable);
Dundi Ravitejae110a042018-04-18 13:11:37 +0530893 else
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
895 "VoWiFi command rejected as not connected in 2.4GHz");
Dundi Ravitejae110a042018-04-18 13:11:37 +0530896
897 if (enable && hdd_ctx->cfg_ini->dynSplitscan) {
898 hdd_ctx->is_vowifi_enabled = true;
899 hdd_ctx->issplitscan_enabled = TRUE;
900 sme_enable_disable_split_scan(hdd_ctx->hHal,
901 hdd_ctx->cfg_ini->nNumStaChanCombinedConc,
902 hdd_ctx->cfg_ini->nNumP2PChanCombinedConc);
903 } else {
904 hdd_ctx->is_vowifi_enabled = false;
Dundi Ravitejaab9d3092018-04-05 18:24:40 +0530905 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +0530906}
Abhishek Singh00b71972016-01-07 10:51:04 +0530907
908/* Function header left blank Intentionally */
909static int hdd_parse_setrmcrate_command(tANI_U8 *pValue,
910 tANI_U32 *pRate, tTxrateinfoflags *pTxFlags)
911{
912 tANI_U8 *inPtr = pValue;
913 int tempInt;
914 int v = 0;
915 char buf[32];
916 *pRate = 0;
917 *pTxFlags = 0;
918
919 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
920 /*no argument after the command*/
921 if (NULL == inPtr)
922 {
923 return -EINVAL;
924 }
925
926 /*no space after the command*/
927 else if (SPACE_ASCII_VALUE != *inPtr)
928 {
929 return -EINVAL;
930 }
931
932 /*removing empty spaces*/
933 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
934
935 /*no argument followed by spaces*/
936 if ('\0' == *inPtr)
937 {
938 return 0;
939 }
940
941 /*
942 * getting the first argument which sets multicast rate.
943 */
Ashish Kumar Dhanotiya06f9f202017-08-04 15:26:27 +0530944 sscanf(inPtr, "%31s ", buf);
Abhishek Singh00b71972016-01-07 10:51:04 +0530945 v = kstrtos32(buf, 10, &tempInt);
946 if ( v < 0)
947 {
948 return -EINVAL;
949 }
950
951 /*
952 * Validate the multicast rate.
953 */
954 switch (tempInt)
955 {
956 default:
957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
958 "Unsupported rate: %d", tempInt);
959 return -EINVAL;
960 case 0:
961 case 6:
962 case 9:
963 case 12:
964 case 18:
965 case 24:
966 case 36:
967 case 48:
968 case 54:
969 *pTxFlags = eHAL_TX_RATE_LEGACY;
970 *pRate = tempInt * 10;
971 break;
972 case 65:
973 *pTxFlags = eHAL_TX_RATE_HT20;
974 *pRate = tempInt * 10;
975 break;
976 case 72:
977 *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI;
978 *pRate = 722; /* fractional rate 72.2 Mbps */
979 break;
980 }
981
982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
983 "Rate: %d", *pRate);
984
985 return 0;
986}
987
988/**---------------------------------------------------------------------------
989
990 \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS
991 Peer Info request
992
993 This is an asynchronous callback function from SME when the peer info
994 is received
995
996 \pUserData -> Adapter private data
997 \pPeerInfoRsp -> Peer info response
998
999 \return - 0 for success non-zero for failure
1000 --------------------------------------------------------------------------*/
1001static void
1002hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp)
1003{
1004 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData;
1005 tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp;
1006 hdd_station_ctx_t *pStaCtx;
1007 v_U8_t i;
1008
1009 /*Sanity check*/
1010 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
1011 {
1012 hddLog(LOGE,
1013 FL("invalid adapter or adapter has invalid magic"));
1014 return;
1015 }
1016
1017 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1018 if (NULL != pStaCtx && NULL != pPeerInfo &&
1019 eHAL_STATUS_SUCCESS == pPeerInfo->status)
1020 {
1021 pStaCtx->ibss_peer_info.status = pPeerInfo->status;
1022 pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers;
1023
1024 /* Paranoia check */
1025 if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA)
1026 {
1027 for (i = 0; i < pPeerInfo->numPeers; i++)
1028 {
1029 memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i],
1030 &pPeerInfo->peerInfoParams[i],
1031 sizeof(hdd_ibss_peer_info_params_t));
1032 }
1033 hddLog(LOG1,
1034 FL("Peer Info copied in HDD"));
1035 }
1036 else
1037 {
1038 hddLog(LOGE,
1039 FL(" Number of peers %d returned is more than limit %d"),
1040 pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA);
1041 }
1042 }
1043 else
1044 {
1045 hddLog(LOG1,
1046 FL("peerInfo returned is NULL"));
1047 }
1048
1049 complete(&pAdapter->ibss_peer_info_comp);
1050}
1051
1052/**---------------------------------------------------------------------------
1053
1054 \brief hdd_cfg80211_get_ibss_peer_info_all() -
1055
1056 Request function to get IBSS peer info from lower layers
1057
1058 \pAdapter -> Adapter context
1059
1060 \return - 0 for success non-zero for failure
1061 --------------------------------------------------------------------------*/
1062static
1063VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter)
1064{
1065 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1066 long status;
1067 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1068
1069 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1070
1071 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1072 hdd_cfg80211_get_ibss_peer_info_cb,
1073 VOS_TRUE, 0xFF);
1074
1075 if (VOS_STATUS_SUCCESS == retStatus)
1076 {
1077 status = wait_for_completion_interruptible_timeout
1078 (&pAdapter->ibss_peer_info_comp,
1079 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1080
1081 /* status will be 0 if timed out */
1082 if (status <= 0)
1083 {
1084 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1085 __func__, status);
1086 retStatus = VOS_STATUS_E_FAILURE;
1087 return retStatus;
1088 }
1089 }
1090 else
1091 {
1092 hddLog(VOS_TRACE_LEVEL_WARN,
1093 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1094 }
1095
1096 return retStatus;
1097}
1098
1099/**---------------------------------------------------------------------------
1100
1101 \brief hdd_cfg80211_get_ibss_peer_info() -
1102
1103 Request function to get IBSS peer info from lower layers
1104
1105 \pAdapter -> Adapter context
1106 \staIdx -> Sta index for which the peer info is requested
1107
1108 \return - 0 for success non-zero for failure
1109 --------------------------------------------------------------------------*/
1110static VOS_STATUS
1111hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx)
1112{
1113 long status;
1114 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1115 VOS_STATUS retStatus = VOS_STATUS_E_FAILURE;
1116
1117 INIT_COMPLETION(pAdapter->ibss_peer_info_comp);
1118
1119 retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter,
1120 hdd_cfg80211_get_ibss_peer_info_cb,
1121 VOS_FALSE, staIdx);
1122
1123 if (VOS_STATUS_SUCCESS == retStatus)
1124 {
1125 status = wait_for_completion_interruptible_timeout
1126 (&pAdapter->ibss_peer_info_comp,
1127 msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT));
1128
1129 /* status = 0 on timeout */
1130 if (status <= 0)
1131 {
1132 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld",
1133 __func__, status);
1134 retStatus = VOS_STATUS_E_FAILURE;
1135 return retStatus;
1136 }
1137 }
1138 else
1139 {
1140 hddLog(VOS_TRACE_LEVEL_WARN,
1141 "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__);
1142 }
1143
1144 return retStatus;
1145}
1146
1147/* Function header left blank Intentionally */
1148VOS_STATUS
1149hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr)
1150{
1151 tANI_U8 *inPtr = pValue;
1152 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1153
1154 /*no argument after the command*/
1155 if (NULL == inPtr)
1156 {
1157 return VOS_STATUS_E_FAILURE;;
1158 }
1159
1160 /*no space after the command*/
1161 else if (SPACE_ASCII_VALUE != *inPtr)
1162 {
1163 return VOS_STATUS_E_FAILURE;;
1164 }
1165
1166 /*removing empty spaces*/
1167 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
1168
1169 /*no argument followed by spaces*/
1170 if ('\0' == *inPtr)
1171 {
1172 return VOS_STATUS_E_FAILURE;;
1173 }
1174
1175 /*getting the first argument ie the peer mac address */
1176 if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' ||
1177 inPtr[11] != ':' || inPtr[14] != ':')
1178 {
1179 return VOS_STATUS_E_FAILURE;;
1180 }
1181 sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x",
1182 (unsigned int *)&pPeerMacAddr->bytes[0],
1183 (unsigned int *)&pPeerMacAddr->bytes[1],
1184 (unsigned int *)&pPeerMacAddr->bytes[2],
1185 (unsigned int *)&pPeerMacAddr->bytes[3],
1186 (unsigned int *)&pPeerMacAddr->bytes[4],
1187 (unsigned int *)&pPeerMacAddr->bytes[5]);
1188
1189 /* The command buffer seems to be fine */
1190 return VOS_STATUS_SUCCESS;
1191}
1192
1193/* Function header left blank Intentionally */
1194static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie,
1195 tANI_U32 limit)
1196{
1197 tANI_U8 len;
1198 tANI_U8 data;
1199
1200 /* skip white space */
1201 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1202 {
1203 command++;
1204 limit--;
1205 }
1206
1207 /* skip element id and element length */
1208 len = 2;
1209
1210 /* extract oui */
1211 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1212 (limit > 1))
1213 {
1214 /* Convert ASCII to decimal */
1215 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1216 ie[len++] = data;
1217 command += 2;
1218 limit -= 2;
1219 }
1220
1221 /* skip white space */
1222 while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command))
1223 {
1224 command++;
1225 limit--;
1226 }
1227
1228 /* extract data */
1229 while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) &&
1230 (limit > 1))
1231 {
1232 /* Convert ASCII to decimal */
1233 data = ((*command -'0') << 4) | (*(command + 1) - '0');
1234 ie[len++] = data;
1235 command += 2;
1236 limit -= 2;
1237 }
1238
1239 /* fill element id and element length */
1240 ie[0] = IE_EID_VENDOR;
1241 ie[1] = len - 2;
1242
1243 return len;
1244}
1245
1246static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen)
1247{
1248 tANI_U32 ieLenPresent = 0;
1249 int left = addIeLen;
1250 v_U8_t *ptr = addIePtr;
1251 v_U8_t elem_id,elem_len;
1252
1253 while(left >= 2)
1254 {
1255 elem_id = ptr[0];
1256 elem_len = ptr[1];
1257 left -= 2;
1258 if(elem_len > left)
1259 {
1260 hddLog(LOGE,
1261 FL("****Invalid elem_len=%d left=%d*****"),
1262 elem_len,left);
1263 return 0;
1264 }
1265 if ((elem_id == IE_EID_VENDOR) &&
1266 (left >= WPA_OUI_TYPE_SIZE))
1267 {
1268 if (!memcmp(&ptr[2], WPA_OUI_TYPE,
1269 WPA_OUI_TYPE_SIZE))
1270 {
1271 ieLenPresent += elem_len + 2;
1272 return ieLenPresent;
1273 }
1274 }
1275 ieLenPresent += (elem_len + 2);
1276 left -= elem_len;
1277 ptr += (elem_len + 2);
1278 }
1279 return 0;
1280}
1281
1282#endif /* WLAN_FEATURE_RMC */
1283
Rajeev79dbe4c2013-10-05 11:03:42 +05301284#ifdef FEATURE_WLAN_BATCH_SCAN
1285
1286/**---------------------------------------------------------------------------
1287
1288 \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from
1289 input string
1290
1291 This function extracts assigned integer from string in below format:
1292 "STRING=10" : extracts integer 10 from this string
1293
1294 \param - pInPtr Pointer to input string
1295 \param - base Base for string to int conversion(10 for decimal 16 for hex)
1296 \param - pOutPtr Pointer to variable in which extracted integer needs to be
1297 assigned
1298 \param - pLastArg to tell whether it is last arguement in input string or
1299 not
1300
1301 \return - NULL for failure cases
1302 pointer to next arguement in input string for success cases
1303 --------------------------------------------------------------------------*/
1304static tANI_U8 *
1305hdd_extract_assigned_int_from_str
1306(
1307 tANI_U8 *pInPtr,
1308 tANI_U8 base,
1309 tANI_U32 *pOutPtr,
1310 tANI_U8 *pLastArg
1311)
1312{
1313 int tempInt;
1314 int v = 0;
1315 char buf[32];
1316 int val = 0;
1317 *pLastArg = FALSE;
1318
1319 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1320 if (NULL == pInPtr)
1321 {
1322 return NULL;
1323 }
1324
1325 pInPtr++;
1326
1327 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1328
1329 val = sscanf(pInPtr, "%32s ", buf);
1330 if (val < 0 && val > strlen(pInPtr))
1331 {
1332 return NULL;
1333 }
1334 pInPtr += val;
1335 v = kstrtos32(buf, base, &tempInt);
1336 if (v < 0)
1337 {
1338 return NULL;
1339 }
Rajeev Kumar4d93d842014-01-02 18:31:21 -08001340 if (tempInt < 0)
1341 {
1342 tempInt = 0;
1343 }
Rajeev79dbe4c2013-10-05 11:03:42 +05301344 *pOutPtr = tempInt;
1345
1346 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1347 if (NULL == pInPtr)
1348 {
1349 *pLastArg = TRUE;
1350 return NULL;
1351 }
1352 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1353
1354 return pInPtr;
1355}
1356
1357/**---------------------------------------------------------------------------
1358
1359 \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from
1360 input string
1361
1362 This function extracts assigned character from string in below format:
1363 "STRING=A" : extracts char 'A' from this string
1364
1365 \param - pInPtr Pointer to input string
1366 \param - pOutPtr Pointer to variable in which extracted char needs to be
1367 assigned
1368 \param - pLastArg to tell whether it is last arguement in input string or
1369 not
1370
1371 \return - NULL for failure cases
1372 pointer to next arguement in input string for success cases
1373 --------------------------------------------------------------------------*/
1374static tANI_U8 *
1375hdd_extract_assigned_char_from_str
1376(
1377 tANI_U8 *pInPtr,
1378 tANI_U8 *pOutPtr,
1379 tANI_U8 *pLastArg
1380)
1381{
1382 *pLastArg = FALSE;
1383
1384 pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE);
1385 if (NULL == pInPtr)
1386 {
1387 return NULL;
1388 }
1389
1390 pInPtr++;
1391
1392 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1393
1394 *pOutPtr = *pInPtr;
1395
1396 pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE);
1397 if (NULL == pInPtr)
1398 {
1399 *pLastArg = TRUE;
1400 return NULL;
1401 }
1402 while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++;
1403
1404 return pInPtr;
1405}
1406
1407
1408/**---------------------------------------------------------------------------
1409
1410 \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command
1411
1412 This function parses set batch scan command in below format:
1413 WLS_BATCHING_SET <space> followed by below arguements
1414 "SCANFREQ=XX" : Optional defaults to 30 sec
1415 "MSCAN=XX" : Required number of scans to attempt to batch
1416 "BESTN=XX" : Best Network (RSSI) defaults to 16
1417 "CHANNEL=<X,Y>" : optional defaults to all channels, can list 'A'or` B.
1418 A. implies only 5 GHz , B. implies only 2.4GHz
1419 "RTT=X" : optional defaults to 0
1420 returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on
1421 error
1422
1423 For example input commands:
1424 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is
1425 translated into set batch scan with following parameters:
1426 a) Frequence 60 seconds
1427 b) Batch 10 scans together
1428 c) Best RSSI to be 20
1429 d) 5GHz band only
1430 e) RTT is equal to 0
1431
1432 \param - pValue Pointer to input channel list
1433 \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure
1434
1435 \return - 0 for success non-zero for failure
1436
1437 --------------------------------------------------------------------------*/
1438static int
1439hdd_parse_set_batchscan_command
1440(
1441 tANI_U8 *pValue,
1442 tSirSetBatchScanReq *pHddSetBatchScanReq
1443)
1444{
1445 tANI_U8 *inPtr = pValue;
1446 tANI_U8 val = 0;
1447 tANI_U8 lastArg = 0;
Abhishek Singh00b71972016-01-07 10:51:04 +05301448 tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001449 tANI_U32 nMscan;
Abhishek Singh00b71972016-01-07 10:51:04 +05301450 tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK;
1451 tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1452 tANI_U32 nRtt = 0;
Rajeev Kumarc933d982013-11-18 20:04:20 -08001453 tANI_U32 temp;
Rajeev79dbe4c2013-10-05 11:03:42 +05301454
Rajeev79dbe4c2013-10-05 11:03:42 +05301455 /*go to space after WLS_BATCHING_SET command*/
1456 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
1457 /*no argument after the command*/
1458 if (NULL == inPtr)
1459 {
1460 return -EINVAL;
1461 }
1462
1463 /*no space after the command*/
1464 else if (SPACE_ASCII_VALUE != *inPtr)
1465 {
1466 return -EINVAL;
1467 }
1468
1469 /*removing empty spaces*/
1470 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
1471
1472 /*no argument followed by spaces*/
1473 if ('\0' == *inPtr)
1474 {
1475 return -EINVAL;
1476 }
1477
1478 /*check and parse SCANFREQ*/
1479 if ((strncmp(inPtr, "SCANFREQ", 8) == 0))
1480 {
1481 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001482 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001483
Rajeev Kumarc933d982013-11-18 20:04:20 -08001484 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001485 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001486 nScanFreq = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001487 }
1488
Rajeev79dbe4c2013-10-05 11:03:42 +05301489 if ( (NULL == inPtr) || (TRUE == lastArg))
1490 {
1491 return -EINVAL;
1492 }
1493 }
1494
1495 /*check and parse MSCAN*/
1496 if ((strncmp(inPtr, "MSCAN", 5) == 0))
1497 {
1498 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001499 &nMscan, &lastArg);
1500
1501 if (0 == nMscan)
1502 {
1503 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1504 "invalid MSCAN=%d", nMscan);
1505 return -EINVAL;
1506 }
1507
Rajeev79dbe4c2013-10-05 11:03:42 +05301508 if (TRUE == lastArg)
1509 {
1510 goto done;
1511 }
1512 else if (NULL == inPtr)
1513 {
1514 return -EINVAL;
1515 }
1516 }
1517 else
1518 {
1519 return -EINVAL;
1520 }
1521
1522 /*check and parse BESTN*/
1523 if ((strncmp(inPtr, "BESTN", 5) == 0))
1524 {
1525 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumarc933d982013-11-18 20:04:20 -08001526 &temp, &lastArg);
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001527
Rajeev Kumarc933d982013-11-18 20:04:20 -08001528 if (0 != temp)
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001529 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001530 nBestN = temp;
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001531 }
1532
Rajeev79dbe4c2013-10-05 11:03:42 +05301533 if (TRUE == lastArg)
1534 {
1535 goto done;
1536 }
1537 else if (NULL == inPtr)
1538 {
1539 return -EINVAL;
1540 }
1541 }
1542
1543 /*check and parse CHANNEL*/
1544 if ((strncmp(inPtr, "CHANNEL", 7) == 0))
1545 {
1546 inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg);
Rajeev Kumarc933d982013-11-18 20:04:20 -08001547
Rajeev79dbe4c2013-10-05 11:03:42 +05301548 if (('A' == val) || ('a' == val))
1549 {
c_hpothuebf89732014-02-25 13:00:24 +05301550 ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301551 }
1552 else if (('B' == val) || ('b' == val))
1553 {
c_hpothuebf89732014-02-25 13:00:24 +05301554 ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY;
Rajeev79dbe4c2013-10-05 11:03:42 +05301555 }
1556 else
1557 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08001558 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND;
1559 }
1560
1561 if (TRUE == lastArg)
1562 {
1563 goto done;
1564 }
1565 else if (NULL == inPtr)
1566 {
Rajeev79dbe4c2013-10-05 11:03:42 +05301567 return -EINVAL;
1568 }
1569 }
1570
1571 /*check and parse RTT*/
1572 if ((strncmp(inPtr, "RTT", 3) == 0))
1573 {
1574 inPtr = hdd_extract_assigned_int_from_str(inPtr, 10,
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001575 &nRtt, &lastArg);
Rajeev79dbe4c2013-10-05 11:03:42 +05301576 if (TRUE == lastArg)
1577 {
1578 goto done;
1579 }
1580 if (NULL == inPtr)
1581 {
1582 return -EINVAL;
1583 }
1584 }
1585
1586
1587done:
1588
Rajeev Kumar45e64a72013-11-18 19:48:15 -08001589 pHddSetBatchScanReq->scanFrequency = nScanFreq;
1590 pHddSetBatchScanReq->numberOfScansToBatch = nMscan;
1591 pHddSetBatchScanReq->bestNetwork = nBestN;
1592 pHddSetBatchScanReq->rfBand = ucRfBand;
1593 pHddSetBatchScanReq->rtt = nRtt;
1594
Rajeev79dbe4c2013-10-05 11:03:42 +05301595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1596 "Received WLS_BATCHING_SET with SCANFREQ=%d "
1597 "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d",
1598 pHddSetBatchScanReq->scanFrequency,
1599 pHddSetBatchScanReq->numberOfScansToBatch,
1600 pHddSetBatchScanReq->bestNetwork,
1601 pHddSetBatchScanReq->rfBand,
1602 pHddSetBatchScanReq->rtt);
1603
1604 return 0;
1605}/*End of hdd_parse_set_batchscan_command*/
1606
1607/**---------------------------------------------------------------------------
1608
1609 \brief hdd_set_batch_scan_req_callback () - This function is called after
1610 receiving set batch scan response from FW and it saves set batch scan
1611 response data FW to HDD context and sets the completion event on
1612 which hdd_ioctl is waiting
1613
1614 \param - callbackContext Pointer to HDD adapter
1615 \param - pRsp Pointer to set batch scan response data received from FW
1616
1617 \return - nothing
1618
1619 --------------------------------------------------------------------------*/
1620static void hdd_set_batch_scan_req_callback
1621(
1622 void *callbackContext,
1623 tSirSetBatchScanRsp *pRsp
1624)
1625{
1626 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
1627 tSirSetBatchScanRsp *pHddSetBatchScanRsp;
1628
1629 /*sanity check*/
1630 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1631 {
1632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1633 "%s: Invalid pAdapter magic", __func__);
1634 VOS_ASSERT(0);
1635 return;
1636 }
1637 pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp;
1638
1639 /*save set batch scan response*/
1640 pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch;
1641
1642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1643 "Received set batch scan rsp from FW with nScansToBatch=%d",
1644 pHddSetBatchScanRsp->nScansToBatch);
1645
1646 pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE;
1647 complete(&pAdapter->hdd_set_batch_scan_req_var);
1648
1649 return;
1650}/*End of hdd_set_batch_scan_req_callback*/
1651
1652
1653/**---------------------------------------------------------------------------
1654
1655 \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta
1656 info in hdd batch scan response queue
1657
1658 \param - pAdapter Pointer to hdd adapter
1659 \param - pAPMetaInfo Pointer to access point meta info
1660 \param - scanId scan ID of batch scan response
1661 \param - isLastAp tells whether AP is last AP in batch scan response or not
1662
1663 \return - nothing
1664
1665 --------------------------------------------------------------------------*/
1666static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter,
1667 tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp)
1668{
1669 tHddBatchScanRsp *pHead;
1670 tHddBatchScanRsp *pNode;
1671 tHddBatchScanRsp *pPrev;
1672 tHddBatchScanRsp *pTemp;
1673 tANI_U8 ssidLen;
1674
1675 /*head of hdd batch scan response queue*/
1676 pHead = pAdapter->pBatchScanRsp;
1677
1678 pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp));
1679 if (NULL == pNode)
1680 {
1681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1682 "%s: Could not allocate memory", __func__);
1683 VOS_ASSERT(0);
1684 return;
1685 }
1686
1687 vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid,
1688 sizeof(pNode->ApInfo.bssid));
1689 ssidLen = strlen(pApMetaInfo->ssid);
1690 if (SIR_MAX_SSID_SIZE < ssidLen)
1691 {
1692 /*invalid scan result*/
1693 vos_mem_free(pNode);
1694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1695 "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen);
1696 return;
1697 }
1698 vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen);
1699 /*null terminate ssid*/
1700 pNode->ApInfo.ssid[ssidLen] = '\0';
1701 pNode->ApInfo.ch = pApMetaInfo->ch;
1702 pNode->ApInfo.rssi = pApMetaInfo->rssi;
1703 pNode->ApInfo.age = pApMetaInfo->timestamp;
1704 pNode->ApInfo.batchId = scanId;
1705 pNode->ApInfo.isLastAp = isLastAp;
1706
1707 pNode->pNext = NULL;
1708 if (NULL == pHead)
1709 {
1710 pAdapter->pBatchScanRsp = pNode;
1711 }
1712 else
1713 {
1714 pTemp = pHead;
1715 while (NULL != pTemp)
1716 {
1717 pPrev = pTemp;
1718 pTemp = pTemp->pNext;
1719 }
1720 pPrev->pNext = pNode;
1721 }
1722
1723 return;
1724}/*End of hdd_populate_batch_scan_rsp_queue*/
1725
1726/**---------------------------------------------------------------------------
1727
1728 \brief hdd_batch_scan_result_ind_callback () - This function is called after
1729 receiving batch scan response indication from FW. It saves get batch scan
1730 response data in HDD batch scan response queue. This callback sets the
1731 completion event on which hdd_ioctl is waiting only after getting complete
1732 batch scan response data from FW
1733
1734 \param - callbackContext Pointer to HDD adapter
1735 \param - pRsp Pointer to get batch scan response data received from FW
1736
1737 \return - nothing
1738
1739 --------------------------------------------------------------------------*/
1740static void hdd_batch_scan_result_ind_callback
1741(
1742 void *callbackContext,
1743 void *pRsp
1744)
1745{
1746 v_BOOL_t isLastAp;
1747 tANI_U32 numApMetaInfo;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001748 tANI_U32 numNetworkInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301749 tANI_U32 numberScanList;
1750 tANI_U32 nextScanListOffset;
1751 tANI_U32 nextApMetaInfoOffset;
1752 hdd_adapter_t* pAdapter;
1753 tpSirBatchScanList pScanList;
1754 tpSirBatchScanNetworkInfo pApMetaInfo;
1755 tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/
1756 tSirSetBatchScanReq *pReq;
1757
1758 pAdapter = (hdd_adapter_t *)callbackContext;
1759 /*sanity check*/
Rajeev Kumar5286bb92013-12-05 11:52:10 -08001760 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
Rajeev79dbe4c2013-10-05 11:03:42 +05301761 {
1762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1763 "%s: Invalid pAdapter magic", __func__);
1764 VOS_ASSERT(0);
1765 return;
1766 }
1767
1768 /*initialize locals*/
1769 pReq = &pAdapter->hddSetBatchScanReq;
1770 pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp;
1771 isLastAp = FALSE;
1772 numApMetaInfo = 0;
Rajeev Kumarce651e42013-10-21 18:57:15 -07001773 numNetworkInScanList = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05301774 numberScanList = 0;
1775 nextScanListOffset = 0;
1776 nextApMetaInfoOffset = 0;
1777 pScanList = NULL;
1778 pApMetaInfo = NULL;
1779
1780 if ((NULL == pBatchScanRsp) || (NULL == pReq))
1781 {
1782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001783 "%s: pBatchScanRsp is %pK pReq %pK", __func__, pBatchScanRsp, pReq);
Rajeev79dbe4c2013-10-05 11:03:42 +05301784 isLastAp = TRUE;
1785 goto done;
1786 }
1787
1788 pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists;
1789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1790 "Batch scan rsp: numberScalList %d", numberScanList);
1791
1792 if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch))
1793 {
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1795 "%s: numberScanList %d", __func__, numberScanList);
1796 isLastAp = TRUE;
1797 goto done;
1798 }
1799
1800 while (numberScanList)
1801 {
Rajeev Kumarce651e42013-10-21 18:57:15 -07001802 pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults +
Rajeev79dbe4c2013-10-05 11:03:42 +05301803 nextScanListOffset);
1804 if (NULL == pScanList)
1805 {
1806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001807 "%s: pScanList is %pK", __func__, pScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05301808 isLastAp = TRUE;
1809 goto done;
1810 }
Rajeev Kumarce651e42013-10-21 18:57:15 -07001811 numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList;
Rajeev79dbe4c2013-10-05 11:03:42 +05301812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumarce651e42013-10-21 18:57:15 -07001813 "Batch scan rsp: numApMetaInfo %d scanId %d",
1814 numApMetaInfo, pScanList->scanId);
Rajeev79dbe4c2013-10-05 11:03:42 +05301815
1816 if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork))
1817 {
1818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1819 "%s: numApMetaInfo %d", __func__, numApMetaInfo);
1820 isLastAp = TRUE;
1821 goto done;
1822 }
1823
Rajeev Kumarce651e42013-10-21 18:57:15 -07001824 /*Initialize next AP meta info offset for next scan list*/
1825 nextApMetaInfoOffset = 0;
1826
Rajeev79dbe4c2013-10-05 11:03:42 +05301827 while (numApMetaInfo)
1828 {
1829 pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList +
1830 nextApMetaInfoOffset);
1831 if (NULL == pApMetaInfo)
1832 {
1833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -07001834 "%s: pApMetaInfo is %pK", __func__, pApMetaInfo);
Rajeev79dbe4c2013-10-05 11:03:42 +05301835 isLastAp = TRUE;
1836 goto done;
1837 }
1838 /*calculate AP age*/
1839 pApMetaInfo->timestamp =
1840 pBatchScanRsp->timestamp - pApMetaInfo->timestamp;
1841
1842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
Arif Hussaina7c8e412013-11-20 11:06:42 -08001843 "%s: bssId "MAC_ADDRESS_STR
1844 " ch %d rssi %d timestamp %d", __func__,
1845 MAC_ADDR_ARRAY(pApMetaInfo->bssid),
1846 pApMetaInfo->ch, pApMetaInfo->rssi,
1847 pApMetaInfo->timestamp);
Rajeev79dbe4c2013-10-05 11:03:42 +05301848
1849 /*mark last AP in batch scan response*/
1850 if ((TRUE == pBatchScanRsp->isLastResult) &&
1851 (1 == numberScanList) && (1 == numApMetaInfo))
1852 {
1853 isLastAp = TRUE;
1854 }
1855
1856 mutex_lock(&pAdapter->hdd_batch_scan_lock);
1857 /*store batch scan repsonse in hdd queue*/
1858 hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo,
1859 pScanList->scanId, isLastAp);
1860 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
1861
1862 nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo);
1863 numApMetaInfo--;
1864 }
1865
Rajeev Kumarce651e42013-10-21 18:57:15 -07001866 nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8))
1867 + (sizeof(tSirBatchScanNetworkInfo)
1868 * numNetworkInScanList));
Rajeev79dbe4c2013-10-05 11:03:42 +05301869 numberScanList--;
1870 }
1871
1872done:
1873
1874 /*notify hdd_ioctl only if complete batch scan rsp is received and it was
1875 requested from hdd_ioctl*/
1876 if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) &&
1877 (TRUE == isLastAp))
1878 {
1879 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
1880 complete(&pAdapter->hdd_get_batch_scan_req_var);
1881 }
1882
1883 return;
1884}/*End of hdd_batch_scan_result_ind_callback*/
1885
1886/**---------------------------------------------------------------------------
1887
1888 \brief hdd_format_batch_scan_rsp () - This function formats batch scan
1889 response as per batch scan FR request format by putting proper markers
1890
1891 \param - pDest pointer to destination buffer
1892 \param - cur_len current length
1893 \param - tot_len total remaining size which can be written to user space
1894 \param - pApMetaInfo Pointer to get batch scan response AP meta info
1895 \param - pAdapter Pointer to HDD adapter
1896
1897 \return - ret no of characters written
1898
1899 --------------------------------------------------------------------------*/
1900static tANI_U32
1901hdd_format_batch_scan_rsp
1902(
1903 tANI_U8 *pDest,
1904 tANI_U32 cur_len,
1905 tANI_U32 tot_len,
1906 tHddBatchScanRsp *pApMetaInfo,
1907 hdd_adapter_t* pAdapter
1908)
1909{
1910 tANI_U32 ret = 0;
1911 tANI_U32 rem_len = 0;
1912 tANI_U8 temp_len = 0;
1913 tANI_U8 temp_total_len = 0;
1914 tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE];
1915 tANI_U8 *pTemp = temp;
1916
1917 /*Batch scan reponse needs to be returned to user space in
1918 following format:
1919 "scancount=X\n" where X is the number of scans in current batch
1920 batch
1921 "trunc\n" optional present if current scan truncated
1922 "bssid=XX:XX:XX:XX:XX:XX\n"
1923 "ssid=XXXX\n"
1924 "freq=X\n" frequency in Mhz
1925 "level=XX\n"
1926 "age=X\n" ms
1927 "dist=X\n" cm (-1 if not available)
1928 "errror=X\n" (-1if not available)
1929 "====\n" (end of ap marker)
1930 "####\n" (end of scan marker)
1931 "----\n" (end of results)*/
1932 /*send scan result in above format to user space based on
1933 available length*/
1934 /*The GET response may have more data than the driver can return in its
1935 buffer. In that case the buffer should be filled to the nearest complete
1936 scan, ending with "%%%%".Subsequent callsshould return the remaining data
1937 starting with the next scan (optional .trunc\n., .apcount=X\n., etc).
1938 The final buffer should end with "----\n"*/
1939
1940 /*sanity*/
1941 if (cur_len > tot_len)
1942 {
1943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1944 "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len);
1945 return 0;
1946 }
1947 else
1948 {
1949 rem_len = (tot_len - cur_len);
1950 }
1951
1952 /*end scan marker*/
1953 if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id)
1954 {
1955 temp_len = snprintf(pTemp, sizeof(temp), "####\n");
1956 pTemp += temp_len;
1957 temp_total_len += temp_len;
1958 }
1959
1960 /*bssid*/
1961 temp_len = snprintf(pTemp, sizeof(temp),
1962 "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
1963 pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1],
1964 pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3],
1965 pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]);
1966 pTemp += temp_len;
1967 temp_total_len += temp_len;
1968
1969 /*ssid*/
1970 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n",
1971 pApMetaInfo->ApInfo.ssid);
1972 pTemp += temp_len;
1973 temp_total_len += temp_len;
1974
1975 /*freq*/
1976 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n",
Rajeev Kumarc40f7512013-11-04 14:13:23 -08001977 sme_ChnToFreq(pApMetaInfo->ApInfo.ch));
Rajeev79dbe4c2013-10-05 11:03:42 +05301978 pTemp += temp_len;
1979 temp_total_len += temp_len;
1980
1981 /*level*/
1982 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n",
1983 pApMetaInfo->ApInfo.rssi);
1984 pTemp += temp_len;
1985 temp_total_len += temp_len;
1986
1987 /*age*/
Jeff Johnson02797792013-10-26 19:17:13 -07001988 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n",
Rajeev79dbe4c2013-10-05 11:03:42 +05301989 pApMetaInfo->ApInfo.age);
1990 pTemp += temp_len;
1991 temp_total_len += temp_len;
1992
1993 /*dist*/
1994 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n");
1995 pTemp += temp_len;
1996 temp_total_len += temp_len;
1997
1998 /*error*/
1999 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n");
2000 pTemp += temp_len;
2001 temp_total_len += temp_len;
2002
2003 /*end AP marker*/
2004 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n");
2005 pTemp += temp_len;
2006 temp_total_len += temp_len;
2007
2008 /*last AP in batch scan response*/
2009 if(TRUE == pApMetaInfo->ApInfo.isLastAp)
2010 {
2011 /*end scan marker*/
2012 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n");
2013 pTemp += temp_len;
2014 temp_total_len += temp_len;
2015
2016 /*end batch scan result marker*/
2017 temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n");
2018 pTemp += temp_len;
2019 temp_total_len += temp_len;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002020
Rajeev79dbe4c2013-10-05 11:03:42 +05302021 }
2022
2023 if (temp_total_len < rem_len)
2024 {
2025 ret = temp_total_len + 1;
2026 strlcpy(pDest, temp, ret);
2027 pAdapter->isTruncated = FALSE;
2028 }
2029 else
2030 {
2031 pAdapter->isTruncated = TRUE;
2032 if (rem_len >= strlen("%%%%"))
2033 {
Rajeev Kumarc933d982013-11-18 20:04:20 -08002034 ret = snprintf(pDest, sizeof(temp), "%%%%");
Rajeev79dbe4c2013-10-05 11:03:42 +05302035 }
Rajeev Kumarc933d982013-11-18 20:04:20 -08002036 else
Rajeev79dbe4c2013-10-05 11:03:42 +05302037 {
2038 ret = 0;
2039 }
2040 }
2041
2042 return ret;
2043
2044}/*End of hdd_format_batch_scan_rsp*/
2045
2046/**---------------------------------------------------------------------------
2047
2048 \brief hdd_populate_user_batch_scan_rsp() - This function populates user data
2049 buffer starting with head of hdd batch scan response queue
2050
2051 \param - pAdapter Pointer to HDD adapter
2052 \param - pDest Pointer to user data buffer
2053 \param - cur_len current offset in user buffer
2054 \param - rem_len remaining no of bytes in user buffer
2055
2056 \return - number of bytes written in user buffer
2057
2058 --------------------------------------------------------------------------*/
2059
2060tANI_U32 hdd_populate_user_batch_scan_rsp
2061(
2062 hdd_adapter_t* pAdapter,
2063 tANI_U8 *pDest,
2064 tANI_U32 cur_len,
2065 tANI_U32 rem_len
2066)
2067{
2068 tHddBatchScanRsp *pHead;
2069 tHddBatchScanRsp *pPrev;
2070 tANI_U32 len;
2071
Rajeev79dbe4c2013-10-05 11:03:42 +05302072 pAdapter->isTruncated = FALSE;
2073
2074 /*head of hdd batch scan response queue*/
2075 pHead = pAdapter->pBatchScanRsp;
2076 while (pHead)
2077 {
2078 len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead,
2079 pAdapter);
2080 pDest += len;
Rajeev Kumar292d2bb2013-10-23 15:01:44 -07002081 pDest--;
Rajeev79dbe4c2013-10-05 11:03:42 +05302082 cur_len += len;
2083 if(TRUE == pAdapter->isTruncated)
2084 {
2085 /*result is truncated return rest of scan rsp in next req*/
2086 cur_len = rem_len;
2087 break;
2088 }
2089 pPrev = pHead;
2090 pHead = pHead->pNext;
2091 pAdapter->pBatchScanRsp = pHead;
Rajeev Kumarbe17d8b2014-01-10 15:39:45 -08002092 if (TRUE == pPrev->ApInfo.isLastAp)
2093 {
2094 pAdapter->prev_batch_id = 0;
2095 }
2096 else
2097 {
2098 pAdapter->prev_batch_id = pPrev->ApInfo.batchId;
2099 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302100 vos_mem_free(pPrev);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08002101 pPrev = NULL;
Rajeev79dbe4c2013-10-05 11:03:42 +05302102 }
2103
2104 return cur_len;
2105}/*End of hdd_populate_user_batch_scan_rsp*/
2106
2107/**---------------------------------------------------------------------------
2108
2109 \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch
2110 scan response data from HDD queue to user space
2111 It does following in detail:
2112 a) if HDD has enough data in its queue then it 1st copies data to user
2113 space and then send get batch scan indication message to FW. In this
2114 case it does not wait on any event and batch scan response data will
2115 be populated in HDD response queue in MC thread context after receiving
2116 indication from FW
2117 b) else send get batch scan indication message to FW and wait on an event
2118 which will be set once HDD receives complete batch scan response from
2119 FW and then this function returns batch scan response to user space
2120
2121 \param - pAdapter Pointer to HDD adapter
2122 \param - pPrivData Pointer to priv_data
2123
2124 \return - 0 for success -EFAULT for failure
2125
2126 --------------------------------------------------------------------------*/
2127
2128int hdd_return_batch_scan_rsp_to_user
2129(
2130 hdd_adapter_t* pAdapter,
2131 hdd_priv_data_t *pPrivData,
2132 tANI_U8 *command
2133)
2134{
2135 tANI_U8 *pDest;
2136 tANI_U32 count = 0;
2137 tANI_U32 len = 0;
2138 tANI_U32 cur_len = 0;
2139 tANI_U32 rem_len = 0;
2140 eHalStatus halStatus;
2141 unsigned long rc;
2142 tSirTriggerBatchScanResultInd *pReq;
2143
2144 pReq = &pAdapter->hddTriggerBatchScanResultInd;
2145 pReq->param = 0;/*batch scan client*/
2146 pDest = (tANI_U8 *)(command + pPrivData->used_len);
2147 pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE;
2148
2149 cur_len = pPrivData->used_len;
2150 if (pPrivData->total_len > pPrivData->used_len)
2151 {
2152 rem_len = pPrivData->total_len - pPrivData->used_len;
2153 }
2154 else
2155 {
2156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2157 "%s: Invalid user data buffer total_len %d used_len %d",
2158 __func__, pPrivData->total_len, pPrivData->used_len);
2159 return -EFAULT;
2160 }
2161
2162 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2163 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2164 cur_len, rem_len);
2165 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2166
2167 /*enough scan result available in cache to return to user space or
2168 scan result needs to be fetched 1st from fw and then return*/
Rajeev Kumar99db6262013-11-11 15:23:36 -08002169 if (len == cur_len)
Rajeev79dbe4c2013-10-05 11:03:42 +05302170 {
2171 pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE;
2172 halStatus = sme_TriggerBatchScanResultInd(
2173 WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2174 pAdapter->sessionId, hdd_batch_scan_result_ind_callback,
2175 pAdapter);
2176 if ( eHAL_STATUS_SUCCESS == halStatus )
2177 {
2178 if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp)
2179 {
2180 INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var);
2181 rc = wait_for_completion_timeout(
2182 &pAdapter->hdd_get_batch_scan_req_var,
2183 msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT));
Abhishek Singh00b71972016-01-07 10:51:04 +05302184 if (0 >= rc)
Rajeev79dbe4c2013-10-05 11:03:42 +05302185 {
2186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Abhishek Singh00b71972016-01-07 10:51:04 +05302187 "%s: wait on hdd_get_batch_scan_req_var failed %ld",
2188 __func__, rc);
Rajeev79dbe4c2013-10-05 11:03:42 +05302189 return -EFAULT;
2190 }
2191 }
2192
2193 len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE,
Jeff Johnson02797792013-10-26 19:17:13 -07002194 "scancount=%u\n", pAdapter->numScanList);
Rajeev79dbe4c2013-10-05 11:03:42 +05302195 pDest += len;
2196 cur_len += len;
2197
2198 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2199 len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest,
2200 cur_len, rem_len);
2201 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2202
2203 count = 0;
2204 len = (len - pPrivData->used_len);
2205 pDest = (command + pPrivData->used_len);
2206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002207 "NEW BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302208 while(count < len)
2209 {
2210 printk("%c", *(pDest + count));
2211 count++;
2212 }
2213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2214 "%s: copy %d data to user buffer", __func__, len);
2215 if (copy_to_user(pPrivData->buf, pDest, len))
2216 {
2217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2218 "%s: failed to copy data to user buffer", __func__);
2219 return -EFAULT;
2220 }
2221 }
2222 else
2223 {
2224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2225 "sme_GetBatchScanScan returned failure halStatus %d",
2226 halStatus);
2227 return -EINVAL;
2228 }
2229 }
2230 else
2231 {
Rajeev79dbe4c2013-10-05 11:03:42 +05302232 count = 0;
2233 len = (len - pPrivData->used_len);
2234 pDest = (command + pPrivData->used_len);
2235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Rajeev Kumar99db6262013-11-11 15:23:36 -08002236 "REMAINING TRUNCATED BATCH SCAN RESULT:");
Rajeev79dbe4c2013-10-05 11:03:42 +05302237 while(count < len)
2238 {
2239 printk("%c", *(pDest + count));
2240 count++;
2241 }
Rajeev Kumar99db6262013-11-11 15:23:36 -08002242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2243 "%s: copy %d data to user buffer", __func__, len);
Rajeev79dbe4c2013-10-05 11:03:42 +05302244 if (copy_to_user(pPrivData->buf, pDest, len))
2245 {
2246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2247 "%s: failed to copy data to user buffer", __func__);
2248 return -EFAULT;
2249 }
Rajeev79dbe4c2013-10-05 11:03:42 +05302250 }
2251
2252 return 0;
2253} /*End of hdd_return_batch_scan_rsp_to_user*/
2254
Rajeev Kumar8b373292014-01-08 20:36:55 -08002255/**---------------------------------------------------------------------------
2256
2257 \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING
2258 IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled:
2259 WLS_BATCHING VERSION
2260 WLS_BATCHING SET
2261 WLS_BATCHING GET
2262 WLS_BATCHING STOP
2263
2264 \param - pAdapter Pointer to HDD adapter
2265 \param - pPrivdata Pointer to priv_data
2266 \param - command Pointer to command
2267
2268 \return - 0 for success -EFAULT for failure
2269
2270 --------------------------------------------------------------------------*/
2271
2272int hdd_handle_batch_scan_ioctl
2273(
2274 hdd_adapter_t *pAdapter,
2275 hdd_priv_data_t *pPrivdata,
2276 tANI_U8 *command
2277)
2278{
2279 int ret = 0;
Yue Mae36e3552014-03-05 17:06:20 -08002280 hdd_context_t *pHddCtx;
2281
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302282 ENTER();
2283
Yue Mae36e3552014-03-05 17:06:20 -08002284 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2285 ret = wlan_hdd_validate_context(pHddCtx);
2286 if (ret)
2287 {
Yue Mae36e3552014-03-05 17:06:20 -08002288 goto exit;
2289 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002290
2291 if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0)
2292 {
2293 char extra[32];
2294 tANI_U8 len = 0;
2295 tANI_U8 version = HDD_BATCH_SCAN_VERSION;
2296
2297 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2298 {
2299 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2300 "%s: Batch scan feature is not supported by FW", __func__);
2301 ret = -EINVAL;
2302 goto exit;
2303 }
2304
2305 len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d",
2306 version);
2307 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2308 {
2309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2310 "%s: failed to copy data to user buffer", __func__);
2311 ret = -EFAULT;
2312 goto exit;
2313 }
2314 ret = HDD_BATCH_SCAN_VERSION;
2315 }
2316 else if (strncmp(command, "WLS_BATCHING SET", 16) == 0)
2317 {
2318 int status;
2319 tANI_U8 *value = (command + 16);
2320 eHalStatus halStatus;
2321 unsigned long rc;
2322 tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq;
2323 tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp;
2324
2325 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2326 {
2327 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2328 "%s: Batch scan feature is not supported by FW", __func__);
2329 ret = -EINVAL;
2330 goto exit;
2331 }
2332
2333 if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) &&
2334 (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) &&
2335 (WLAN_HDD_P2P_GO != pAdapter->device_mode) &&
2336 (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode))
2337 {
2338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302339 "Received WLS_BATCHING SET command in invalid mode %s (%d) "
Rajeev Kumar8b373292014-01-08 20:36:55 -08002340 "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode",
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302341 hdd_device_modetoString(pAdapter->device_mode),
2342 pAdapter->device_mode);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002343 ret = -EINVAL;
2344 goto exit;
2345 }
2346
2347 status = hdd_parse_set_batchscan_command(value, pReq);
2348 if (status)
2349 {
2350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2351 "Invalid WLS_BATCHING SET command");
2352 ret = -EINVAL;
2353 goto exit;
2354 }
2355
2356
2357 pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE;
2358 halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq,
2359 pAdapter->sessionId, hdd_set_batch_scan_req_callback,
2360 pAdapter);
2361
2362 if ( eHAL_STATUS_SUCCESS == halStatus )
2363 {
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302364 char extra[32];
2365 tANI_U8 len = 0;
2366 tANI_U8 mScan = 0;
2367
Rajeev Kumar8b373292014-01-08 20:36:55 -08002368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2369 "sme_SetBatchScanReq returned success halStatus %d",
2370 halStatus);
2371 if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp)
2372 {
2373 INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var);
2374 rc = wait_for_completion_timeout(
2375 &pAdapter->hdd_set_batch_scan_req_var,
2376 msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT));
2377 if (0 == rc)
2378 {
2379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2380 "%s: Timeout waiting for set batch scan to complete",
2381 __func__);
2382 ret = -EINVAL;
2383 goto exit;
2384 }
2385 }
2386 if ( !pRsp->nScansToBatch )
2387 {
2388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2389 "%s: Received set batch scan failure response from FW",
2390 __func__);
2391 ret = -EINVAL;
2392 goto exit;
2393 }
2394 /*As per the Batch Scan Framework API we should return the MIN of
2395 either MSCAN or the max # of scans firmware can cache*/
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302396 mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch);
Rajeev Kumar8b373292014-01-08 20:36:55 -08002397
2398 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED;
2399
2400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2401 "%s: request MSCAN %d response MSCAN %d ret %d",
Mahesh A Saptasagar5f568172014-05-14 17:02:33 +05302402 __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan);
2403 len = scnprintf(extra, sizeof(extra), "%d", mScan);
2404 if (copy_to_user(pPrivdata->buf, &extra, len + 1))
2405 {
2406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2407 "%s: failed to copy MSCAN value to user buffer", __func__);
2408 ret = -EFAULT;
2409 goto exit;
2410 }
Rajeev Kumar8b373292014-01-08 20:36:55 -08002411 }
2412 else
2413 {
2414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2415 "sme_SetBatchScanReq returned failure halStatus %d",
2416 halStatus);
2417 ret = -EINVAL;
2418 goto exit;
2419 }
2420 }
2421 else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0)
2422 {
2423 eHalStatus halStatus;
2424 tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd;
2425 pInd->param = 0;
2426
2427 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2428 {
2429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2430 "%s: Batch scan feature is not supported by FW", __func__);
2431 ret = -EINVAL;
2432 goto exit;
2433 }
2434
2435 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2436 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002438 "Batch scan is not yet enabled batch scan state %d",
2439 pAdapter->batchScanState);
2440 ret = -EINVAL;
2441 goto exit;
2442 }
2443
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002444 mutex_lock(&pAdapter->hdd_batch_scan_lock);
2445 hdd_deinit_batch_scan(pAdapter);
2446 mutex_unlock(&pAdapter->hdd_batch_scan_lock);
2447
Rajeev Kumar8b373292014-01-08 20:36:55 -08002448 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
2449
2450 halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd,
2451 pAdapter->sessionId);
2452 if ( eHAL_STATUS_SUCCESS == halStatus )
2453 {
2454 ret = 0;
2455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2456 "sme_StopBatchScanInd returned success halStatus %d",
2457 halStatus);
2458 }
2459 else
2460 {
2461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2462 "sme_StopBatchScanInd returned failure halStatus %d",
2463 halStatus);
2464 ret = -EINVAL;
2465 goto exit;
2466 }
2467 }
2468 else if (strncmp(command, "WLS_BATCHING GET", 16) == 0)
2469 {
2470 tANI_U32 remain_len;
2471
2472 if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN))
2473 {
2474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2475 "%s: Batch scan feature is not supported by FW", __func__);
2476 ret = -EINVAL;
2477 goto exit;
2478 }
2479
2480 if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState)
2481 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05302482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Rajeev Kumar8b373292014-01-08 20:36:55 -08002483 "Batch scan is not yet enabled could not return results"
2484 "Batch Scan state %d",
2485 pAdapter->batchScanState);
2486 ret = -EINVAL;
2487 goto exit;
2488 }
2489
2490 pPrivdata->used_len = 16;
2491 remain_len = pPrivdata->total_len - pPrivdata->used_len;
2492 if (remain_len < pPrivdata->total_len)
2493 {
2494 /*Clear previous batch scan response data if any*/
2495 vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len);
2496 }
2497 else
2498 {
2499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2500 "Invalid total length from user space can't fetch batch"
2501 " scan response total_len %d used_len %d remain len %d",
2502 pPrivdata->total_len, pPrivdata->used_len, remain_len);
2503 ret = -EINVAL;
2504 goto exit;
2505 }
2506 ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command);
2507 }
2508
2509exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302510 EXIT();
Rajeev Kumar8b373292014-01-08 20:36:55 -08002511 return ret;
2512}
2513
2514
Rajeev79dbe4c2013-10-05 11:03:42 +05302515#endif/*End of FEATURE_WLAN_BATCH_SCAN*/
2516
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302517#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
2518/**
2519 * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC
2520 * to Handoff request
2521 * @handoffInfo: Pointer to Handoff request
2522 * @src: enum of handoff_src
2523 * Return: None
2524 */
2525#ifndef QCA_WIFI_ISOC
2526static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2527 *handoffInfo, handoff_src src)
2528{
2529 handoffInfo->src = src;
2530}
2531#else
2532static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest
2533 *handoffInfo, handoff_src src)
2534{
2535}
2536#endif
2537
2538/**
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302539 * hdd_reassoc() - perform a user space-directed reassoc
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302540 *
2541 * @pAdapter: Adapter upon which the command was received
2542 * @bssid: BSSID with which to reassociate
2543 * @channel: channel upon which to reassociate
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302544 * @src: The source for the trigger of this action
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302545 *
2546 * Return: 0 for success non-zero for failure
2547 */
2548#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302549int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302550 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302551{
2552 hdd_station_ctx_t *pHddStaCtx;
2553 tCsrHandoffRequest handoffInfo;
2554 hdd_context_t *pHddCtx = NULL;
2555 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2556
2557 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2558
2559 /* if not associated, no need to proceed with reassoc */
2560 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
2561 hddLog(LOG1, FL("Not associated"));
2562 return -EINVAL;
2563 }
2564
2565 /* if the target bssid is same as currently associated AP,
2566 then no need to proceed with reassoc */
2567 if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) {
2568 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
2569 return -EINVAL;
2570 }
2571
2572 /* Check channel number is a valid channel number */
2573 if (VOS_STATUS_SUCCESS !=
2574 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
2575 hddLog(LOGE, FL("Invalid Channel %d"), channel);
2576 return -EINVAL;
2577 }
2578
2579 /* Proceed with reassoc */
2580 handoffInfo.channel = channel;
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302581 hdd_assign_handoff_src_reassoc(&handoffInfo, src);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302582 memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr));
2583 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
2584 return 0;
2585}
2586#else
Selvaraj, Sridhar8ecb4192016-06-23 17:50:49 +05302587int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302588 const tANI_U8 channel, const handoff_src src)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302589{
2590 return -EPERM;
2591}
2592#endif
2593
2594/**
2595 * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command
2596 * This function parses the v1 REASSOC command with the format
2597 * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the
2598 * Hex-ASCII representation of the BSSID and CH is the ASCII
2599 * representation of the channel. For example
2600 * REASSOC 00:0a:0b:11:22:33 48
2601 *
2602 * @pAdapter: Adapter upon which the command was received
2603 * @command: ASCII text command that was received
2604 *
2605 * Return: 0 for success non-zero for failure
2606 */
2607static int
2608hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command)
2609{
2610 tANI_U8 channel = 0;
2611 tSirMacAddr bssid;
2612 int ret;
2613
2614 ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel);
2615 if (ret)
2616 hddLog(LOGE, FL("Failed to parse reassoc command data"));
2617 else
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302618 ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302619
2620 return ret;
2621}
2622
2623/**
2624 * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command
2625 * This function parses the v2 REASSOC command with the format
2626 * REASSOC <android_wifi_reassoc_params>
2627 *
2628 * @pAdapter: Adapter upon which the command was received
2629 * @command: command that was received, ASCII command followed
2630 * by binary data
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302631 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302632 *
2633 * Return: 0 for success non-zero for failure
2634 */
2635static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302636hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command,
2637 int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302638{
2639 struct android_wifi_reassoc_params params;
2640 tSirMacAddr bssid;
2641 int ret;
2642
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302643 if (total_len < sizeof(params) + 8) {
2644 hddLog(LOGE, FL("Invalid command length"));
2645 return -EINVAL;
2646 }
2647
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302648 /* The params are located after "REASSOC " */
2649 memcpy(&params, command + 8, sizeof(params));
2650
2651 if (!mac_pton(params.bssid, (u8 *)&bssid)) {
2652 hddLog(LOGE, FL("MAC address parsing failed"));
2653 ret = -EINVAL;
2654 } else {
Selvaraj, Sridhar4fa15232016-06-18 12:27:25 +05302655 ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302656 }
2657 return ret;
2658}
2659
2660/**
2661 * hdd_parse_reassoc() - parse the REASSOC command
2662 * There are two different versions of the REASSOC command.Version 1
2663 * of the command contains a parameter list that is ASCII characters
2664 * whereas version 2 contains a combination of ASCII and binary
2665 * payload. Determine if a version 1 or a version 2 command is being
2666 * parsed by examining the parameters, and then dispatch the parser
2667 * that is appropriate for the command.
2668 *
2669 * @pAdapter: Adapter upon which the command was received
2670 * @command: command that was received
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302671 * @total_len: Total length of the command received
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302672 *
2673 * Return: 0 for success non-zero for failure
2674 */
2675static int
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302676hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len)
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302677{
2678 int ret;
2679
2680 /*
2681 * both versions start with "REASSOC"
2682 * v1 has a bssid and channel # as an ASCII string
2683 * REASSOC xx:xx:xx:xx:xx:xx CH
2684 * v2 has a C struct
2685 * REASSOC <binary c struct>
2686 *
2687 * The first field in the v2 struct is also the bssid in ASCII.
2688 * But in the case of a v2 message the BSSID is NUL-terminated.
2689 * Hence we can peek at that offset to see if this is V1 or V2
2690 * REASSOC xx:xx:xx:xx:xx:xx*
2691 * 1111111111222222
2692 * 01234567890123456789012345
2693 */
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302694
2695 if (total_len < 26) {
2696 hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len);
2697 return -EINVAL;
2698 }
2699
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302700 if (command[25])
2701 ret = hdd_parse_reassoc_v1(pAdapter, command);
2702 else
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302703 ret = hdd_parse_reassoc_v2(pAdapter, command, total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05302704
2705 return ret;
2706}
2707#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */
2708
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302709struct bcn_miss_rate_priv {
2710 int bcn_miss_rate;
2711};
2712
2713/**
2714 * get_bcn_miss_rate_cb() callback invoked on receiving beacon miss
2715 * rate from firmware
2716 * @status: Status of get beacon miss rate operation
2717 * @bcnMissRate: Beacon miss rate
2718 * @context: Context passed while registering callback
2719 *
2720 * This function is invoked by WDA layer on receiving
2721 * WDI_GET_BCN_MISS_RATE_RSP
2722 *
2723 * Return: None
2724 */
2725static void get_bcn_miss_rate_cb(VOS_STATUS status, int bcnMissRate,
2726 void *context)
c_hpothu92367912014-05-01 15:18:17 +05302727{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302728 struct hdd_request *request;
2729 struct bcn_miss_rate_priv *priv;
c_hpothu39eb1e32014-06-26 16:31:50 +05302730
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302731 request = hdd_request_get(context);
2732 if (!request) {
2733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2734 return;
2735 }
c_hpothu92367912014-05-01 15:18:17 +05302736
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302737 priv = hdd_request_priv(request);
c_hpothu92367912014-05-01 15:18:17 +05302738
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302739 if (VOS_STATUS_SUCCESS == status)
2740 priv->bcn_miss_rate = bcnMissRate;
2741 else
2742 hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate"));
c_hpothu92367912014-05-01 15:18:17 +05302743
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302744 hdd_request_complete(request);
2745 hdd_request_put(request);
Hanumanth Reddy Pothulad0d3c172018-05-02 18:53:05 +05302746
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302747 return;
c_hpothu92367912014-05-01 15:18:17 +05302748}
2749
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302750struct fw_stats_priv {
2751 tSirFwStatsResult *fw_stats;
2752};
2753
2754/**
2755 * hdd_fw_stats_cb() callback invoked on receiving firmware stats
2756 * from firmware
2757 * @status: Status of get firmware stats operation
2758 * @fwStatsResult: firmware stats
2759 * @context: Context passed while registering callback
2760 *
2761 * This function is invoked by WDA layer on receiving
2762 * WDI_GET_FW_STATS_RSP
2763 *
2764 * Return: None
2765 */
2766static void hdd_fw_stats_cb(VOS_STATUS status,
2767 tSirFwStatsResult *fwStatsResult, void *context)
Satyanarayana Dash72806012014-12-02 14:30:08 +05302768{
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302769 struct hdd_request *request;
2770 struct fw_stats_priv *priv;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302771
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302772 hddLog(VOS_TRACE_LEVEL_INFO, FL("with status = %d"),status);
Satyanarayana Dash72806012014-12-02 14:30:08 +05302773
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05302774 request = hdd_request_get(context);
2775 if (!request) {
2776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
2777 return;
2778 }
2779 priv = hdd_request_priv(request);
2780
2781 if (VOS_STATUS_SUCCESS == status)
2782 *priv->fw_stats = *fwStatsResult;
2783 else
2784 priv->fw_stats = NULL;
2785
2786 hdd_request_complete(request);
2787 hdd_request_put(request);
2788 return;
Satyanarayana Dash72806012014-12-02 14:30:08 +05302789}
2790
jge35567202017-06-21 16:39:38 +08002791/*
2792 *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command
2793 *@pValue Pointer to MAXTXPOWER command
2794 *@pTxPower Pointer to tx power
2795 *
2796 *This function parses the MAXTXPOWER command passed in the format
2797 * MAXTXPOWER<space>X(Tx power in dbm)
2798 * For example input commands:
2799 * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm
2800 * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm
2801 *
2802 *return - 0 for success non-zero for failure
2803 */
2804static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower)
2805{
2806 unsigned char *inPtr = pValue;
2807 int tempInt;
2808 int v = 0;
2809 *pTxPower = 0;
2810
2811 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
2812 /* no argument after the command */
2813 if (NULL == inPtr)
2814 return -EINVAL;
2815 /* no space after the command */
2816 else if (SPACE_ASCII_VALUE != *inPtr)
2817 return -EINVAL;
2818
2819 /* removing empty spaces */
2820 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
2821
2822 /* no argument followed by spaces */
2823 if ('\0' == *inPtr)
2824 return 0;
2825
2826 v = kstrtos32(inPtr, 10, &tempInt);
2827
2828 /* Range checking for passed parameter */
2829 if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER))
2830 return -EINVAL;
2831
2832 *pTxPower = tempInt;
2833
2834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2835 "SETMAXTXPOWER: %d", *pTxPower);
2836
2837 return 0;
2838}
2839
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302840static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len)
2841{
2842 int ret = 0;
2843
2844 if (!pCfg || !command || !extra || !len)
2845 {
2846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2847 "%s: argument passsed for GETDWELLTIME is incorrect", __func__);
2848 ret = -EINVAL;
2849 return ret;
2850 }
2851
2852 if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0)
2853 {
2854 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n",
2855 (int)pCfg->nActiveMaxChnTime);
2856 return ret;
2857 }
2858 else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0)
2859 {
2860 *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n",
2861 (int)pCfg->nActiveMinChnTime);
2862 return ret;
2863 }
2864 else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0)
2865 {
2866 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n",
2867 (int)pCfg->nPassiveMaxChnTime);
2868 return ret;
2869 }
2870 else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0)
2871 {
2872 *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n",
2873 (int)pCfg->nPassiveMinChnTime);
2874 return ret;
2875 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05302876 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
2877 {
2878 *len = scnprintf(extra, n, "GETDWELLTIME %u \n",
2879 (int)pCfg->nActiveMaxChnTime);
2880 return ret;
2881 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05302882 else
2883 {
2884 ret = -EINVAL;
2885 }
2886
2887 return ret;
2888}
2889
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302890/**
2891 * hdd_btc_get_dwell_time() - Get BTC dwell time parameters
2892 * @pCfg: Pointer to HDD context
2893 * @command: ASCII text command that is received
2894 * @extra: Pointer to copy data sent to user
2895 * @n: size of 'extra' buffer
2896 * @len: length copied to 'extra' buffer
2897 *
2898 * Driver commands:
2899 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MAX
2900 * wpa_cli DRIVER BTCGETDWELLTIME ESCO MIN
2901 * wpa_cli DRIVER BTCGETDWELLTIME SCO MAX
2902 * wpa_cli DRIVER BTCGETDWELLTIME SCO MIN
2903 *
2904 * Return: 0 for success non-zero for failure
2905 */
2906
2907static int hdd_btc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2908 char *extra, tANI_U8 n, tANI_U8 *len)
2909{
2910 int ret = 0;
2911
2912 if (!pCfg || !command || !extra || !len)
2913 {
2914 hddLog(LOGE, FL("Argument passsed for BTCGETDWELLTIME is incorrect"));
2915 ret = -EINVAL;
2916 return ret;
2917 }
2918
2919 if (strncmp(command, "BTCGETDWELLTIME ESCO MAX", 24) == 0)
2920 {
2921 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MAX %u\n",
2922 (int)pCfg->max_chntime_btc_esco);
2923 return ret;
2924 }
2925 else if (strncmp(command, "BTCGETDWELLTIME ESCO MIN", 24) == 0)
2926 {
2927 *len = scnprintf(extra, n, "BTCGETDWELLTIME ESCO MIN %u\n",
2928 (int)pCfg->min_chntime_btc_esco);
2929 return ret;
2930 }
2931 else if (strncmp(command, "BTCGETDWELLTIME SCO MAX", 23) == 0)
2932 {
2933 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MAX %u\n",
2934 (int)pCfg->max_chntime_btc_sco);
2935 return ret;
2936 }
2937 else if (strncmp(command, "BTCGETDWELLTIME SCO MIN", 23) == 0)
2938 {
2939 *len = scnprintf(extra, n, "BTCGETDWELLTIME SCO MIN %u\n",
2940 (int)pCfg->min_chntime_btc_sco);
2941 return ret;
2942 }
2943 else
2944 {
2945 ret = -EINVAL;
2946 }
2947
2948 return ret;
2949}
2950
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05302951int hdd_drv_cmd_validate(tANI_U8 *command, int len)
2952{
2953 if (command[len] != ' ')
2954 return -EINVAL;
2955
2956 return 0;
2957}
2958
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05302959#ifdef WLAN_AP_STA_CONCURRENCY
2960
2961/**
2962 * hdd_conc_get_dwell_time() - Get concurrency dwell time parameters
2963 * @pCfg: Pointer to HDD context
2964 * @command: ASCII text command that is received
2965 * @extra: Pointer to copy data sent to user
2966 * @n: size of 'extra' buffer
2967 * @len: length copied to 'extra' buffer
2968 *
2969 * Driver commands:
2970 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MAX
2971 * wpa_cli DRIVER CONCGETDWELLTIME ACTIVE MIN
2972 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MAX
2973 * wpa_cli DRIVER CONCGETDWELLTIME PASSIVE MIN
2974 *
2975 * Return: 0 for success non-zero for failure
2976 */
2977
2978static int hdd_conc_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command,
2979 char *extra, tANI_U8 n, tANI_U8 *len)
2980{
2981 int ret = 0;
2982
2983 if (!pCfg || !command || !extra || !len)
2984 {
2985 hddLog(LOGE, FL("Argument passsed for CONCGETDWELLTIME is incorrect"));
2986 ret = -EINVAL;
2987 return ret;
2988 }
2989
2990 if (strncmp(command, "CONCGETDWELLTIME ACTIVE MAX", 27) == 0)
2991 {
2992 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MAX %u\n",
2993 (int)pCfg->nActiveMaxChnTimeConc);
2994 return ret;
2995 }
2996 else if (strncmp(command, "CONCGETDWELLTIME ACTIVE MIN", 27) == 0)
2997 {
2998 *len = scnprintf(extra, n, "CONCGETDWELLTIME ACTIVE MIN %u\n",
2999 (int)pCfg->nActiveMinChnTimeConc);
3000 return ret;
3001 }
3002 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MAX", 28) == 0)
3003 {
3004 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MAX %u\n",
3005 (int)pCfg->nPassiveMaxChnTimeConc);
3006 return ret;
3007 }
3008 else if (strncmp(command, "CONCGETDWELLTIME PASSIVE MIN", 28) == 0)
3009 {
3010 *len = scnprintf(extra, n, "CONCGETDWELLTIME PASSIVE MIN %u\n",
3011 (int)pCfg->nPassiveMinChnTimeConc);
3012 return ret;
3013 }
3014 else
3015 {
3016 ret = -EINVAL;
3017 }
3018
3019 return ret;
3020}
3021
3022/**
3023 * hdd_conc_set_dwell_time() - Set concurrency dwell time parameters
3024 * @pAdapter: Adapter upon which the command was received
3025 * @command: ASCII text command that is received
3026 *
3027 * Driver commands:
3028 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MAX <value>
3029 * wpa_cli DRIVER CONCSETDWELLTIME ACTIVE MIN <value>
3030 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MAX <value
3031 * wpa_cli DRIVER CONCSETDWELLTIME PASSIVE MIN <value>
3032 *
3033 * Return: 0 for success non-zero for failure
3034 */
3035
3036static int hdd_conc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3037{
3038 tHalHandle hHal;
3039 hdd_config_t *pCfg;
3040 tANI_U8 *value = command;
3041 int val = 0, ret = 0, temp = 0;
3042 tSmeConfigParams smeConfig;
3043
3044 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3045 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3046 {
3047 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME is incorrect"));
3048 ret = -EINVAL;
3049 return ret;
3050 }
3051
3052 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3053 sme_GetConfigParam(hHal, &smeConfig);
3054
3055 if (strncmp(command, "CONCSETDWELLTIME ACTIVE MAX", 27) == 0 )
3056 {
3057 if (hdd_drv_cmd_validate(command, 27)) {
3058 hddLog(LOGE, FL("Invalid driver command"));
3059 return -EINVAL;
3060 }
3061
3062 value = value + 28;
3063 temp = kstrtou32(value, 10, &val);
3064 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3065 val > CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX)
3066 {
3067 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME ACTIVE MAX is incorrect"));
3068 ret = -EFAULT;
3069 return ret;
3070 }
3071 pCfg->nActiveMaxChnTimeConc = val;
3072 smeConfig.csrConfig.nActiveMaxChnTimeConc = val;
3073 sme_UpdateConfig(hHal, &smeConfig);
3074 }
3075 else if (strncmp(command, "CONCSETDWELLTIME ACTIVE MIN", 27) == 0)
3076 {
3077 if (hdd_drv_cmd_validate(command, 27)) {
3078 hddLog(LOGE, FL("Invalid driver command"));
3079 return -EINVAL;
3080 }
3081
3082 value = value + 28;
3083 temp = kstrtou32(value, 10, &val);
3084 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3085 val > CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX)
3086 {
3087 hddLog(LOGE, FL("Argument passsed for CONCSETDWELLTIME ACTIVE MIN is incorrect"));
3088 ret = -EFAULT;
3089 return ret;
3090 }
3091 pCfg->nActiveMinChnTimeConc = val;
3092 smeConfig.csrConfig.nActiveMinChnTimeConc = val;
3093 sme_UpdateConfig(hHal, &smeConfig);
3094 }
3095 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MAX", 28) == 0)
3096 {
3097 if (hdd_drv_cmd_validate(command, 28)) {
3098 hddLog(LOGE, FL("Invalid driver command"));
3099 return -EINVAL;
3100 }
3101
3102 value = value + 29;
3103 temp = kstrtou32(value, 10, &val);
3104 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ||
3105 val > CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX)
3106 {
3107 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MAX is incorrect"));
3108 ret = -EFAULT;
3109 return ret;
3110 }
3111 pCfg->nPassiveMaxChnTimeConc = val;
3112 smeConfig.csrConfig.nPassiveMaxChnTimeConc = val;
3113 sme_UpdateConfig(hHal, &smeConfig);
3114 }
3115 else if (strncmp(command, "CONCSETDWELLTIME PASSIVE MIN", 28) == 0)
3116 {
3117 if (hdd_drv_cmd_validate(command, 28)) {
3118 hddLog(LOGE, FL("Invalid driver command"));
3119 return -EINVAL;
3120 }
3121
3122 value = value + 29;
3123 temp = kstrtou32(value, 10, &val);
3124 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ||
3125 val > CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX )
3126 {
3127 hddLog(LOGE, FL("Argument passed for CONCSETDWELLTIME PASSIVE MIN is incorrect"));
3128 ret = -EFAULT;
3129 return ret;
3130 }
3131 pCfg->nPassiveMinChnTimeConc = val;
3132 smeConfig.csrConfig.nPassiveMinChnTimeConc = val;
3133 sme_UpdateConfig(hHal, &smeConfig);
3134 }
3135 else
3136 {
3137 ret = -EINVAL;
3138 }
3139
3140 return ret;
3141}
3142
3143#endif
3144
3145/**
3146 * hdd_btc_set_dwell_time() - Set BTC dwell time parameters
3147 * @pAdapter: Adapter upon which the command was received
3148 * @command: ASCII text command that is received
3149 *
3150 * Driver commands:
3151 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MAX <value>
3152 * wpa_cli DRIVER BTCSETDWELLTIME ESCO MIN <value>
3153 * wpa_cli DRIVER BTCSETDWELLTIME SCO MAX <value>
3154 * wpa_cli DRIVER BTCSETDWELLTIME SCO MIN <value>
3155 *
3156 * Return: 0 for success non-zero for failure
3157 */
3158
3159static int hdd_btc_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3160{
3161 tHalHandle hHal;
3162 hdd_config_t *pCfg;
3163 tANI_U8 *value = command;
3164 int val = 0, ret = 0, temp = 0;
3165 tSmeConfigParams smeConfig;
3166
3167 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3168 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
3169 {
3170 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME is incorrect"));
3171 ret = -EINVAL;
3172 return ret;
3173 }
3174
3175 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3176 sme_GetConfigParam(hHal, &smeConfig);
3177
3178 if (strncmp(command, "BTCSETDWELLTIME ESCO MAX", 24) == 0)
3179 {
3180 if (hdd_drv_cmd_validate(command, 24)) {
3181 hddLog(LOGE, FL("Invalid driver command"));
3182 return -EINVAL;
3183 }
3184
3185 value = value + 25;
3186 temp = kstrtou32(value, 10, &val);
3187 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ||
3188 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX)
3189 {
3190 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME ESCO MAX is incorrect"));
3191 ret = -EFAULT;
3192 return ret;
3193 }
3194 pCfg->max_chntime_btc_esco = val;
3195 smeConfig.csrConfig.max_chntime_btc_esco = val;
3196 sme_UpdateConfig(hHal, &smeConfig);
3197 }
3198 else if (strncmp(command, "BTCSETDWELLTIME ESCO MIN", 24) == 0)
3199 {
3200 if (hdd_drv_cmd_validate(command, 24)) {
3201 hddLog(LOGE, FL("Invalid driver command"));
3202 return -EINVAL;
3203 }
3204
3205 value = value + 25;
3206 temp = kstrtou32(value, 10, &val);
3207 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ||
3208 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX)
3209 {
3210 hddLog(LOGE, FL("Argument passsed for BTCSETDWELLTIME ESCO MIN is incorrect"));
3211 ret = -EFAULT;
3212 return ret;
3213 }
3214 pCfg->min_chntime_btc_esco = val;
3215 smeConfig.csrConfig.min_chntime_btc_esco = val;
3216 sme_UpdateConfig(hHal, &smeConfig);
3217 }
3218 else if (strncmp(command, "BTCSETDWELLTIME SCO MAX", 23) == 0)
3219 {
3220 if (hdd_drv_cmd_validate(command, 23)) {
3221 hddLog(LOGE, FL("Invalid driver command"));
3222 return -EINVAL;
3223 }
3224
3225 value = value + 24;
3226 temp = kstrtou32(value, 10, &val);
3227 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN ||
3228 val > CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX)
3229 {
3230 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MAX is incorrect"));
3231 ret = -EFAULT;
3232 return ret;
3233 }
3234 pCfg->max_chntime_btc_sco = val;
3235 smeConfig.csrConfig.max_chntime_btc_sco = val;
3236 sme_UpdateConfig(hHal, &smeConfig);
3237 }
3238 else if (strncmp(command, "BTCSETDWELLTIME SCO MIN", 23) == 0)
3239 {
3240 if (hdd_drv_cmd_validate(command, 23)) {
3241 hddLog(LOGE, FL("Invalid driver command"));
3242 return -EINVAL;
3243 }
3244
3245 value = value + 24;
3246 temp = kstrtou32(value, 10, &val);
3247 if (temp != 0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN ||
3248 val > CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX)
3249 {
3250 hddLog(LOGE, FL("Argument passed for BTCSETDWELLTIME SCO MIN is incorrect"));
3251 ret = -EFAULT;
3252 return ret;
3253 }
3254 pCfg->min_chntime_btc_sco = val;
3255 smeConfig.csrConfig.min_chntime_btc_sco = val;
3256 sme_UpdateConfig(hHal, &smeConfig);
3257 }
3258 else
3259 {
3260 ret = -EINVAL;
3261 }
3262
3263 return ret;
3264}
3265
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303266static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command)
3267{
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303268 tHalHandle hHal;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303269 hdd_config_t *pCfg;
3270 tANI_U8 *value = command;
3271 int val = 0, ret = 0, temp = 0;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303272 tSmeConfigParams smeConfig;
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303273
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303274 if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini)
3275 || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter))))
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303276 {
3277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3278 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3279 ret = -EINVAL;
3280 return ret;
3281 }
3282
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303283 vos_mem_zero(&smeConfig, sizeof(smeConfig));
3284 sme_GetConfigParam(hHal, &smeConfig);
3285
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303286 if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 )
3287 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303288 if (hdd_drv_cmd_validate(command, 23))
3289 return -EINVAL;
3290
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303291 value = value + 24;
3292 temp = kstrtou32(value, 10, &val);
3293 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3294 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3295 {
3296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3297 "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__);
3298 ret = -EFAULT;
3299 return ret;
3300 }
3301 pCfg->nActiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303302 smeConfig.csrConfig.nActiveMaxChnTime = val;
3303 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303304 }
3305 else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0)
3306 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303307 if (hdd_drv_cmd_validate(command, 23))
3308 return -EINVAL;
3309
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303310 value = value + 24;
3311 temp = kstrtou32(value, 10, &val);
3312 if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ||
3313 val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX )
3314 {
3315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3316 "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__);
3317 ret = -EFAULT;
3318 return ret;
3319 }
3320 pCfg->nActiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303321 smeConfig.csrConfig.nActiveMinChnTime = val;
3322 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303323 }
3324 else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0)
3325 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303326 if (hdd_drv_cmd_validate(command, 24))
3327 return -EINVAL;
3328
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303329 value = value + 25;
3330 temp = kstrtou32(value, 10, &val);
3331 if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ||
3332 val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX )
3333 {
3334 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3335 "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__);
3336 ret = -EFAULT;
3337 return ret;
3338 }
3339 pCfg->nPassiveMaxChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303340 smeConfig.csrConfig.nPassiveMaxChnTime = val;
3341 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303342 }
3343 else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0)
3344 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303345 if (hdd_drv_cmd_validate(command, 24))
3346 return -EINVAL;
3347
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303348 value = value + 25;
3349 temp = kstrtou32(value, 10, &val);
3350 if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ||
3351 val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX )
3352 {
3353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3354 "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__);
3355 ret = -EFAULT;
3356 return ret;
3357 }
3358 pCfg->nPassiveMinChnTime = val;
Rajesh Babu Prathipatib09815c2014-07-05 11:22:24 +05303359 smeConfig.csrConfig.nPassiveMinChnTime = val;
3360 sme_UpdateConfig(hHal, &smeConfig);
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303361 }
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303362 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
3363 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303364 if (hdd_drv_cmd_validate(command, 12))
3365 return -EINVAL;
3366
Rajesh Babu Prathipati0fd227e2014-07-05 12:50:00 +05303367 value = value + 13;
3368 temp = kstrtou32(value, 10, &val);
3369 if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ||
3370 val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX )
3371 {
3372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3373 "%s: argument passed for SETDWELLTIME is incorrect", __func__);
3374 ret = -EFAULT;
3375 return ret;
3376 }
3377 pCfg->nActiveMaxChnTime = val;
3378 smeConfig.csrConfig.nActiveMaxChnTime = val;
3379 sme_UpdateConfig(hHal, &smeConfig);
3380 }
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303381 else
3382 {
3383 ret = -EINVAL;
3384 }
3385
3386 return ret;
3387}
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303388static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd,
3389 tANI_U8 cmd_len)
3390{
3391 tANI_U8 *value;
3392 tANI_U8 fcc_constraint;
3393
3394 eHalStatus status;
3395 int ret = 0;
3396 value = cmd + cmd_len + 1;
3397
3398 ret = kstrtou8(value, 10, &fcc_constraint);
3399 if ((ret < 0) || (fcc_constraint > 1)) {
3400 /*
3401 * If the input value is greater than max value of datatype,
3402 * then also it is a failure
3403 */
3404 hddLog(VOS_TRACE_LEVEL_ERROR,
3405 "%s: value out of range", __func__);
3406 return -EINVAL;
3407 }
3408
Agrawal Ashish842eea82016-02-04 17:56:16 +05303409 status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint,
3410 pHddCtx->scan_info.mScanPending);
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303411 if (status != eHAL_STATUS_SUCCESS)
3412 ret = -EPERM;
3413
3414 return ret;
3415}
3416
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303417/**---------------------------------------------------------------------------
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05303418
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05303419 \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled),
3420 FW will send *ONE* CA ind to Host(even though it is duplicate).
3421 When Host send IOCTL (disable), FW doesn't perform any action.
3422 Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW
3423 sends CA ind to host. (regard less of IOCTL status)
3424 \param - pHddCtx - HDD context
3425 \param - command - command received from framework
3426 \param - cmd_len - len of the command
3427
3428 \return - 0 on success, appropriate error values on failure.
3429
3430 --------------------------------------------------------------------------*/
3431int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len)
3432{
3433 tANI_U8 set_value;
3434 int ret = 0;
3435 eHalStatus status;
3436
3437 ret = wlan_hdd_validate_context(pHddCtx);
3438 if (0 != ret)
3439 {
3440 ret = -EINVAL;
3441 goto exit;
3442 }
3443
3444 if (pHddCtx->cfg_ini->gOptimizeCAevent == 0)
3445 {
3446 hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent"
3447 " ini param to control channel avooidance indication");
3448 ret = 0;
3449 goto exit;
3450 }
3451
3452 set_value = command[cmd_len + 1] - '0';
3453 status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value);
3454 if (status != eHAL_STATUS_SUCCESS)
3455 {
3456 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send"
3457 " enableDisableChanAoidance command to SME\n", __func__);
3458 ret = -EINVAL;
3459 }
3460
3461exit:
3462 return ret;
3463}
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05303464
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303465/**
3466 * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME
3467 * @pHddCtx: Pointer to the HDD context
3468 * @channel: channel to reassociate
3469 * @targetApBssid: Target AP/BSSID to reassociate
3470 *
3471 * Return: None
3472 */
3473#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC)
3474static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3475 uint8_t channel, tSirMacAddr targetApBssid)
3476{
3477 tCsrHandoffRequest handoffInfo;
3478 handoffInfo.channel = channel;
3479 handoffInfo.src = FASTREASSOC;
3480 vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr));
3481 sme_HandoffRequest(pHddCtx->hHal, &handoffInfo);
3482}
3483#else
3484static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx,
3485 uint8_t channel, tSirMacAddr targetApBssid)
3486{
3487}
3488#endif
3489
3490/**
3491 * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam
3492 * @pAdapter: Pointer to HDD adapter
3493 * @channel: Channel to scan/roam
3494 * @targetApBssid: BSSID to roam
3495 *
3496 * Return: None
3497 */
3498#ifdef QCA_WIFI_ISOC
3499static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3500 uint8_t channel, tSirMacAddr targetApBssid)
3501{
3502 smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter),
3503 &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel);
3504}
3505#else
3506static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter,
3507 uint8_t channel, tSirMacAddr targetApBssid)
3508{
3509}
3510#endif
3511
3512/**
3513 * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command
3514 * @pAdapter: pointer to hdd adapter
3515 * @command: pointer to the command received
3516 *
3517 * Return: VOS_STATUS enum
3518 */
3519static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter,
3520 uint8_t *command)
3521{
3522 tANI_U8 *value = command;
3523 tANI_U8 channel = 0;
3524 tSirMacAddr targetApBssid;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303525 hdd_station_ctx_t *pHddStaCtx = NULL;
3526 hdd_context_t *pHddCtx = NULL;
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303527 int ret;
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303528 tCsrRoamModifyProfileFields mod_profile_fields;
3529 uint32_t roam_id = 0;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303530 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3531 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3532
3533 /* if not associated, no need to proceed with reassoc */
3534 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
3535 hddLog(LOG1, FL("Not associated!"));
3536 return eHAL_STATUS_FAILURE;
3537 }
3538
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05303539 ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel);
3540 if (ret) {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303541 hddLog(LOGE, FL("Failed to parse reassoc command data"));
3542 return eHAL_STATUS_FAILURE;
3543 }
3544
3545 /* if the target bssid is same as currently associated AP,
3546 then no need to proceed with reassoc */
3547 if (vos_mem_compare(targetApBssid,
3548 pHddStaCtx->conn_info.bssId,
3549 sizeof(tSirMacAddr))) {
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303550 sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId,
3551 &mod_profile_fields);
3552 sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL,
3553 mod_profile_fields, &roam_id, 1);
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303554 hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid"));
Selvaraj, Sridhar349b8fe2017-01-18 13:11:25 +05303555 return eHAL_STATUS_SUCCESS;
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05303556 }
3557
3558 /* Check channel number is a valid channel number */
3559 if (VOS_STATUS_SUCCESS !=
3560 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
3561 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
3562 return eHAL_STATUS_FAILURE;
3563 }
3564
3565 /* Proceed with reassoc */
3566 wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid);
3567
3568 /* Proceed with scan/roam */
3569 csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid);
3570
3571 return eHAL_STATUS_SUCCESS;
3572}
3573
3574/**
3575 * hdd_assign_reassoc_handoff - Set handoff source as REASSOC
3576 * @handoffInfo: Pointer to the csr Handoff Request.
3577 *
3578 * Return: None
3579 */
3580#ifndef QCA_WIFI_ISOC
3581static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3582{
3583 handoffInfo->src = REASSOC;
3584}
3585#else
3586static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo)
3587{
3588}
3589#endif
3590
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05303591/**
3592 * wlan_hdd_free_cache_channels() - Free the cache channels list
3593 * @hdd_ctx: Pointer to HDD context
3594 *
3595 * Return: None
3596 */
3597
3598static void wlan_hdd_free_cache_channels(hdd_context_t *hdd_ctx)
3599{
3600 mutex_lock(&hdd_ctx->cache_channel_lock);
3601 hdd_ctx->orginal_channels->num_channels = 0;
3602 vos_mem_free(hdd_ctx->orginal_channels->channel_info);
3603 hdd_ctx->orginal_channels->channel_info = NULL;
3604 vos_mem_free(hdd_ctx->orginal_channels);
3605 hdd_ctx->orginal_channels = NULL;
3606 mutex_unlock(&hdd_ctx->cache_channel_lock);
3607}
3608
3609/**
3610 * hdd_alloc_chan_cache() - Allocate the memory to cache the channel
3611 * info for the channels received in command SET_DISABLE_CHANNEL_LIST
3612 * @hdd_ctx: Pointer to HDD context
3613 * @num_chan: Number of channels for which memory needs to
3614 * be allocated
3615 *
3616 * Return: 0 on success and error code on failure
3617 */
3618
3619int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan)
3620{
3621 if (NULL == hdd_ctx->orginal_channels) {
3622 hdd_ctx->orginal_channels =
3623 vos_mem_malloc(sizeof(struct hdd_cache_channels));
3624 if (NULL == hdd_ctx->orginal_channels) {
3625 hddLog(VOS_TRACE_LEVEL_ERROR,
3626 "In %s, VOS_MALLOC_ERR", __func__);
3627 return -EINVAL;
3628 }
3629 hdd_ctx->orginal_channels->num_channels = num_chan;
3630 hdd_ctx->orginal_channels->channel_info =
3631 vos_mem_malloc(num_chan *
3632 sizeof(struct hdd_cache_channel_info));
3633 if (NULL == hdd_ctx->orginal_channels->channel_info) {
3634 hddLog(VOS_TRACE_LEVEL_ERROR,
3635 "In %s, VOS_MALLOC_ERR", __func__);
3636 hdd_ctx->orginal_channels->num_channels = 0;
3637 vos_mem_free(hdd_ctx->orginal_channels);
3638 hdd_ctx->orginal_channels = NULL;
3639 return -EINVAL;
3640 }
3641 } else {
3642 /* Same command comes multiple times */
3643 struct hdd_cache_channel_info *temp_chan_info;
3644
3645 if (hdd_ctx->orginal_channels->num_channels + num_chan >
3646 MAX_CHANNEL) {
3647 hddLog(VOS_TRACE_LEVEL_ERROR,
3648 "%s: Invalid Number of channel received",
3649 __func__);
3650 return -EINVAL;
3651 }
3652
3653 temp_chan_info = vos_mem_malloc((
3654 hdd_ctx->orginal_channels->
3655 num_channels + num_chan) *
3656 sizeof(struct hdd_cache_channel_info));
3657 if (NULL == temp_chan_info) {
3658 hddLog(VOS_TRACE_LEVEL_ERROR,
3659 "In %s, VOS_MALLOC_ERR",
3660 __func__);
3661 return -EINVAL;
3662 }
3663
3664 vos_mem_copy(temp_chan_info, hdd_ctx->orginal_channels->
3665 channel_info, hdd_ctx->orginal_channels->
3666 num_channels *
3667 sizeof(struct hdd_cache_channel_info));
3668
3669 hdd_ctx->orginal_channels->num_channels += num_chan;
3670 vos_mem_free(hdd_ctx->orginal_channels->channel_info);
3671 hdd_ctx->orginal_channels->channel_info = temp_chan_info;
3672 temp_chan_info = NULL;
3673 }
3674 return 0;
3675
3676}
3677
3678
3679int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, tANI_U8 *ptr)
3680{
3681 v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
3682 hdd_context_t *hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, pvosGCtx);
3683 tANI_U8 *param;
3684 int j, tempInt, index = 0, ret = 0;
3685
3686 if (NULL == pvosGCtx) {
3687 hddLog(VOS_TRACE_LEVEL_FATAL,
3688 "VOS Global Context is NULL");
3689 return -EINVAL;
3690 }
3691
3692 if (NULL == hdd_ctx) {
3693 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
3694 return -EINVAL;
3695 }
3696
3697 param = strchr(ptr, ' ');
3698 /*no argument after the command*/
3699 if (NULL == param)
3700 return -EINVAL;
3701
3702 /*no space after the command*/
3703 else if (SPACE_ASCII_VALUE != *param)
3704 return -EINVAL;
3705
3706 param++;
3707
3708 /*removing empty spaces*/
3709 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3710 param++;
3711
3712 /*no argument followed by spaces*/
3713 if ('\0' == *param)
3714 return -EINVAL;
3715
3716 /*getting the first argument ie the number of channels*/
3717 if (sscanf(param, "%d ", &tempInt) != 1) {
3718 hddLog(VOS_TRACE_LEVEL_ERROR,
3719 "%s: Cannot get number of channels from input",
3720 __func__);
3721 return -EINVAL;
3722 }
3723
3724 if (tempInt < 0 || tempInt > MAX_CHANNEL) {
3725 hddLog(VOS_TRACE_LEVEL_ERROR,
3726 "%s: Invalid Number of channel received", __func__);
3727 return -EINVAL;
3728 }
3729
3730 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
3731 "%s: Number of channel to disable are: %d",
3732 __func__, tempInt);
3733
3734 if (!tempInt) {
3735 if (!wlan_hdd_restore_channels(hdd_ctx)) {
3736 /*
3737 * Free the cache channels only when the command is
3738 * received with num channels as 0
3739 */
3740 wlan_hdd_free_cache_channels(hdd_ctx);
3741 }
3742 return 0;
3743 }
3744
3745 mutex_lock(&hdd_ctx->cache_channel_lock);
3746 if (hdd_alloc_chan_cache(hdd_ctx, tempInt)) {
3747 ret = -ENOMEM;
3748 goto parse_done;
3749 }
3750 index = hdd_ctx->orginal_channels->num_channels - tempInt;
3751
3752 for (j = index; j < hdd_ctx->orginal_channels->num_channels; j++) {
3753 /*
3754 * param pointing to the beginning of first space
3755 * after number of channels
3756 */
3757 param = strpbrk(param, " ");
3758 /*no channel list after the number of channels argument*/
3759 if (NULL == param) {
3760 hddLog(VOS_TRACE_LEVEL_ERROR,
3761 "%s, Invalid No of channel provided in the list",
3762 __func__);
3763 ret = -EINVAL;
3764 goto parse_done;
3765 }
3766
3767 param++;
3768
3769 /*removing empty space*/
3770 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3771 param++;
3772
3773 if ('\0' == *param) {
3774 hddLog(VOS_TRACE_LEVEL_ERROR,
3775 "%s, No channel is provided in the list",
3776 __func__);
3777 ret = -EINVAL;
3778 goto parse_done;
3779
3780 }
3781
3782 if (sscanf(param, "%d ", &tempInt) != 1) {
3783 hddLog(VOS_TRACE_LEVEL_ERROR,
3784 "%s: Cannot read channel number",
3785 __func__);
3786 ret = -EINVAL;
3787 goto parse_done;
3788
3789 }
3790
3791 if (!IS_CHANNEL_VALID(tempInt)) {
3792 hddLog(VOS_TRACE_LEVEL_ERROR,
3793 "%s: Invalid channel number received",
3794 __func__);
3795 ret = -EINVAL;
3796 goto parse_done;
3797
3798 }
3799
3800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: channel[%d] = %d", __func__,
3801 j, tempInt);
3802 hdd_ctx->orginal_channels->channel_info[j].channel_num =
3803 tempInt;
3804 }
3805
3806 /*extra arguments check*/
3807 param = strchr(param, ' ');
3808 if (NULL != param) {
3809 while ((SPACE_ASCII_VALUE == *param) && ('\0' != *param))
3810 param++;
3811
3812 if ('\0' != *param) {
3813 hddLog(VOS_TRACE_LEVEL_ERROR,
3814 "%s: Invalid argument received", __func__);
3815 ret = -EINVAL;
3816 goto parse_done;
3817 }
3818 }
3819
3820parse_done:
3821 mutex_unlock(&hdd_ctx->cache_channel_lock);
3822 EXIT();
3823
3824 return ret;
3825}
3826
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05303827int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
3828 tANI_U8 buf_len)
3829{
3830 struct hdd_cache_channel_info *ch_list;
3831 unsigned char i, num_ch;
3832 int len = 0;
3833
3834 mutex_lock(&hdd_ctx->cache_channel_lock);
3835 if (hdd_ctx->orginal_channels &&
3836 hdd_ctx->orginal_channels->num_channels) {
3837 num_ch = hdd_ctx->orginal_channels->num_channels;
3838
3839 if (num_ch == 0) {
3840 mutex_unlock(&hdd_ctx->cache_channel_lock);
3841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3842 FL("no disable channels programed"));
3843 return 0;
3844 }
3845
3846 len = scnprintf(buf, buf_len, "%s %hhu",
3847 "GET_DISABLE_CHANNEL_LIST", num_ch);
3848
3849 ch_list = hdd_ctx->orginal_channels->channel_info;
3850 if (!ch_list) {
3851 mutex_unlock(&hdd_ctx->cache_channel_lock);
3852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3853 FL("disable channel list is NULL"));
3854 return 0;
3855 }
3856
3857 for (i = 0; (i < num_ch) && len <= buf_len; i++) {
3858 len += scnprintf(buf + len, buf_len - len,
3859 " %d", ch_list[i].channel_num);
3860 }
3861 }
3862 mutex_unlock(&hdd_ctx->cache_channel_lock);
3863
3864 return len;
3865}
3866
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003867static int hdd_driver_command(hdd_adapter_t *pAdapter,
3868 hdd_priv_data_t *ppriv_data)
Jeff Johnson295189b2012-06-20 16:38:30 -07003869{
Jeff Johnson295189b2012-06-20 16:38:30 -07003870 hdd_priv_data_t priv_data;
3871 tANI_U8 *command = NULL;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303872 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3873 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003874 int ret = 0;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303875 int status;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05303876#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
3877 struct cfg80211_mgmt_tx_params params;
3878#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303879
3880 ENTER();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003881 /*
3882 * Note that valid pointers are provided by caller
3883 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003884
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003885 /* copy to local struct to avoid numerous changes to legacy code */
3886 priv_data = *ppriv_data;
Jeff Johnson295189b2012-06-20 16:38:30 -07003887
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003888 if (priv_data.total_len <= 0 ||
3889 priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN)
Sameer Thalappil8ef3a0e2013-04-05 14:36:04 -07003890 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003891 hddLog(VOS_TRACE_LEVEL_WARN,
3892 "%s:invalid priv_data.total_len(%d)!!!", __func__,
3893 priv_data.total_len);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003894 ret = -EINVAL;
3895 goto exit;
3896 }
Kaushik, Sushant96122442014-10-21 16:40:18 +05303897 status = wlan_hdd_validate_context(pHddCtx);
3898 if (0 != status)
3899 {
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303900 ret = -EINVAL;
3901 goto exit;
Kaushik, Sushant96122442014-10-21 16:40:18 +05303902 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003903 /* Allocate +1 for '\0' */
3904 command = kmalloc(priv_data.total_len + 1, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07003905 if (!command)
3906 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003907 hddLog(VOS_TRACE_LEVEL_ERROR,
3908 "%s: failed to allocate memory", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003909 ret = -ENOMEM;
3910 goto exit;
3911 }
3912
3913 if (copy_from_user(command, priv_data.buf, priv_data.total_len))
3914 {
3915 ret = -EFAULT;
3916 goto exit;
3917 }
3918
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003919 /* Make sure the command is NUL-terminated */
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07003920 command[priv_data.total_len] = '\0';
3921
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07003922 /* at one time the following block of code was conditional. braces
3923 * have been retained to avoid re-indenting the legacy code
3924 */
Jeff Johnson295189b2012-06-20 16:38:30 -07003925 {
3926 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
3927
3928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07003929 "%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
Jeff Johnson295189b2012-06-20 16:38:30 -07003930
3931 if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 )
3932 {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303933 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3934 TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL,
3935 pAdapter->sessionId, (unsigned)
3936 (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 |
3937 *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 |
3938 *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 |
3939 *(pHddCtx->p2pDeviceAddress.bytes+5))));
Jeff Johnson295189b2012-06-20 16:38:30 -07003940 if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes,
3941 sizeof(tSirMacAddr)))
3942 {
3943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003944 "%s: failed to copy data to user buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07003945 ret = -EFAULT;
3946 }
3947 }
Amar Singhal0974e402013-02-12 14:27:46 -08003948 else if(strncmp(command, "SETBAND", 7) == 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07003949 {
Amar Singhal0974e402013-02-12 14:27:46 -08003950 tANI_U8 *ptr = command ;
Srinivas Girigowdade697412013-02-14 16:31:48 -08003951
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303952 ret = hdd_drv_cmd_validate(command, 7);
3953 if (ret)
3954 goto exit;
3955
Jeff Johnson295189b2012-06-20 16:38:30 -07003956 /* Change band request received */
Srinivas Girigowdade697412013-02-14 16:31:48 -08003957
3958 /* First 8 bytes will have "SETBAND " and
Jeff Johnson295189b2012-06-20 16:38:30 -07003959 * 9 byte will have band setting value */
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07003960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Amar Singhal0974e402013-02-12 14:27:46 -08003961 "%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 +05303962 if(VOS_FTM_MODE != hdd_get_conparam())
3963 {
3964 /* Change band request received */
3965 ret = hdd_setBand_helper(pAdapter->dev, ptr);
3966 if(ret < 0)
3967 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
3968 "%s: failed to set band ret=%d", __func__, ret);
3969 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08003970 }
Kiet Lamf040f472013-11-20 21:15:23 +05303971 else if(strncmp(command, "SETWMMPS", 8) == 0)
3972 {
3973 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303974
3975 ret = hdd_drv_cmd_validate(command, 8);
3976 if (ret)
3977 goto exit;
3978
Kiet Lamf040f472013-11-20 21:15:23 +05303979 ret = hdd_wmmps_helper(pAdapter, ptr);
3980 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05303981
3982 else if(strncmp(command, "TDLSSCAN", 8) == 0)
3983 {
3984 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303985
3986 ret = hdd_drv_cmd_validate(command, 8);
3987 if (ret)
3988 goto exit;
3989
Agarwal Ashishef54a182014-12-16 15:07:31 +05303990 ret = hdd_set_tdls_scan_type(pAdapter, ptr);
3991 }
3992
Jeff Johnson32d95a32012-09-10 13:15:23 -07003993 else if ( strncasecmp(command, "COUNTRY", 7) == 0 )
3994 {
3995 char *country_code;
3996
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05303997 ret = hdd_drv_cmd_validate(command, 7);
3998 if (ret)
3999 goto exit;
4000
Jeff Johnson32d95a32012-09-10 13:15:23 -07004001 country_code = command + 8;
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004002
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004003 INIT_COMPLETION(pAdapter->change_country_code);
Tushnim Bhattacharyya9cdf6082013-04-21 16:33:30 -07004004 hdd_checkandupdate_dfssetting(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004005#ifndef CONFIG_ENABLE_LINUX_REG
Gopichand Nakkaladacbcb52013-04-18 16:41:54 +05304006 hdd_checkandupdate_phymode(pAdapter, country_code);
Tushnim Bhattacharyya71ccecc2013-10-14 16:22:56 -07004007#endif
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004008 ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
4009 (void *)(tSmeChangeCountryCallback)
4010 wlan_hdd_change_country_code_callback,
Abhishek Singha306a442013-11-07 18:39:01 +05304011 country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004012 if (eHAL_STATUS_SUCCESS == ret)
4013 {
4014 ret = wait_for_completion_interruptible_timeout(
4015 &pAdapter->change_country_code,
4016 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
4017 if (0 >= ret)
4018 {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004019 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d",
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304020 __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004021 }
4022 }
4023 else
Jeff Johnson32d95a32012-09-10 13:15:23 -07004024 {
4025 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004026 "%s: SME Change Country code fail ret=%d", __func__, ret);
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004027 ret = -EINVAL;
Jeff Johnson32d95a32012-09-10 13:15:23 -07004028 }
Sameer Thalappilda4eb6a2013-09-25 11:45:07 -07004029
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004030 }
4031 /*
4032 command should be a string having format
4033 SET_SAP_CHANNEL_LIST <num of channels> <the channels seperated by spaces>
4034 */
Amar Singhal0974e402013-02-12 14:27:46 -08004035 else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0)
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004036 {
Amar Singhal0974e402013-02-12 14:27:46 -08004037 tANI_U8 *ptr = command;
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004038
4039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004040 " Received Command to Set Preferred Channels for SAP in %s", __func__);
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07004041
Mahesh Kumar Kalikot Veetil2aad8d82013-02-07 12:31:28 -08004042 ret = sapSetPreferredChannel(ptr);
Jeff Johnson32d95a32012-09-10 13:15:23 -07004043 }
Sourav Mohapatra2416e0e2018-03-05 18:44:21 +05304044
4045 else if (strncmp(command, "VOWIFIMODE", 10) == 0)
4046 {
4047 tANI_U8 *ptr;
4048
4049 ret = hdd_drv_cmd_validate(command, 10);
4050 if (ret)
4051 goto exit;
4052
4053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4054 "Received Command for VOWIFI mode in %s", __func__);
4055
4056 ptr = (tANI_U8*)command + 11;
4057 hdd_set_vowifi_mode(pHddCtx, *ptr - '0');
4058 }
4059
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004060 else if(strncmp(command, "SETSUSPENDMODE", 14) == 0)
4061 {
4062 int suspend = 0;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304063 tANI_U8 *ptr;
4064
4065 ret = hdd_drv_cmd_validate(command, 14);
4066 if (ret)
4067 goto exit;
4068
4069 ptr = (tANI_U8*)command + 15;
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004070
4071 suspend = *ptr - '0';
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304072 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4073 TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL,
4074 pAdapter->sessionId, suspend));
Sameer Thalappil45931fb2013-02-01 11:18:05 -08004075 hdd_set_wlan_suspend_mode(suspend);
4076 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004077#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
4078 else if (strncmp(command, "SETROAMTRIGGER", 14) == 0)
4079 {
4080 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004081 tANI_S8 rssi = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004082 tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT;
4083 eHalStatus status = eHAL_STATUS_SUCCESS;
4084
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304085 ret = hdd_drv_cmd_validate(command, 14);
4086 if (ret)
4087 goto exit;
4088
Srinivas Girigowdade697412013-02-14 16:31:48 -08004089 /* Move pointer to ahead of SETROAMTRIGGER<delimiter> */
4090 value = value + 15;
4091
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004092 /* Convert the value from ascii to integer */
4093 ret = kstrtos8(value, 10, &rssi);
4094 if (ret < 0)
4095 {
4096 /* If the input value is greater than max value of datatype, then also
4097 kstrtou8 fails */
4098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4099 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdafa7157d2013-10-31 10:14:22 -07004100 __func__,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004101 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4102 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4103 ret = -EINVAL;
4104 goto exit;
4105 }
4106
Srinivas Girigowdade697412013-02-14 16:31:48 -08004107 lookUpThreshold = abs(rssi);
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004108
Srinivas Girigowdade697412013-02-14 16:31:48 -08004109 if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) ||
4110 (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX))
4111 {
4112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4113 "Neighbor lookup threshold value %d is out of range"
4114 " (Min: %d Max: %d)", lookUpThreshold,
4115 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN,
4116 CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX);
4117 ret = -EINVAL;
4118 goto exit;
4119 }
4120
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304121 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4122 TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL,
4123 pAdapter->sessionId, lookUpThreshold));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4125 "%s: Received Command to Set Roam trigger"
4126 " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold);
4127
4128 pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold;
4129 status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold);
4130 if (eHAL_STATUS_SUCCESS != status)
4131 {
4132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4133 "%s: Failed to set roam trigger, try again", __func__);
4134 ret = -EPERM;
4135 goto exit;
4136 }
4137
4138 /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */
mukul sharmad6e1fdd2014-06-23 19:19:09 +05304139 pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004140 sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5);
4141 }
4142 else if (strncmp(command, "GETROAMTRIGGER", 14) == 0)
4143 {
4144 tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal));
4145 int rssi = (-1) * lookUpThreshold;
4146 char extra[32];
4147 tANI_U8 len = 0;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304148 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4149 TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL,
4150 pAdapter->sessionId, lookUpThreshold));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004151 len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi);
Srinivas Girigowda91719232015-07-13 15:10:10 +05304152 len = VOS_MIN(priv_data.total_len, len + 1);
4153 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004154 {
4155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4156 "%s: failed to copy data to user buffer", __func__);
4157 ret = -EFAULT;
4158 goto exit;
4159 }
4160 }
4161 else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0)
4162 {
4163 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004164 tANI_U8 roamScanPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004165 tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004166
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304167 ret = hdd_drv_cmd_validate(command, 17);
4168 if (ret)
4169 goto exit;
4170
Srinivas Girigowdade697412013-02-14 16:31:48 -08004171 /* input refresh period is in terms of seconds */
4172 /* Move pointer to ahead of SETROAMSCANPERIOD<delimiter> */
4173 value = value + 18;
4174 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004175 ret = kstrtou8(value, 10, &roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004176 if (ret < 0)
4177 {
4178 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004179 kstrtou8 fails */
Srinivas Girigowdade697412013-02-14 16:31:48 -08004180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004181 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdade697412013-02-14 16:31:48 -08004182 __func__,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004183 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4184 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004185 ret = -EINVAL;
4186 goto exit;
4187 }
4188
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004189 if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) ||
4190 (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004191 {
4192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004193 "Roam scan period value %d is out of range"
4194 " (Min: %d Max: %d)", roamScanPeriod,
Srinivas Girigowdab8edd1e2013-03-19 11:42:08 -07004195 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000),
4196 (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004197 ret = -EINVAL;
4198 goto exit;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304199 }
4200 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4201 TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL,
4202 pAdapter->sessionId, roamScanPeriod));
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004203 neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004204
4205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4206 "%s: Received Command to Set roam scan period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004207 " (Empty Scan refresh period) = %d", __func__, roamScanPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004208
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004209 pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod;
4210 sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004211 }
4212 else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0)
4213 {
4214 tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4215 char extra[32];
4216 tANI_U8 len = 0;
4217
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304218 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4219 TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL,
4220 pAdapter->sessionId, nEmptyScanRefreshPeriod));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004221 len = scnprintf(extra, sizeof(extra), "%s %d",
4222 "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004223 /* Returned value is in units of seconds */
Ratnam Rachuria72ba112015-07-17 13:27:03 +05304224 len = VOS_MIN(priv_data.total_len, len + 1);
4225 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004226 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4227 "%s: failed to copy data to user buffer", __func__);
4228 ret = -EFAULT;
4229 goto exit;
4230 }
4231 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004232 else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0)
4233 {
4234 tANI_U8 *value = command;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004235 tANI_U8 roamScanRefreshPeriod = 0;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004236 tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004237
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304238 ret = hdd_drv_cmd_validate(command, 24);
4239 if (ret)
4240 goto exit;
4241
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004242 /* input refresh period is in terms of seconds */
4243 /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD<delimiter> */
4244 value = value + 25;
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004245
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004246 /* Convert the value from ascii to integer */
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004247 ret = kstrtou8(value, 10, &roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004248 if (ret < 0)
4249 {
4250 /* If the input value is greater than max value of datatype, then also
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004251 kstrtou8 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004253 "%s: kstrtou8 failed Input value may be out of range[%d - %d]",
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004254 __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004255 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4256 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4257 ret = -EINVAL;
4258 goto exit;
4259 }
4260
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004261 if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) ||
4262 (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)))
4263 {
4264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4265 "Neighbor scan results refresh period value %d is out of range"
4266 " (Min: %d Max: %d)", roamScanRefreshPeriod,
4267 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000),
4268 (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000));
4269 ret = -EINVAL;
4270 goto exit;
4271 }
4272 neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000;
4273
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4275 "%s: Received Command to Set roam scan refresh period"
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004276 " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004277
4278 pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod;
4279 sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod);
4280 }
4281 else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0)
4282 {
4283 tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal));
4284 char extra[32];
4285 tANI_U8 len = 0;
4286
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004287 len = scnprintf(extra, sizeof(extra), "%s %d",
4288 "GETROAMSCANREFRESHPERIOD", (value/1000));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004289 /* Returned value is in units of seconds */
Ratnam Rachuri2c9d6702015-07-17 13:25:16 +05304290 len = VOS_MIN(priv_data.total_len, len + 1);
4291 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4293 "%s: failed to copy data to user buffer", __func__);
4294 ret = -EFAULT;
4295 goto exit;
4296 }
4297 }
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004298#ifdef FEATURE_WLAN_LFR
4299 /* SETROAMMODE */
4300 else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0)
4301 {
4302 tANI_U8 *value = command;
4303 tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
4304
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05304305 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
4306 hddLog(LOGE,
4307 FL("Roaming is always disabled in STA + MON concurrency"));
4308 ret = -EINVAL;
4309 goto exit;
4310 }
4311
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304312 ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE);
4313 if (ret)
4314 goto exit;
4315
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004316 /* Move pointer to ahead of SETROAMMODE<delimiter> */
4317 value = value + SIZE_OF_SETROAMMODE + 1;
4318
4319 /* Convert the value from ascii to integer */
4320 ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode);
4321 if (ret < 0)
4322 {
4323 /* If the input value is greater than max value of datatype, then also
4324 kstrtou8 fails */
4325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4326 "%s: kstrtou8 failed range [%d - %d]", __func__,
4327 CFG_LFR_FEATURE_ENABLED_MIN,
4328 CFG_LFR_FEATURE_ENABLED_MAX);
4329 ret = -EINVAL;
4330 goto exit;
4331 }
4332 if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
4333 (roamMode > CFG_LFR_FEATURE_ENABLED_MAX))
4334 {
4335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4336 "Roam Mode value %d is out of range"
4337 " (Min: %d Max: %d)", roamMode,
4338 CFG_LFR_FEATURE_ENABLED_MIN,
4339 CFG_LFR_FEATURE_ENABLED_MAX);
4340 ret = -EINVAL;
4341 goto exit;
4342 }
4343
4344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4345 "%s: Received Command to Set Roam Mode = %d", __func__, roamMode);
4346 /*
4347 * Note that
4348 * SETROAMMODE 0 is to enable LFR while
4349 * SETROAMMODE 1 is to disable LFR, but
4350 * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable.
4351 * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled.
4352 */
4353 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4354 roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */
4355 else
4356 roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */
4357
4358 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode;
4359 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode);
4360 }
4361 /* GETROAMMODE */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304362 else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0)
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004363 {
4364 tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4365 char extra[32];
4366 tANI_U8 len = 0;
4367
4368 /*
4369 * roamMode value shall be inverted because the sementics is different.
4370 */
4371 if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode)
4372 roamMode = CFG_LFR_FEATURE_ENABLED_MAX;
4373 else
4374 roamMode = CFG_LFR_FEATURE_ENABLED_MIN;
4375
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004376 len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode);
Ratnam Rachuri28693eb2015-07-17 13:23:42 +05304377 len = VOS_MIN(priv_data.total_len, len + 1);
4378 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu6d99ac82013-05-08 14:15:35 -07004379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4380 "%s: failed to copy data to user buffer", __func__);
4381 ret = -EFAULT;
4382 goto exit;
4383 }
4384 }
4385#endif
Srinivas Girigowdade697412013-02-14 16:31:48 -08004386#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004387#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004388 else if (strncmp(command, "SETROAMDELTA", 12) == 0)
4389 {
4390 tANI_U8 *value = command;
4391 tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT;
4392
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304393 ret = hdd_drv_cmd_validate(command, 12);
4394 if (ret)
4395 goto exit;
4396
Srinivas Girigowdade697412013-02-14 16:31:48 -08004397 /* Move pointer to ahead of SETROAMDELTA<delimiter> */
4398 value = value + 13;
4399 /* Convert the value from ascii to integer */
4400 ret = kstrtou8(value, 10, &roamRssiDiff);
4401 if (ret < 0)
4402 {
4403 /* If the input value is greater than max value of datatype, then also
4404 kstrtou8 fails */
4405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4406 "%s: kstrtou8 failed range [%d - %d]", __func__,
4407 CFG_ROAM_RSSI_DIFF_MIN,
4408 CFG_ROAM_RSSI_DIFF_MAX);
4409 ret = -EINVAL;
4410 goto exit;
4411 }
4412
4413 if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) ||
4414 (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX))
4415 {
4416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4417 "Roam rssi diff value %d is out of range"
4418 " (Min: %d Max: %d)", roamRssiDiff,
4419 CFG_ROAM_RSSI_DIFF_MIN,
4420 CFG_ROAM_RSSI_DIFF_MAX);
4421 ret = -EINVAL;
4422 goto exit;
4423 }
4424
4425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4426 "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff);
4427
4428 pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff;
4429 sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff);
4430 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05304431 else if (strncmp(command, "GETROAMDELTA", 12) == 0)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004432 {
4433 tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal));
4434 char extra[32];
4435 tANI_U8 len = 0;
4436
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304437 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4438 TRACE_CODE_HDD_GETROAMDELTA_IOCTL,
4439 pAdapter->sessionId, roamRssiDiff));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004440 len = scnprintf(extra, sizeof(extra), "%s %d",
4441 command, roamRssiDiff);
Ratnam Rachuri22a3b402015-07-17 13:21:49 +05304442 len = VOS_MIN(priv_data.total_len, len + 1);
4443 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4445 "%s: failed to copy data to user buffer", __func__);
4446 ret = -EFAULT;
4447 goto exit;
4448 }
4449 }
4450#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004451#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004452 else if (strncmp(command, "GETBAND", 7) == 0)
4453 {
4454 int band = -1;
4455 char extra[32];
4456 tANI_U8 len = 0;
4457 hdd_getBand_helper(pHddCtx, &band);
4458
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304459 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4460 TRACE_CODE_HDD_GETBAND_IOCTL,
4461 pAdapter->sessionId, band));
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004462 len = scnprintf(extra, sizeof(extra), "%s %d", command, band);
Ratnam Rachuri52139592015-07-17 13:17:29 +05304463 len = VOS_MIN(priv_data.total_len, len + 1);
4464 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdade697412013-02-14 16:31:48 -08004465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4466 "%s: failed to copy data to user buffer", __func__);
4467 ret = -EFAULT;
4468 goto exit;
4469 }
4470 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08004471 else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0)
4472 {
4473 tANI_U8 *value = command;
4474 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4475 tANI_U8 numChannels = 0;
4476 eHalStatus status = eHAL_STATUS_SUCCESS;
4477
4478 status = hdd_parse_channellist(value, ChannelList, &numChannels);
4479 if (eHAL_STATUS_SUCCESS != status)
4480 {
4481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4482 "%s: Failed to parse channel list information", __func__);
4483 ret = -EINVAL;
4484 goto exit;
4485 }
4486
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304487 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4488 TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL,
4489 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004490 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
4491 {
4492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4493 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
4494 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
4495 ret = -EINVAL;
4496 goto exit;
4497 }
4498 status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList,
4499 numChannels);
4500 if (eHAL_STATUS_SUCCESS != status)
4501 {
4502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4503 "%s: Failed to update channel list information", __func__);
4504 ret = -EINVAL;
4505 goto exit;
4506 }
4507 }
4508 else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0)
4509 {
4510 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4511 tANI_U8 numChannels = 0;
Jeff Johnson51b67782013-04-05 12:35:41 -07004512 tANI_U8 j = 0;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004513 char extra[128] = {0};
Jeff Johnson51b67782013-04-05 12:35:41 -07004514 int len;
Srinivas Girigowdade697412013-02-14 16:31:48 -08004515
4516 if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal),
4517 ChannelList, &numChannels ))
4518 {
4519 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4520 "%s: failed to get roam scan channel list", __func__);
4521 ret = -EFAULT;
4522 goto exit;
4523 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4525 TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL,
4526 pAdapter->sessionId, numChannels));
Srinivas Girigowdade697412013-02-14 16:31:48 -08004527 /* output channel list is of the format
4528 [Number of roam scan channels][Channel1][Channel2]... */
4529 /* copy the number of channels in the 0th index */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004530 len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels);
Sushant Kaushika08ca192015-09-16 15:52:04 +05304531 for (j = 0; (j < numChannels) && len <= sizeof(extra); j++)
Srinivas Girigowdade697412013-02-14 16:31:48 -08004532 {
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004533 len += scnprintf(extra + len, sizeof(extra) - len, " %d",
4534 ChannelList[j]);
Srinivas Girigowdade697412013-02-14 16:31:48 -08004535 }
4536
Sushant Kaushikc9b8be52015-07-15 16:41:27 +05304537 len = VOS_MIN(priv_data.total_len, len + 1);
4538 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdade697412013-02-14 16:31:48 -08004539 {
4540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4541 "%s: failed to copy data to user buffer", __func__);
4542 ret = -EFAULT;
4543 goto exit;
4544 }
4545 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004546 else if (strncmp(command, "GETCCXMODE", 10) == 0)
4547 {
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004548 tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004549 char extra[32];
4550 tANI_U8 len = 0;
4551
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004552 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004553 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004554 if (eseMode &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004555 hdd_is_okc_mode_enabled(pHddCtx) &&
4556 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4557 {
4558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004559 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004560 " hence this operation is not permitted!", __func__);
4561 ret = -EPERM;
4562 goto exit;
4563 }
4564
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004565 len = scnprintf(extra, sizeof(extra), "%s %d",
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004566 "GETCCXMODE", eseMode);
Sushant Kaushikf8abd352015-07-15 16:37:49 +05304567 len = VOS_MIN(priv_data.total_len, len + 1);
4568 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004569 {
4570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4571 "%s: failed to copy data to user buffer", __func__);
4572 ret = -EFAULT;
4573 goto exit;
4574 }
4575 }
4576 else if (strncmp(command, "GETOKCMODE", 10) == 0)
4577 {
4578 tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx);
4579 char extra[32];
4580 tANI_U8 len = 0;
4581
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004582 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004583 then this operation is not permitted (return FAILURE) */
4584 if (okcMode &&
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004585 sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004586 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
4587 {
4588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004589 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07004590 " hence this operation is not permitted!", __func__);
4591 ret = -EPERM;
4592 goto exit;
4593 }
4594
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004595 len = scnprintf(extra, sizeof(extra), "%s %d",
4596 "GETOKCMODE", okcMode);
Sushant Kaushikbc2fb5c2015-07-15 16:43:16 +05304597 len = VOS_MIN(priv_data.total_len, len + 1);
4598 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004599 {
4600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4601 "%s: failed to copy data to user buffer", __func__);
4602 ret = -EFAULT;
4603 goto exit;
4604 }
4605 }
Srinivas Girigowdacb4c6412013-07-02 10:19:12 -07004606 else if (strncmp(command, "GETFASTROAM", 11) == 0)
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004607 {
4608 tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4609 char extra[32];
4610 tANI_U8 len = 0;
4611
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004612 len = scnprintf(extra, sizeof(extra), "%s %d",
4613 "GETFASTROAM", lfrMode);
Sushant Kaushik4da7ec92015-07-15 16:39:32 +05304614 len = VOS_MIN(priv_data.total_len, len + 1);
4615 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004616 {
4617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4618 "%s: failed to copy data to user buffer", __func__);
4619 ret = -EFAULT;
4620 goto exit;
4621 }
4622 }
4623 else if (strncmp(command, "GETFASTTRANSITION", 17) == 0)
4624 {
4625 tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal));
4626 char extra[32];
4627 tANI_U8 len = 0;
4628
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004629 len = scnprintf(extra, sizeof(extra), "%s %d",
4630 "GETFASTTRANSITION", ft);
Sushant Kaushik231a4452015-07-15 16:23:56 +05304631 len = VOS_MIN(priv_data.total_len, len + 1);
4632 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004633 {
4634 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4635 "%s: failed to copy data to user buffer", __func__);
4636 ret = -EFAULT;
4637 goto exit;
4638 }
4639 }
4640 else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0)
4641 {
4642 tANI_U8 *value = command;
4643 tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT;
4644
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304645 ret = hdd_drv_cmd_validate(command, 25);
4646 if (ret)
4647 goto exit;
4648
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004649 /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME<delimiter> */
4650 value = value + 26;
4651 /* Convert the value from ascii to integer */
4652 ret = kstrtou8(value, 10, &minTime);
4653 if (ret < 0)
4654 {
4655 /* If the input value is greater than max value of datatype, then also
4656 kstrtou8 fails */
4657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4658 "%s: kstrtou8 failed range [%d - %d]", __func__,
4659 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4660 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4661 ret = -EINVAL;
4662 goto exit;
4663 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004664 if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) ||
4665 (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX))
4666 {
4667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4668 "scan min channel time value %d is out of range"
4669 " (Min: %d Max: %d)", minTime,
4670 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN,
4671 CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX);
4672 ret = -EINVAL;
4673 goto exit;
4674 }
4675
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304676 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4677 TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL,
4678 pAdapter->sessionId, minTime));
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4680 "%s: Received Command to change channel min time = %d", __func__, minTime);
4681
4682 pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime;
4683 sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime);
4684 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004685 else if (strncmp(command, "SENDACTIONFRAME", 15) == 0)
4686 {
4687 tANI_U8 *value = command;
4688 tANI_U8 channel = 0;
4689 tANI_U8 dwellTime = 0;
4690 tANI_U8 bufLen = 0;
4691 tANI_U8 *buf = NULL;
4692 tSirMacAddr targetApBssid;
4693 eHalStatus status = eHAL_STATUS_SUCCESS;
4694 struct ieee80211_channel chan;
4695 tANI_U8 finalLen = 0;
4696 tANI_U8 *finalBuf = NULL;
4697 tANI_U8 temp = 0;
4698 u64 cookie;
4699 hdd_station_ctx_t *pHddStaCtx = NULL;
4700 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4701
4702 /* if not associated, no need to send action frame */
4703 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4704 {
4705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__);
4706 ret = -EINVAL;
4707 goto exit;
4708 }
4709
4710 status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel,
4711 &dwellTime, &buf, &bufLen);
4712 if (eHAL_STATUS_SUCCESS != status)
4713 {
4714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4715 "%s: Failed to parse send action frame data", __func__);
4716 ret = -EINVAL;
4717 goto exit;
4718 }
4719
4720 /* if the target bssid is different from currently associated AP,
4721 then no need to send action frame */
4722 if (VOS_TRUE != vos_mem_compare(targetApBssid,
4723 pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr)))
4724 {
4725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__);
4726 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004727 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004728 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004729 goto exit;
4730 }
4731
4732 /* if the channel number is different from operating channel then
4733 no need to send action frame */
4734 if (channel != pHddStaCtx->conn_info.operationChannel)
4735 {
4736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4737 "%s: channel(%d) is different from operating channel(%d)",
4738 __func__, channel, pHddStaCtx->conn_info.operationChannel);
4739 ret = -EINVAL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004740 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004741 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004742 goto exit;
4743 }
4744 chan.center_freq = sme_ChnToFreq(channel);
4745
4746 finalLen = bufLen + 24;
4747 finalBuf = vos_mem_malloc(finalLen);
4748 if (NULL == finalBuf)
4749 {
4750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__);
4751 ret = -ENOMEM;
Jeff Johnson11c33152013-04-16 17:52:40 -07004752 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004753 buf = NULL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004754 goto exit;
4755 }
4756 vos_mem_zero(finalBuf, finalLen);
4757
4758 /* Fill subtype */
4759 temp = SIR_MAC_MGMT_ACTION << 4;
4760 vos_mem_copy(finalBuf + 0, &temp, sizeof(temp));
4761
4762 /* Fill type */
4763 temp = SIR_MAC_MGMT_FRAME;
4764 vos_mem_copy(finalBuf + 2, &temp, sizeof(temp));
4765
4766 /* Fill destination address (bssid of the AP) */
4767 vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid));
4768
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004769 /* Fill source address (STA mac address) */
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004770 vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes));
4771
Srinivas Girigowdab27c0192013-06-03 10:19:56 -07004772 /* Fill BSSID (AP mac address) */
4773 vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid));
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004774
4775 /* Fill received buffer from 24th address */
4776 vos_mem_copy(finalBuf + 24, buf, bufLen);
4777
Jeff Johnson11c33152013-04-16 17:52:40 -07004778 /* done with the parsed buffer */
4779 vos_mem_free(buf);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08004780 buf = NULL;
Jeff Johnson11c33152013-04-16 17:52:40 -07004781
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304782#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
4783 params.chan = &chan;
4784 params.offchan = 0;
4785 params.wait = dwellTime;
4786 params.buf = finalBuf;
4787 params.len = finalLen;
4788 params.no_cck = 1;
4789 params.dont_wait_for_ack = 1;
4790 ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, &params, &cookie);
4791#else
DARAM SUDHA39eede62014-02-12 11:16:40 +05304792 wlan_hdd_mgmt_tx( NULL,
Yue Maf49ba872013-08-19 12:04:25 -07004793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4794 &(pAdapter->wdev),
4795#else
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07004796 pAdapter->dev,
Yue Maf49ba872013-08-19 12:04:25 -07004797#endif
4798 &chan, 0,
4799#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4800 NL80211_CHAN_HT20, 1,
4801#endif
4802 dwellTime, finalBuf, finalLen, 1,
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004803 1, &cookie );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05304804#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/
Srinivas Girigowda100eb322013-03-15 16:48:20 -07004805 vos_mem_free(finalBuf);
4806 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004807 else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0)
4808 {
4809 tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal));
4810 char extra[32];
4811 tANI_U8 len = 0;
4812
4813 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004814 len = scnprintf(extra, sizeof(extra), "%s %d",
4815 "GETROAMSCANCHANNELMINTIME", val);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304816 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4817 TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL,
4818 pAdapter->sessionId, val));
Sushant Kaushikbb8c52c2015-07-15 16:36:23 +05304819 len = VOS_MIN(priv_data.total_len, len + 1);
4820 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004821 {
4822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4823 "%s: failed to copy data to user buffer", __func__);
4824 ret = -EFAULT;
4825 goto exit;
4826 }
4827 }
4828 else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0)
4829 {
4830 tANI_U8 *value = command;
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004831 tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004832
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304833 ret = hdd_drv_cmd_validate(command, 18);
4834 if (ret)
4835 goto exit;
4836
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004837 /* Move pointer to ahead of SETSCANCHANNELTIME<delimiter> */
4838 value = value + 19;
4839 /* Convert the value from ascii to integer */
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004840 ret = kstrtou16(value, 10, &maxTime);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004841 if (ret < 0)
4842 {
4843 /* If the input value is greater than max value of datatype, then also
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004844 kstrtou16 fails */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu3885a662013-06-19 07:10:37 -07004846 "%s: kstrtou16 failed range [%d - %d]", __func__,
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004847 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4848 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4849 ret = -EINVAL;
4850 goto exit;
4851 }
4852
4853 if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) ||
4854 (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX))
4855 {
4856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4857 "lfr mode value %d is out of range"
4858 " (Min: %d Max: %d)", maxTime,
4859 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN,
4860 CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX);
4861 ret = -EINVAL;
4862 goto exit;
4863 }
4864
4865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4866 "%s: Received Command to change channel max time = %d", __func__, maxTime);
4867
4868 pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime;
4869 sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime);
4870 }
4871 else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0)
4872 {
4873 tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal));
4874 char extra[32];
4875 tANI_U8 len = 0;
4876
4877 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004878 len = scnprintf(extra, sizeof(extra), "%s %d",
4879 "GETSCANCHANNELTIME", val);
Ratheesh S Pacbfa932015-07-16 15:27:18 +05304880 len = VOS_MIN(priv_data.total_len, len + 1);
4881 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004882 {
4883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4884 "%s: failed to copy data to user buffer", __func__);
4885 ret = -EFAULT;
4886 goto exit;
4887 }
4888 }
4889 else if (strncmp(command, "SETSCANHOMETIME", 15) == 0)
4890 {
4891 tANI_U8 *value = command;
4892 tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT;
4893
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304894 ret = hdd_drv_cmd_validate(command, 15);
4895 if (ret)
4896 goto exit;
4897
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004898 /* Move pointer to ahead of SETSCANHOMETIME<delimiter> */
4899 value = value + 16;
4900 /* Convert the value from ascii to integer */
4901 ret = kstrtou16(value, 10, &val);
4902 if (ret < 0)
4903 {
4904 /* If the input value is greater than max value of datatype, then also
4905 kstrtou16 fails */
4906 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4907 "%s: kstrtou16 failed range [%d - %d]", __func__,
4908 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4909 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4910 ret = -EINVAL;
4911 goto exit;
4912 }
4913
4914 if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) ||
4915 (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX))
4916 {
4917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4918 "scan home time value %d is out of range"
4919 " (Min: %d Max: %d)", val,
4920 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN,
4921 CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX);
4922 ret = -EINVAL;
4923 goto exit;
4924 }
4925
4926 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4927 "%s: Received Command to change scan home time = %d", __func__, val);
4928
4929 pHddCtx->cfg_ini->nNeighborScanPeriod = val;
4930 sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val);
4931 }
4932 else if (strncmp(command, "GETSCANHOMETIME", 15) == 0)
4933 {
4934 tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal));
4935 char extra[32];
4936 tANI_U8 len = 0;
4937
4938 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004939 len = scnprintf(extra, sizeof(extra), "%s %d",
4940 "GETSCANHOMETIME", val);
Ratheesh S P728d7c62015-07-16 15:38:58 +05304941 len = VOS_MIN(priv_data.total_len, len + 1);
4942 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004943 {
4944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4945 "%s: failed to copy data to user buffer", __func__);
4946 ret = -EFAULT;
4947 goto exit;
4948 }
4949 }
4950 else if (strncmp(command, "SETROAMINTRABAND", 16) == 0)
4951 {
4952 tANI_U8 *value = command;
4953 tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT;
4954
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05304955 ret = hdd_drv_cmd_validate(command, 16);
4956 if (ret)
4957 goto exit;
4958
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004959 /* Move pointer to ahead of SETROAMINTRABAND<delimiter> */
4960 value = value + 17;
4961 /* Convert the value from ascii to integer */
4962 ret = kstrtou8(value, 10, &val);
4963 if (ret < 0)
4964 {
4965 /* If the input value is greater than max value of datatype, then also
4966 kstrtou8 fails */
4967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4968 "%s: kstrtou8 failed range [%d - %d]", __func__,
4969 CFG_ROAM_INTRA_BAND_MIN,
4970 CFG_ROAM_INTRA_BAND_MAX);
4971 ret = -EINVAL;
4972 goto exit;
4973 }
4974
4975 if ((val < CFG_ROAM_INTRA_BAND_MIN) ||
4976 (val > CFG_ROAM_INTRA_BAND_MAX))
4977 {
4978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4979 "intra band mode value %d is out of range"
4980 " (Min: %d Max: %d)", val,
4981 CFG_ROAM_INTRA_BAND_MIN,
4982 CFG_ROAM_INTRA_BAND_MAX);
4983 ret = -EINVAL;
4984 goto exit;
4985 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4987 "%s: Received Command to change intra band = %d", __func__, val);
4988
4989 pHddCtx->cfg_ini->nRoamIntraBand = val;
4990 sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val);
4991 }
4992 else if (strncmp(command, "GETROAMINTRABAND", 16) == 0)
4993 {
4994 tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal));
4995 char extra[32];
4996 tANI_U8 len = 0;
4997
4998 /* value is interms of msec */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07004999 len = scnprintf(extra, sizeof(extra), "%s %d",
5000 "GETROAMINTRABAND", val);
Ratheesh S P2dd2a3e2015-07-16 15:34:23 +05305001 len = VOS_MIN(priv_data.total_len, len + 1);
5002 if (copy_to_user(priv_data.buf, &extra, len))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005003 {
5004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5005 "%s: failed to copy data to user buffer", __func__);
5006 ret = -EFAULT;
5007 goto exit;
5008 }
5009 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005010 else if (strncmp(command, "SETSCANNPROBES", 14) == 0)
5011 {
5012 tANI_U8 *value = command;
5013 tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT;
5014
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305015 ret = hdd_drv_cmd_validate(command, 14);
5016 if (ret)
5017 goto exit;
5018
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005019 /* Move pointer to ahead of SETSCANNPROBES<delimiter> */
5020 value = value + 15;
5021 /* Convert the value from ascii to integer */
5022 ret = kstrtou8(value, 10, &nProbes);
5023 if (ret < 0)
5024 {
5025 /* If the input value is greater than max value of datatype, then also
5026 kstrtou8 fails */
5027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5028 "%s: kstrtou8 failed range [%d - %d]", __func__,
5029 CFG_ROAM_SCAN_N_PROBES_MIN,
5030 CFG_ROAM_SCAN_N_PROBES_MAX);
5031 ret = -EINVAL;
5032 goto exit;
5033 }
5034
5035 if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) ||
5036 (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX))
5037 {
5038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5039 "NProbes value %d is out of range"
5040 " (Min: %d Max: %d)", nProbes,
5041 CFG_ROAM_SCAN_N_PROBES_MIN,
5042 CFG_ROAM_SCAN_N_PROBES_MAX);
5043 ret = -EINVAL;
5044 goto exit;
5045 }
5046
5047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5048 "%s: Received Command to Set nProbes = %d", __func__, nProbes);
5049
5050 pHddCtx->cfg_ini->nProbes = nProbes;
5051 sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes);
5052 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305053 else if (strncmp(command, "GETSCANNPROBES", 14) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005054 {
5055 tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal));
5056 char extra[32];
5057 tANI_U8 len = 0;
5058
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005059 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri6da525d2015-08-07 13:55:54 +05305060 len = VOS_MIN(priv_data.total_len, len + 1);
5061 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5063 "%s: failed to copy data to user buffer", __func__);
5064 ret = -EFAULT;
5065 goto exit;
5066 }
5067 }
5068 else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0)
5069 {
5070 tANI_U8 *value = command;
5071 tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT;
5072
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305073 ret = hdd_drv_cmd_validate(command, 19);
5074 if (ret)
5075 goto exit;
5076
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005077 /* Move pointer to ahead of SETSCANHOMEAWAYTIME<delimiter> */
5078 /* input value is in units of msec */
5079 value = value + 20;
5080 /* Convert the value from ascii to integer */
5081 ret = kstrtou16(value, 10, &homeAwayTime);
5082 if (ret < 0)
5083 {
5084 /* If the input value is greater than max value of datatype, then also
5085 kstrtou8 fails */
5086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5087 "%s: kstrtou8 failed range [%d - %d]", __func__,
5088 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5089 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5090 ret = -EINVAL;
5091 goto exit;
5092 }
5093
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005094 if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) ||
5095 (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX))
5096 {
5097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5098 "homeAwayTime value %d is out of range"
5099 " (Min: %d Max: %d)", homeAwayTime,
5100 CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN,
5101 CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX);
5102 ret = -EINVAL;
5103 goto exit;
5104 }
5105
5106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5107 "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime);
Srinivas Girigowda6cf0b822013-06-27 14:00:20 -07005108 if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime)
5109 {
5110 pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime;
5111 sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE);
5112 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005113 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305114 else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005115 {
5116 tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal));
5117 char extra[32];
5118 tANI_U8 len = 0;
5119
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005120 len = scnprintf(extra, sizeof(extra), "%s %d", command, val);
Ratnam Rachuri51a5ad12015-08-07 14:06:37 +05305121 len = VOS_MIN(priv_data.total_len, len + 1);
5122 if (copy_to_user(priv_data.buf, &extra, len)) {
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5124 "%s: failed to copy data to user buffer", __func__);
5125 ret = -EFAULT;
5126 goto exit;
5127 }
5128 }
5129 else if (strncmp(command, "REASSOC", 7) == 0)
5130 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305131 ret = hdd_drv_cmd_validate(command, 7);
5132 if (ret)
5133 goto exit;
5134
5135 ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len);
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05305136 if (!ret)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005137 goto exit;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005138 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005139 else if (strncmp(command, "SETWESMODE", 10) == 0)
5140 {
5141 tANI_U8 *value = command;
5142 tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT;
5143
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305144 ret = hdd_drv_cmd_validate(command, 10);
5145 if (ret)
5146 goto exit;
5147
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005148 /* Move pointer to ahead of SETWESMODE<delimiter> */
5149 value = value + 11;
5150 /* Convert the value from ascii to integer */
5151 ret = kstrtou8(value, 10, &wesMode);
5152 if (ret < 0)
5153 {
5154 /* If the input value is greater than max value of datatype, then also
5155 kstrtou8 fails */
5156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5157 "%s: kstrtou8 failed range [%d - %d]", __func__,
5158 CFG_ENABLE_WES_MODE_NAME_MIN,
5159 CFG_ENABLE_WES_MODE_NAME_MAX);
5160 ret = -EINVAL;
5161 goto exit;
5162 }
5163
5164 if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) ||
5165 (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX))
5166 {
5167 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5168 "WES Mode value %d is out of range"
5169 " (Min: %d Max: %d)", wesMode,
5170 CFG_ENABLE_WES_MODE_NAME_MIN,
5171 CFG_ENABLE_WES_MODE_NAME_MAX);
5172 ret = -EINVAL;
5173 goto exit;
5174 }
5175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5176 "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode);
5177
5178 pHddCtx->cfg_ini->isWESModeEnabled = wesMode;
5179 sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode);
5180 }
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305181 else if (strncmp(command, "GETWESMODE", 10) == 0)
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005182 {
5183 tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal));
5184 char extra[32];
5185 tANI_U8 len = 0;
5186
Arif Hussain826d9412013-11-12 16:44:54 -08005187 len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode);
Ratnam Rachuri8fe90c62015-08-07 14:03:26 +05305188 len = VOS_MIN(priv_data.total_len, len + 1);
5189 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5191 "%s: failed to copy data to user buffer", __func__);
5192 ret = -EFAULT;
5193 goto exit;
5194 }
5195 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005196#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005197#ifdef FEATURE_WLAN_LFR
5198 else if (strncmp(command, "SETFASTROAM", 11) == 0)
5199 {
5200 tANI_U8 *value = command;
5201 tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT;
5202
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05305203 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
5204 hddLog(LOGE,
5205 FL("Roaming is always disabled in STA + MON concurrency"));
5206 ret = -EINVAL;
5207 goto exit;
5208 }
5209
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305210 ret = hdd_drv_cmd_validate(command, 11);
5211 if (ret)
5212 goto exit;
5213
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005214 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5215 value = value + 12;
5216 /* Convert the value from ascii to integer */
5217 ret = kstrtou8(value, 10, &lfrMode);
5218 if (ret < 0)
5219 {
5220 /* If the input value is greater than max value of datatype, then also
5221 kstrtou8 fails */
5222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5223 "%s: kstrtou8 failed range [%d - %d]", __func__,
5224 CFG_LFR_FEATURE_ENABLED_MIN,
5225 CFG_LFR_FEATURE_ENABLED_MAX);
5226 ret = -EINVAL;
5227 goto exit;
5228 }
5229
5230 if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) ||
5231 (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX))
5232 {
5233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5234 "lfr mode value %d is out of range"
5235 " (Min: %d Max: %d)", lfrMode,
5236 CFG_LFR_FEATURE_ENABLED_MIN,
5237 CFG_LFR_FEATURE_ENABLED_MAX);
5238 ret = -EINVAL;
5239 goto exit;
5240 }
5241
5242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5243 "%s: Received Command to change lfr mode = %d", __func__, lfrMode);
5244
5245 pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode;
5246 sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode);
5247 }
5248#endif
5249#ifdef WLAN_FEATURE_VOWIFI_11R
5250 else if (strncmp(command, "SETFASTTRANSITION", 17) == 0)
5251 {
5252 tANI_U8 *value = command;
5253 tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT;
5254
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305255 ret = hdd_drv_cmd_validate(command, 17);
5256 if (ret)
5257 goto exit;
5258
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005259 /* Move pointer to ahead of SETFASTROAM<delimiter> */
5260 value = value + 18;
5261 /* Convert the value from ascii to integer */
5262 ret = kstrtou8(value, 10, &ft);
5263 if (ret < 0)
5264 {
5265 /* If the input value is greater than max value of datatype, then also
5266 kstrtou8 fails */
5267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5268 "%s: kstrtou8 failed range [%d - %d]", __func__,
5269 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5270 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5271 ret = -EINVAL;
5272 goto exit;
5273 }
5274
5275 if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) ||
5276 (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX))
5277 {
5278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5279 "ft mode value %d is out of range"
5280 " (Min: %d Max: %d)", ft,
5281 CFG_FAST_TRANSITION_ENABLED_NAME_MIN,
5282 CFG_FAST_TRANSITION_ENABLED_NAME_MAX);
5283 ret = -EINVAL;
5284 goto exit;
5285 }
5286
5287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5288 "%s: Received Command to change ft mode = %d", __func__, ft);
5289
5290 pHddCtx->cfg_ini->isFastTransitionEnabled = ft;
5291 sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft);
5292 }
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305293 else if (strncmp(command, "SETDFSSCANMODE", 14) == 0)
5294 {
5295 tANI_U8 *value = command;
5296 tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305297
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305298 ret = hdd_drv_cmd_validate(command, 14);
5299 if (ret)
5300 goto exit;
5301
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305302 /* Move pointer to ahead of SETDFSSCANMODE<delimiter> */
5303 value = value + 15;
5304 /* Convert the value from ascii to integer */
5305 ret = kstrtou8(value, 10, &dfsScanMode);
5306 if (ret < 0)
5307 {
5308 /* If the input value is greater than max value of
5309 datatype, then also kstrtou8 fails
5310 */
5311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5312 "%s: kstrtou8 failed range [%d - %d]", __func__,
5313 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5314 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5315 ret = -EINVAL;
5316 goto exit;
5317 }
5318
5319 if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) ||
5320 (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX))
5321 {
5322 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5323 "dfsScanMode value %d is out of range"
5324 " (Min: %d Max: %d)", dfsScanMode,
5325 CFG_ENABLE_DFS_CHNL_SCAN_MIN,
5326 CFG_ENABLE_DFS_CHNL_SCAN_MAX);
5327 ret = -EINVAL;
5328 goto exit;
5329 }
5330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5331 "%s: Received Command to Set DFS Scan Mode = %d",
5332 __func__, dfsScanMode);
5333
5334 ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode);
5335 }
5336 else if (strncmp(command, "GETDFSSCANMODE", 14) == 0)
5337 {
5338 tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal);
5339 char extra[32];
5340 tANI_U8 len = 0;
5341
5342 len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode);
Ratheesh S P767224e2015-07-16 15:35:51 +05305343 len = VOS_MIN(priv_data.total_len, len + 1);
5344 if (copy_to_user(priv_data.buf, &extra, len))
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +05305345 {
5346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5347 "%s: failed to copy data to user buffer", __func__);
5348 ret = -EFAULT;
5349 goto exit;
5350 }
5351 }
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305352 else if (strncmp(command, "FASTREASSOC", 11) == 0)
5353 {
Selvaraj, Sridhar3714c4d2016-06-22 15:19:12 +05305354 ret = wlan_hdd_handle_fastreassoc(pAdapter, command);
5355 if (!ret)
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305356 goto exit;
Madan Mohan Koyyalamudi48101412013-09-11 23:09:37 +05305357 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005358#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005359#ifdef FEATURE_WLAN_ESE
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005360 else if (strncmp(command, "SETCCXMODE", 10) == 0)
5361 {
5362 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005363 tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005364
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305365 ret = hdd_drv_cmd_validate(command, 10);
5366 if (ret)
5367 goto exit;
5368
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005369 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005370 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005371 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005372 hdd_is_okc_mode_enabled(pHddCtx) &&
5373 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5374 {
5375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005376 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005377 " hence this operation is not permitted!", __func__);
5378 ret = -EPERM;
5379 goto exit;
5380 }
5381
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005382 /* Move pointer to ahead of SETCCXMODE<delimiter> */
5383 value = value + 11;
5384 /* Convert the value from ascii to integer */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005385 ret = kstrtou8(value, 10, &eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005386 if (ret < 0)
5387 {
5388 /* If the input value is greater than max value of datatype, then also
5389 kstrtou8 fails */
5390 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5391 "%s: kstrtou8 failed range [%d - %d]", __func__,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005392 CFG_ESE_FEATURE_ENABLED_MIN,
5393 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005394 ret = -EINVAL;
5395 goto exit;
5396 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005397 if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) ||
5398 (eseMode > CFG_ESE_FEATURE_ENABLED_MAX))
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005399 {
5400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005401 "Ese mode value %d is out of range"
5402 " (Min: %d Max: %d)", eseMode,
5403 CFG_ESE_FEATURE_ENABLED_MIN,
5404 CFG_ESE_FEATURE_ENABLED_MAX);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005405 ret = -EINVAL;
5406 goto exit;
5407 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005409 "%s: Received Command to change ese mode = %d", __func__, eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005410
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005411 pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode;
5412 sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005413 }
5414#endif
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005415 else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0)
5416 {
5417 tANI_U8 *value = command;
5418 tANI_BOOLEAN roamScanControl = 0;
5419
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305420 ret = hdd_drv_cmd_validate(command, 18);
5421 if (ret)
5422 goto exit;
5423
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005424 /* Move pointer to ahead of SETROAMSCANCONTROL<delimiter> */
5425 value = value + 19;
5426 /* Convert the value from ascii to integer */
5427 ret = kstrtou8(value, 10, &roamScanControl);
5428 if (ret < 0)
5429 {
5430 /* If the input value is greater than max value of datatype, then also
5431 kstrtou8 fails */
5432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5433 "%s: kstrtou8 failed ", __func__);
5434 ret = -EINVAL;
5435 goto exit;
5436 }
5437
5438 if (0 != roamScanControl)
5439 {
5440 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5441 "roam scan control invalid value = %d",
5442 roamScanControl);
5443 ret = -EINVAL;
5444 goto exit;
5445 }
5446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5447 "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl);
5448
5449 sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl);
5450 }
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005451#ifdef FEATURE_WLAN_OKC
5452 else if (strncmp(command, "SETOKCMODE", 10) == 0)
5453 {
5454 tANI_U8 *value = command;
5455 tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT;
5456
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305457 ret = hdd_drv_cmd_validate(command, 10);
5458 if (ret)
5459 goto exit;
5460
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005461 /* Check if the features OKC/ESE/11R are supported simultaneously,
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005462 then this operation is not permitted (return FAILURE) */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005463 if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) &&
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005464 hdd_is_okc_mode_enabled(pHddCtx) &&
5465 sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)))
5466 {
5467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005468 "%s: OKC/ESE/11R are supported simultaneously"
Srinivas Girigowdac6745a32013-07-15 19:19:10 -07005469 " hence this operation is not permitted!", __func__);
5470 ret = -EPERM;
5471 goto exit;
5472 }
5473
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07005474 /* Move pointer to ahead of SETOKCMODE<delimiter> */
5475 value = value + 11;
5476 /* Convert the value from ascii to integer */
5477 ret = kstrtou8(value, 10, &okcMode);
5478 if (ret < 0)
5479 {
5480 /* If the input value is greater than max value of datatype, then also
5481 kstrtou8 fails */
5482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5483 "%s: kstrtou8 failed range [%d - %d]", __func__,
5484 CFG_OKC_FEATURE_ENABLED_MIN,
5485 CFG_OKC_FEATURE_ENABLED_MAX);
5486 ret = -EINVAL;
5487 goto exit;
5488 }
5489
5490 if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) ||
5491 (okcMode > CFG_OKC_FEATURE_ENABLED_MAX))
5492 {
5493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5494 "Okc mode value %d is out of range"
5495 " (Min: %d Max: %d)", okcMode,
5496 CFG_OKC_FEATURE_ENABLED_MIN,
5497 CFG_OKC_FEATURE_ENABLED_MAX);
5498 ret = -EINVAL;
5499 goto exit;
5500 }
5501
5502 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5503 "%s: Received Command to change okc mode = %d", __func__, okcMode);
5504
5505 pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode;
5506 }
Srinivas Girigowdaad34ca92013-10-22 10:54:29 -07005507#endif /* FEATURE_WLAN_OKC */
Mahesh A Saptasagarec7d1092015-04-02 13:41:34 +05305508 else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0)
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005509 {
5510 tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal));
5511 char extra[32];
5512 tANI_U8 len = 0;
5513
Sameer Thalappilb0a30232013-09-27 15:37:48 -07005514 len = scnprintf(extra, sizeof(extra), "%s %d",
5515 command, roamScanControl);
Ratnam Rachuri083ada82015-08-07 14:01:05 +05305516 len = VOS_MIN(priv_data.total_len, len + 1);
5517 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda100eb322013-03-15 16:48:20 -07005518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5519 "%s: failed to copy data to user buffer", __func__);
5520 ret = -EFAULT;
5521 goto exit;
5522 }
5523 }
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305524#ifdef WLAN_FEATURE_PACKET_FILTERING
5525 else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0)
5526 {
5527 tANI_U8 filterType = 0;
5528 tANI_U8 *value = command;
5529
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305530 ret = hdd_drv_cmd_validate(command, 21);
5531 if (ret)
5532 goto exit;
5533
Gopichand Nakkala227c7f32013-06-26 22:44:57 +05305534 /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6<delimiter> */
5535 value = value + 22;
5536
5537 /* Convert the value from ascii to integer */
5538 ret = kstrtou8(value, 10, &filterType);
5539 if (ret < 0)
5540 {
5541 /* If the input value is greater than max value of datatype,
5542 * then also kstrtou8 fails
5543 */
5544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5545 "%s: kstrtou8 failed range ", __func__);
5546 ret = -EINVAL;
5547 goto exit;
5548 }
5549
5550 if (filterType != 0 && filterType != 1)
5551 {
5552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5553 "%s: Accepted Values are 0 and 1 ", __func__);
5554 ret = -EINVAL;
5555 goto exit;
5556 }
5557 wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType,
5558 pAdapter->sessionId);
5559 }
5560#endif
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305561 else if (strncmp(command, "BTCOEXMODE", 10) == 0 )
5562 {
Kiet Lamad161252014-07-22 11:23:32 -07005563 char *dhcpPhase;
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305564 int ret;
5565
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305566 ret = hdd_drv_cmd_validate(command, 10);
5567 if (ret)
5568 goto exit;
5569
Kiet Lamad161252014-07-22 11:23:32 -07005570 dhcpPhase = command + 11;
5571 if ('1' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305572 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005574 FL("send DHCP START indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305575
5576 pHddCtx->btCoexModeSet = TRUE;
Kiet Lamad161252014-07-22 11:23:32 -07005577
Satyanarayana Dash1faea4f2014-09-22 16:21:04 +05305578 ret = wlan_hdd_scan_abort(pAdapter);
5579 if (ret < 0)
5580 {
5581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5582 FL("failed to abort existing scan %d"), ret);
5583 }
5584
Kiet Lamad161252014-07-22 11:23:32 -07005585 sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode,
5586 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305587 }
Kiet Lamad161252014-07-22 11:23:32 -07005588 else if ('2' == *dhcpPhase)
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305589 {
Deepthi Gowribfd17132014-11-14 17:59:04 +05305590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiet Lamad161252014-07-22 11:23:32 -07005591 FL("send DHCP STOP indication"));
c_hpothu9b781ba2013-12-30 20:57:45 +05305592
5593 pHddCtx->btCoexModeSet = FALSE;
Kiet Lamad161252014-07-22 11:23:32 -07005594
5595 sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode,
5596 pAdapter->sessionId);
Sundaresan Ramachandran76e48e82013-07-15 13:07:17 +05305597 }
5598 }
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005599 else if (strncmp(command, "SCAN-ACTIVE", 11) == 0)
5600 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305601 hddLog(LOG1,
5602 FL("making default scan to ACTIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305603 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005604 }
5605 else if (strncmp(command, "SCAN-PASSIVE", 12) == 0)
5606 {
Abhishek Singh58749d62016-02-03 15:27:20 +05305607 hddLog(LOG1,
5608 FL("making default scan to PASSIVE"));
c_hpothudbefd3e2014-04-28 15:59:47 +05305609 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnsonf54df2c2013-07-24 11:43:39 -07005610 }
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305611 else if (strncmp(command, "GETDWELLTIME", 12) == 0)
5612 {
5613 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5614 char extra[32];
5615 tANI_U8 len = 0;
5616
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305617 memset(extra, 0, sizeof(extra));
5618 ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len);
Ratnam Rachuri12d5d462015-08-07 14:10:23 +05305619 len = VOS_MIN(priv_data.total_len, len + 1);
5620 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5622 "%s: failed to copy data to user buffer", __func__);
5623 ret = -EFAULT;
5624 goto exit;
5625 }
5626 ret = len;
5627 }
5628 else if (strncmp(command, "SETDWELLTIME", 12) == 0)
5629 {
Rajesh Babu Prathipatic7baf6f2014-05-30 10:08:16 +05305630 ret = hdd_set_dwell_time(pAdapter, command);
Hanumantha Reddy Pothula212243c2013-08-01 17:28:31 +05305631 }
Dundi Ravitejaae5adf42018-04-23 20:44:47 +05305632 else if (strncmp(command, "BTCGETDWELLTIME", 15) == 0)
5633 {
5634 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5635 char extra[32];
5636 tANI_U8 len = 0;
5637
5638 if (hdd_drv_cmd_validate(command, 15)) {
5639 hddLog(LOGE, FL("Invalid driver command"));
5640 return -EINVAL;
5641 }
5642
5643 memset(extra, 0, sizeof(extra));
5644 ret = hdd_btc_get_dwell_time(pCfg, command, extra,
5645 sizeof(extra), &len);
5646 len = VOS_MIN(priv_data.total_len, len + 1);
5647 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5648 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5649 ret = -EFAULT;
5650 goto exit;
5651 }
5652 ret = len;
5653 }
5654 else if (strncmp(command, "BTCSETDWELLTIME", 15) == 0)
5655 {
5656 if (hdd_drv_cmd_validate(command, 15)) {
5657 hddLog(LOGE, FL("Invalid driver command"));
5658 return -EINVAL;
5659 }
5660 ret = hdd_btc_set_dwell_time(pAdapter, command);
5661 }
5662#ifdef WLAN_AP_STA_CONCURRENCY
5663 else if (strncmp(command, "CONCGETDWELLTIME", 16) == 0)
5664 {
5665 hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5666 char extra[32];
5667 tANI_U8 len = 0;
5668
5669 if (hdd_drv_cmd_validate(command, 16)) {
5670 hddLog(LOGE, FL("Invalid driver command"));
5671 return -EINVAL;
5672 }
5673
5674 memset(extra, 0, sizeof(extra));
5675 ret = hdd_conc_get_dwell_time(pCfg, command, extra,
5676 sizeof(extra), &len);
5677 len = VOS_MIN(priv_data.total_len, len + 1);
5678 if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) {
5679 hddLog(LOGE, FL("Failed to copy data to user buffer"));
5680 ret = -EFAULT;
5681 goto exit;
5682 }
5683 ret = len;
5684 }
5685 else if (strncmp(command, "CONCSETDWELLTIME", 16) == 0)
5686 {
5687 if (hdd_drv_cmd_validate(command, 16)) {
5688 hddLog(LOGE, FL("Invalid driver command"));
5689 return -EINVAL;
5690 }
5691 ret = hdd_conc_set_dwell_time(pAdapter, command);
5692 }
5693#endif
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005694 else if ( strncasecmp(command, "MIRACAST", 8) == 0 )
5695 {
5696 tANI_U8 filterType = 0;
5697 tANI_U8 *value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305698
5699 ret = hdd_drv_cmd_validate(command, 8);
5700 if (ret)
5701 goto exit;
5702
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005703 value = command + 9;
5704
5705 /* Convert the value from ascii to integer */
5706 ret = kstrtou8(value, 10, &filterType);
5707 if (ret < 0)
5708 {
5709 /* If the input value is greater than max value of datatype,
5710 * then also kstrtou8 fails
5711 */
5712 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5713 "%s: kstrtou8 failed range ", __func__);
5714 ret = -EINVAL;
5715 goto exit;
5716 }
5717 if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) ||
5718 (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL))
5719 {
5720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5721 "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source,"
5722 " 2-Sink ", __func__);
5723 ret = -EINVAL;
5724 goto exit;
5725 }
5726 //Filtertype value should be either 0-Disabled, 1-Source, 2-sink
5727 pHddCtx->drvr_miracast = filterType;
Kaushik, Sushant96122442014-10-21 16:40:18 +05305728 pScanInfo = &pHddCtx->scan_info;
5729 if (filterType && pScanInfo != NULL &&
5730 pHddCtx->scan_info.mScanPending)
5731 {
5732 /*Miracast Session started. Abort Scan */
5733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5734 "%s, Aborting Scan For Miracast",__func__);
5735 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
5736 eCSR_SCAN_ABORT_DEFAULT);
5737 }
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005738 hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx);
Ganesh Kondabattini8f6e3b32014-08-25 16:07:54 +05305739 sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast);
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -07005740 }
Leo Chang614d2072013-08-22 14:59:44 -07005741 else if (strncmp(command, "SETMCRATE", 9) == 0)
5742 {
Leo Chang614d2072013-08-22 14:59:44 -07005743 tANI_U8 *value = command;
5744 int targetRate;
Leo Chang1f98cbd2013-10-17 15:03:52 -07005745 tSirRateUpdateInd *rateUpdate;
5746 eHalStatus status;
Leo Chang614d2072013-08-22 14:59:44 -07005747
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05305748 ret = hdd_drv_cmd_validate(command, 9);
5749 if (ret)
5750 goto exit;
5751
Leo Chang614d2072013-08-22 14:59:44 -07005752 /* Only valid for SAP mode */
5753 if (WLAN_HDD_SOFTAP != pAdapter->device_mode)
5754 {
5755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5756 "%s: SAP mode is not running", __func__);
5757 ret = -EFAULT;
5758 goto exit;
5759 }
5760
5761 /* Move pointer to ahead of SETMCRATE<delimiter> */
5762 /* input value is in units of hundred kbps */
5763 value = value + 10;
5764 /* Convert the value from ascii to integer, decimal base */
5765 ret = kstrtouint(value, 10, &targetRate);
5766
Leo Chang1f98cbd2013-10-17 15:03:52 -07005767 rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd));
5768 if (NULL == rateUpdate)
Leo Chang614d2072013-08-22 14:59:44 -07005769 {
Leo Chang1f98cbd2013-10-17 15:03:52 -07005770 hddLog(VOS_TRACE_LEVEL_ERROR,
5771 "%s: SETMCRATE indication alloc fail", __func__);
5772 ret = -EFAULT;
5773 goto exit;
5774 }
5775 vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd ));
5776
5777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5778 "MC Target rate %d", targetRate);
5779 /* Ignore unicast */
5780 rateUpdate->ucastDataRate = -1;
5781 rateUpdate->mcastDataRate24GHz = targetRate;
5782 rateUpdate->mcastDataRate5GHz = targetRate;
5783 rateUpdate->mcastDataRate24GHzTxFlag = 0;
5784 rateUpdate->mcastDataRate5GHzTxFlag = 0;
5785 status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate);
5786 if (eHAL_STATUS_SUCCESS != status)
5787 {
5788 hddLog(VOS_TRACE_LEVEL_ERROR,
5789 "%s: SET_MC_RATE failed", __func__);
5790 vos_mem_free(rateUpdate);
5791 ret = -EFAULT;
5792 goto exit;
Leo Chang614d2072013-08-22 14:59:44 -07005793 }
5794 }
jge35567202017-06-21 16:39:38 +08005795 else if (strncmp(command, "MAXTXPOWER", 10) == 0)
5796 {
5797 int status;
5798 int txPower;
5799 eHalStatus smeStatus;
5800 tANI_U8 *value = command;
5801 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5802 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
5803
5804 status = hdd_parse_setmaxtxpower_command(value, &txPower);
5805 if (status)
5806 {
5807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5808 "Invalid MAXTXPOWER command ");
5809 ret = -EINVAL;
5810 goto exit;
5811 }
5812
5813 hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: "
5814 MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ",
5815 txPower, MAC_ADDR_ARRAY(selfMac),
5816 MAC_ADDR_ARRAY(bssid));
5817 smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal),
5818 bssid, selfMac, txPower) ;
5819 if( smeStatus != eHAL_STATUS_SUCCESS )
5820 {
5821 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed",
5822 __func__);
5823 ret = -EINVAL;
5824 goto exit;
5825 }
5826
5827 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success",
5828 __func__);
5829 }
Rajeev79dbe4c2013-10-05 11:03:42 +05305830#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev Kumar8b373292014-01-08 20:36:55 -08005831 else if (strncmp(command, "WLS_BATCHING", 12) == 0)
Rajeev79dbe4c2013-10-05 11:03:42 +05305832 {
Rajeev Kumar8b373292014-01-08 20:36:55 -08005833 ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command);
Rajeev79dbe4c2013-10-05 11:03:42 +05305834 }
5835#endif
Abhishek Singh00b71972016-01-07 10:51:04 +05305836#ifdef WLAN_FEATURE_RMC
5837 else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) &&
5838 (WLAN_HDD_IBSS == pAdapter->device_mode))
5839 {
5840 int i = 0;
5841 tANI_U8 *ibss_ie;
5842 tANI_U32 command_len;
5843 tANI_U8 *value = command;
5844 tHalHandle hHal = pHddCtx->hHal;
5845 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5846 tANI_U32 ibss_ie_length;
5847 tANI_U32 len, present;
5848 tANI_U8 *addIE;
5849 tANI_U8 *addIEData;
5850
5851 hddLog(LOG1,
5852 FL(" received command %s"),((char *) value));
5853 /* validate argument of command */
5854 if (strlen(value) <= 21)
5855 {
5856 hddLog(LOGE,
5857 FL("No arguements in command length %zu"), strlen(value));
5858 ret = -EFAULT;
5859 goto exit;
5860 }
5861
5862 /* moving to arguments of commands */
5863 value = value + 21;
5864 command_len = strlen(value);
5865
5866 /* oui_data can't be less than 3 bytes */
5867 if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH))
5868 {
5869 hddLog(LOGE,
5870 FL("Invalid SETIBSSBEACONOUIDATA command length %d"),
5871 command_len);
5872 ret = -EFAULT;
5873 goto exit;
5874 }
5875 ibss_ie = vos_mem_malloc(command_len);
5876 if (!ibss_ie) {
5877 hddLog(LOGE,
5878 FL("Could not allocate memory for command length %d"),
5879 command_len);
5880 ret = -ENOMEM;
5881 goto exit;
5882 }
5883 vos_mem_zero(ibss_ie, command_len);
5884
5885 ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie,
5886 command_len);
5887 if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) {
5888 hddLog(LOGE, FL("Could not parse command %s return length %d"),
5889 value, ibss_ie_length);
5890 ret = -EFAULT;
5891 vos_mem_free(ibss_ie);
5892 goto exit;
5893 }
5894
5895 hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length);
5896 while (i < ibss_ie_length)
5897 hddLog(LOG1, FL("0x%x"), ibss_ie[i++]);
5898
5899 /* Populate Vendor IE in Beacon */
5900 if ((ccmCfgGetInt(hHal,
5901 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
5902 &present)) != eHAL_STATUS_SUCCESS)
5903 {
5904 hddLog(LOGE,
5905 FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5906 ret = -EFAULT;
5907 vos_mem_free(ibss_ie);
5908 goto exit;
5909 }
5910
5911 addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5912 if (!addIE) {
5913 hddLog(LOGE,
5914 FL("Could not allocate memory for command length %d"),
5915 command_len);
5916 vos_mem_free(ibss_ie);
5917 ret = -ENOMEM;
5918 goto exit;
5919 }
5920 vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN);
5921
5922 if (present)
5923 {
5924 if ((wlan_cfgGetStrLen(pMac,
5925 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS)
5926 {
5927 hddLog(LOGE,
5928 FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN"));
5929 ret = -EFAULT;
5930 vos_mem_free(ibss_ie);
5931 vos_mem_free(addIE);
5932 goto exit;
5933 }
5934
5935 if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
5936 ((len + ibss_ie_length) <=
5937 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN))
5938 {
5939 if ((ccmCfgGetStr(hHal,
5940 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len))
5941 != eHAL_STATUS_SUCCESS)
5942 {
5943 hddLog(LOGE,
5944 FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA"));
5945 ret = -EFAULT;
5946 vos_mem_free(ibss_ie);
5947 vos_mem_free(addIE);
5948 goto exit;
5949 }
5950 else
5951 {
5952 /* Curruntly only WPA IE is added before Vendor IE
5953 * so we can blindly place the Vendor IE after WPA
5954 * IE. If no WPA IE found replace all with Vendor IE.
5955 */
5956 len = hdd_find_ibss_wpa_ie_pos(addIE, len);
5957 }
5958 }
5959 else
5960 {
5961 hddLog(LOGE,
5962 FL("IE len exceed limit len %d,ibss_ie_length %d "),
5963 len, ibss_ie_length);
5964 ret = -EFAULT;
5965 vos_mem_free(addIE);
5966 vos_mem_free(ibss_ie);
5967 goto exit;
5968 }
5969 }
5970 else {
5971 len = 0;
5972 }
5973
5974 vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length);
5975 len += ibss_ie_length;
5976
5977 if (ccmCfgSetStr(hHal,
5978 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL,
5979 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5980 {
5981 hddLog(LOGE,
5982 FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA"));
5983 ret = -EFAULT;
5984 vos_mem_free(ibss_ie);
5985 vos_mem_free(addIE);
5986 goto exit;
5987 }
5988 vos_mem_free(addIE);
5989 if (ccmCfgSetInt(hHal,
5990 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5991 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
5992 {
5993 hddLog(LOGE,
5994 FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
5995 ret = -EFAULT;
5996 vos_mem_free(ibss_ie);
5997 goto exit;
5998 }
5999
6000 /* Populate Vendor IE in probe resp */
6001 if ((ccmCfgGetInt(hHal,
6002 WNI_CFG_PROBE_RSP_ADDNIE_FLAG,
6003 &present)) != eHAL_STATUS_SUCCESS)
6004 {
6005 hddLog(LOGE,
6006 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6007 ret = -EFAULT;
6008 vos_mem_free(ibss_ie);
6009 goto exit;
6010 }
6011
6012 addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6013 if (!addIEData) {
6014 hddLog(LOGE,
6015 FL("Could not allocate memory for command length %d"),
6016 command_len);
6017 vos_mem_free(ibss_ie);
6018 ret = -ENOMEM;
6019 goto exit;
6020 }
6021 vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN);
6022
6023 if (present) {
6024 if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac,
6025 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) {
6026 hddLog(LOGE,
6027 FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6028 ret = -EFAULT;
6029 vos_mem_free(ibss_ie);
6030 vos_mem_free(addIEData);
6031 goto exit;
6032 }
6033 if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len &&
6034 (ibss_ie_length + len) <=
6035 WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) {
6036
6037 if ((ccmCfgGetStr(hHal,
6038 WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len))
6039 != eHAL_STATUS_SUCCESS) {
6040 hddLog(LOGE,
6041 FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6042 ret = -EFAULT;
6043 vos_mem_free(ibss_ie);
6044 vos_mem_free(addIEData);
6045 goto exit;
6046 }
6047 else {
6048 /* Curruntly only WPA IE is added before Vendor IE
6049 * so we can blindly place the Vendor IE after WPA
6050 * IE. If no WPA IE found replace all with Vendor IE.
6051 */
6052 len = hdd_find_ibss_wpa_ie_pos(addIEData, len);
6053 }
6054 }
6055 else
6056 {
6057 hddLog(LOGE,
6058 FL("IE len exceed limit len %d,ibss_ie_length %d "),
6059 len, ibss_ie_length);
6060 ret = -EFAULT;
6061 vos_mem_free(addIEData);
6062 vos_mem_free(ibss_ie);
6063 goto exit;
6064 }
6065 } /* probe rsp ADD IE present */
6066 else {
6067 /* probe rsp add IE is not present */
6068 len = 0;
6069 }
6070
6071 vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length);
6072 len += ibss_ie_length;
6073
6074 vos_mem_free(ibss_ie);
6075
6076 if (ccmCfgSetStr(hHal,
6077 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6078 (tANI_U8*)(addIEData),
6079 len, NULL,
6080 eANI_BOOLEAN_FALSE)
6081 == eHAL_STATUS_FAILURE) {
6082 hddLog(LOGE,
6083 FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1"));
6084 ret = -EFAULT;
6085 vos_mem_free(addIEData);
6086 goto exit;
6087 }
6088 vos_mem_free(addIEData);
6089 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6090 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6091 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6092 {
6093 hddLog(LOGE,
6094 FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG"));
6095 ret = -EFAULT;
6096 goto exit;
6097 }
6098 }
6099 else if (strncasecmp(command, "SETRMCENABLE", 12) == 0)
6100 {
6101 tANI_U8 *value = command;
6102 tANI_U8 ucRmcEnable = 0;
6103 int status;
6104
6105 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6106 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6107 {
6108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6109 "Received SETRMCENABLE command in invalid mode %d "
6110 "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode",
6111 pAdapter->device_mode);
6112 ret = -EINVAL;
6113 goto exit;
6114 }
6115
6116 status = hdd_parse_setrmcenable_command(value, &ucRmcEnable);
6117 if (status)
6118 {
6119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6120 "Invalid SETRMCENABLE command ");
6121 ret = -EINVAL;
6122 goto exit;
6123 }
6124
6125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6126 "%s: ucRmcEnable %d ", __func__, ucRmcEnable);
6127
6128 if (TRUE == ucRmcEnable)
6129 {
6130 status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal),
6131 pAdapter->sessionId );
6132 }
6133 else if(FALSE == ucRmcEnable)
6134 {
6135 status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal),
6136 pAdapter->sessionId );
6137 }
6138 else
6139 {
6140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6141 "Invalid SETRMCENABLE command %d", ucRmcEnable);
6142 ret = -EINVAL;
6143 goto exit;
6144 }
6145
6146 if (VOS_STATUS_SUCCESS != status)
6147 {
6148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6149 "%s: SETRMC %d failed status %d", __func__, ucRmcEnable,
6150 status);
6151 ret = -EINVAL;
6152 goto exit;
6153 }
6154 }
6155 else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0)
6156 {
6157 tANI_U8 *value = command;
6158 tANI_U32 uActionPeriod = 0;
6159 int status;
6160
6161 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6162 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6163 {
6164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6165 "Received SETRMC command in invalid mode %d "
6166 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6167 pAdapter->device_mode);
6168 ret = -EINVAL;
6169 goto exit;
6170 }
6171
6172 status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod);
6173 if (status)
6174 {
6175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6176 "Invalid SETRMCACTIONPERIOD command ");
6177 ret = -EINVAL;
6178 goto exit;
6179 }
6180
6181 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6182 "%s: uActionPeriod %d ", __func__, uActionPeriod);
6183
6184 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY,
6185 uActionPeriod, NULL, eANI_BOOLEAN_FALSE))
6186 {
6187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6188 "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod);
6189 ret = -EINVAL;
6190 goto exit;
6191 }
6192
6193 }
6194 else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0)
6195 {
6196 /* Peer Info All Command */
6197 int status = eHAL_STATUS_SUCCESS;
6198 hdd_station_ctx_t *pHddStaCtx = NULL;
6199 char *extra = NULL;
6200 int idx = 0, length = 0;
6201 v_MACADDR_t *macAddr;
6202 v_U32_t txRateMbps = 0, numOfBytestoPrint = 0;
6203
6204 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6205 {
6206 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6207 }
6208 else
6209 {
6210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6211 "%s: pAdapter is not valid for this device mode",
6212 __func__);
6213 ret = -EINVAL;
6214 goto exit;
6215 }
6216
6217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6218 "%s: Received GETIBSSPEERINFOALL Command", __func__);
6219
6220
6221 /* Handle the command */
6222 status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter);
6223 if (VOS_STATUS_SUCCESS == status)
6224 {
6225 /* The variable extra needed to be allocated on the heap since
6226 * amount of memory required to copy the data for 32 devices
6227 * exceeds the size of 1024 bytes of default stack size. On
6228 * 64 bit devices, the default max stack size of 2048 bytes
6229 */
6230 extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL);
6231
6232 if (NULL == extra)
6233 {
6234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6235 "%s:kmalloc failed", __func__);
6236 ret = -EINVAL;
6237 goto exit;
6238 }
6239
6240 /* Copy number of stations */
6241 length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ",
6242 pHddStaCtx->ibss_peer_info.numIBSSPeers);
6243 numOfBytestoPrint = length;
6244 for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++)
6245 {
6246 macAddr =
6247 hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter,
6248 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6249 if (NULL != macAddr)
6250 {
6251 txRateMbps =
6252 ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000;
6253
6254 length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length,
6255 "%02x:%02x:%02x:%02x:%02x:%02x %d %d ",
6256 macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2],
6257 macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5],
6258 (int)txRateMbps,
6259 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi);
6260 }
6261 else
6262 {
6263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6264 "%s: MAC ADDR is NULL for staIdx: %d", __func__,
6265 pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx);
6266 }
6267
6268 /*
6269 * VOS_TRACE() macro has limitation of 512 bytes for the print
6270 * buffer. Hence printing the data in two chunks. The first chunk
6271 * will have the data for 16 devices and the second chunk will
6272 * have the rest.
6273 */
6274 if (idx < NUM_OF_STA_DATA_TO_PRINT)
6275 {
6276 numOfBytestoPrint = length;
6277 }
6278 }
6279
6280 /*
6281 * Copy the data back into buffer, if the data to copy is
6282 * morethan 512 bytes than we will split the data and do
6283 * it in two shots
6284 */
6285 if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint))
6286 {
6287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6288 "%s: Copy into user data buffer failed ", __func__);
6289 ret = -EFAULT;
6290 kfree(extra);
6291 goto exit;
6292 }
6293 priv_data.buf[numOfBytestoPrint] = '\0';
6294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6295 "%s", priv_data.buf);
6296
6297 if (length > numOfBytestoPrint)
6298 {
6299 if (copy_to_user(priv_data.buf + numOfBytestoPrint,
6300 extra + numOfBytestoPrint,
6301 length - numOfBytestoPrint + 1))
6302 {
6303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6304 "%s: Copy into user data buffer failed ", __func__);
6305 ret = -EFAULT;
6306 kfree(extra);
6307 goto exit;
6308 }
6309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6310 "%s", &priv_data.buf[numOfBytestoPrint]);
6311 }
6312
6313 /* Free temporary buffer */
6314 kfree(extra);
6315 }
6316
6317 else
6318 {
6319 /* Command failed, log error */
6320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6321 "%s: GETIBSSPEERINFOALL command failed with status code %d",
6322 __func__, status);
6323 ret = -EINVAL;
6324 goto exit;
6325 }
6326 ret = 0;
6327 }
6328 else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0)
6329 {
6330 /* Peer Info <Peer Addr> command */
6331 tANI_U8 *value = command;
6332 VOS_STATUS status;
6333 hdd_station_ctx_t *pHddStaCtx = NULL;
6334 char extra[128] = { 0 };
6335 v_U32_t length = 0;
6336 v_U8_t staIdx = 0;
6337 v_U32_t txRateMbps = 0;
6338 v_MACADDR_t peerMacAddr;
6339
6340 if (WLAN_HDD_IBSS == pAdapter->device_mode)
6341 {
6342 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6343 }
6344 else
6345 {
6346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6347 "%s: pAdapter is not valid for this device mode",
6348 __func__);
6349 ret = -EINVAL;
6350 goto exit;
6351 }
6352
6353 /* if there are no peers, no need to continue with the command */
6354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6355 "%s: Received GETIBSSPEERINFO Command", __func__);
6356
6357 if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState)
6358 {
6359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6360 "%s:No IBSS Peers coalesced", __func__);
6361 ret = -EINVAL;
6362 goto exit;
6363 }
6364
6365 /* Parse the incoming command buffer */
6366 status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr);
6367 if (VOS_STATUS_SUCCESS != status)
6368 {
6369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6370 "%s: Invalid GETIBSSPEERINFO command", __func__);
6371 ret = -EINVAL;
6372 goto exit;
6373 }
6374
6375 /* Get station index for the peer mac address */
6376 hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx);
6377
6378 if (staIdx > HDD_MAX_NUM_IBSS_STA)
6379 {
6380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6381 "%s: Invalid StaIdx %d returned", __func__, staIdx);
6382 ret = -EINVAL;
6383 goto exit;
6384 }
6385
6386 /* Handle the command */
6387 status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx);
6388 if (VOS_STATUS_SUCCESS == status)
6389 {
6390 v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate;
6391 txRateMbps = (txRate * 500 * 1000)/1000000;
6392
6393 length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps,
6394 (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi);
6395
6396 /* Copy the data back into buffer */
6397 if (copy_to_user(priv_data.buf, &extra, length+ 1))
6398 {
6399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6400 "%s: copy data to user buffer failed GETIBSSPEERINFO command",
6401 __func__);
6402 ret = -EFAULT;
6403 goto exit;
6404 }
6405 }
6406 else
6407 {
6408 /* Command failed, log error */
6409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6410 "%s: GETIBSSPEERINFO command failed with status code %d",
6411 __func__, status);
6412 ret = -EINVAL;
6413 goto exit;
6414 }
6415
6416 /* Success ! */
6417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
6418 "%s", priv_data.buf);
6419 ret = 0;
6420 }
6421 else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0)
6422 {
6423 tANI_U8 *value = command;
6424 tANI_U32 uRate = 0;
6425 tTxrateinfoflags txFlags = 0;
6426 tSirRateUpdateInd *rateUpdateParams;
6427 int status;
6428
6429 if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
6430 (WLAN_HDD_SOFTAP != pAdapter->device_mode))
6431 {
6432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6433 "Received SETRMCTXRATE command in invalid mode %d "
6434 "SETRMC command is only allowed in IBSS or SOFTAP mode",
6435 pAdapter->device_mode);
6436 ret = -EINVAL;
6437 goto exit;
6438 }
6439
6440 status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags);
6441 if (status)
6442 {
6443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6444 "Invalid SETRMCTXRATE command ");
6445 ret = -EINVAL;
6446 goto exit;
6447 }
6448
6449 rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd));
6450 if (NULL == rateUpdateParams)
6451 {
6452 ret = -EINVAL;
6453 goto exit;
6454 }
6455
6456 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6457 "%s: uRate %d ", __func__, uRate);
6458
6459 vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd ));
6460
6461 /* -1 implies ignore this param */
6462 rateUpdateParams->ucastDataRate = -1;
6463
6464 /*
6465 * Fill the user specifieed RMC rate param
6466 * and the derived tx flags.
6467 */
6468 rateUpdateParams->rmcDataRate = uRate;
6469 rateUpdateParams->rmcDataRateTxFlag = txFlags;
6470
6471 status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams);
6472 }
6473 else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 )
6474 {
6475 char *value;
6476 tANI_U8 tx_fail_count = 0;
6477 tANI_U16 pid = 0;
6478
6479 value = command;
6480
6481 ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid);
6482
6483 if (0 != ret)
6484 {
6485 hddLog(VOS_TRACE_LEVEL_INFO,
6486 "%s: Failed to parse SETIBSSTXFAILEVENT arguments",
6487 __func__);
6488 goto exit;
6489 }
6490
6491 hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu",
6492 __func__, tx_fail_count, pid);
6493
6494 if (0 == tx_fail_count)
6495 {
6496 // Disable TX Fail Indication
6497 if (eHAL_STATUS_SUCCESS ==
6498 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6499 tx_fail_count,
6500 NULL))
6501 {
6502 cesium_pid = 0;
6503 }
6504 else
6505 {
6506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6507 "%s: failed to disable TX Fail Event ", __func__);
6508 ret = -EINVAL;
6509 }
6510 }
6511 else
6512 {
6513 if (eHAL_STATUS_SUCCESS ==
6514 sme_TXFailMonitorStartStopInd(pHddCtx->hHal,
6515 tx_fail_count,
6516 (void*)hdd_tx_fail_ind_callback))
6517 {
6518 cesium_pid = pid;
6519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6520 "%s: Registered Cesium pid %u", __func__,
6521 cesium_pid);
6522 }
6523 else
6524 {
6525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6526 "%s: Failed to enable TX Fail Monitoring", __func__);
6527 ret = -EINVAL;
6528 }
6529 }
6530 }
6531
6532#endif /* WLAN_FEATURE_RMC */
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006533#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006534 else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0)
6535 {
6536 tANI_U8 *value = command;
6537 tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
6538 tANI_U8 numChannels = 0;
6539 eHalStatus status = eHAL_STATUS_SUCCESS;
6540
6541 status = hdd_parse_channellist(value, ChannelList, &numChannels);
6542 if (eHAL_STATUS_SUCCESS != status)
6543 {
6544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6545 "%s: Failed to parse channel list information", __func__);
6546 ret = -EINVAL;
6547 goto exit;
6548 }
6549
6550 if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN)
6551 {
6552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6553 "%s: number of channels (%d) supported exceeded max (%d)", __func__,
6554 numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
6555 ret = -EINVAL;
6556 goto exit;
6557 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006558 status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal),
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006559 ChannelList,
6560 numChannels);
6561 if (eHAL_STATUS_SUCCESS != status)
6562 {
6563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6564 "%s: Failed to update channel list information", __func__);
6565 ret = -EINVAL;
6566 goto exit;
6567 }
6568 }
6569 else if (strncmp(command, "GETTSMSTATS", 11) == 0)
6570 {
6571 tANI_U8 *value = command;
6572 char extra[128] = {0};
6573 int len = 0;
6574 tANI_U8 tid = 0;
6575 hdd_station_ctx_t *pHddStaCtx = NULL;
6576 tAniTrafStrmMetrics tsmMetrics;
6577 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6578
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306579 ret = hdd_drv_cmd_validate(command, 11);
6580 if (ret)
6581 goto exit;
6582
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006583 /* if not associated, return error */
6584 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6585 {
6586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__);
6587 ret = -EINVAL;
6588 goto exit;
6589 }
6590
6591 /* Move pointer to ahead of GETTSMSTATS<delimiter> */
6592 value = value + 12;
6593 /* Convert the value from ascii to integer */
6594 ret = kstrtou8(value, 10, &tid);
6595 if (ret < 0)
6596 {
6597 /* If the input value is greater than max value of datatype, then also
6598 kstrtou8 fails */
6599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6600 "%s: kstrtou8 failed range [%d - %d]", __func__,
6601 TID_MIN_VALUE,
6602 TID_MAX_VALUE);
6603 ret = -EINVAL;
6604 goto exit;
6605 }
6606
6607 if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE))
6608 {
6609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6610 "tid value %d is out of range"
6611 " (Min: %d Max: %d)", tid,
6612 TID_MIN_VALUE,
6613 TID_MAX_VALUE);
6614 ret = -EINVAL;
6615 goto exit;
6616 }
6617
6618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6619 "%s: Received Command to get tsm stats tid = %d", __func__, tid);
6620
6621 if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics))
6622 {
6623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6624 "%s: failed to get tsm stats", __func__);
6625 ret = -EFAULT;
6626 goto exit;
6627 }
6628
6629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6630 "UplinkPktQueueDly(%d)\n"
6631 "UplinkPktQueueDlyHist[0](%d)\n"
6632 "UplinkPktQueueDlyHist[1](%d)\n"
6633 "UplinkPktQueueDlyHist[2](%d)\n"
6634 "UplinkPktQueueDlyHist[3](%d)\n"
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05306635 "UplinkPktTxDly(%u)\n"
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006636 "UplinkPktLoss(%d)\n"
6637 "UplinkPktCount(%d)\n"
6638 "RoamingCount(%d)\n"
6639 "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly,
6640 tsmMetrics.UplinkPktQueueDlyHist[0],
6641 tsmMetrics.UplinkPktQueueDlyHist[1],
6642 tsmMetrics.UplinkPktQueueDlyHist[2],
6643 tsmMetrics.UplinkPktQueueDlyHist[3],
6644 tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss,
6645 tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly);
6646
6647 /* Output TSM stats is of the format
6648 GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly]
6649 eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006650 len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006651 tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0],
6652 tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2],
6653 tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly,
6654 tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount,
6655 tsmMetrics.RoamingDly);
6656
Ratnam Rachurid53009c2015-08-07 13:59:00 +05306657 len = VOS_MIN(priv_data.total_len, len + 1);
6658 if (copy_to_user(priv_data.buf, &extra, len)) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6660 "%s: failed to copy data to user buffer", __func__);
6661 ret = -EFAULT;
6662 goto exit;
6663 }
6664 }
6665 else if (strncmp(command, "SETCCKMIE", 9) == 0)
6666 {
6667 tANI_U8 *value = command;
6668 tANI_U8 *cckmIe = NULL;
6669 tANI_U8 cckmIeLen = 0;
6670 eHalStatus status = eHAL_STATUS_SUCCESS;
6671
6672 status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen);
6673 if (eHAL_STATUS_SUCCESS != status)
6674 {
6675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6676 "%s: Failed to parse cckm ie data", __func__);
6677 ret = -EINVAL;
6678 goto exit;
6679 }
6680
6681 if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN)
6682 {
6683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6684 "%s: CCKM Ie input length is more than max[%d]", __func__,
6685 DOT11F_IE_RSN_MAX_LEN);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006686 vos_mem_free(cckmIe);
6687 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006688 ret = -EINVAL;
6689 goto exit;
6690 }
6691 sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -08006692 vos_mem_free(cckmIe);
6693 cckmIe = NULL;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07006694 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006695 else if (strncmp(command, "CCXBEACONREQ", 12) == 0)
6696 {
6697 tANI_U8 *value = command;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006698 tCsrEseBeaconReq eseBcnReq;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006699 eHalStatus status = eHAL_STATUS_SUCCESS;
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006700
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006701 status = hdd_parse_ese_beacon_req(value, &eseBcnReq);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006702 if (eHAL_STATUS_SUCCESS != status)
6703 {
6704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006705 "%s: Failed to parse ese beacon req", __func__);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006706 ret = -EINVAL;
6707 goto exit;
6708 }
Srinivas Girigowda0c6d7fe2014-05-28 18:18:10 -07006709 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6710 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated"));
6711 hdd_indicateEseBcnReportNoResults (pAdapter,
6712 eseBcnReq.bcnReq[0].measurementToken,
6713 0x02, //BIT(1) set for measurement done
6714 0); // no BSS
6715 goto exit;
6716 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006717
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006718 status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq);
6719 if (eHAL_STATUS_SUCCESS != status)
6720 {
6721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6722 "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status);
6723 ret = -EINVAL;
6724 goto exit;
6725 }
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08006726 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006727#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
c_hpothu92367912014-05-01 15:18:17 +05306728 else if (strncmp(command, "GETBCNMISSRATE", 14) == 0)
6729 {
6730 eHalStatus status;
6731 char buf[32], len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306732 void *cookie;
6733 struct hdd_request *request;
6734 struct bcn_miss_rate_priv *priv;
6735 static const struct hdd_request_params params = {
6736 .priv_size = sizeof(*priv),
6737 .timeout_ms = WLAN_WAIT_TIME_STATS,
6738 };
c_hpothu92367912014-05-01 15:18:17 +05306739
6740 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6741
6742 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6743 {
6744 hddLog(VOS_TRACE_LEVEL_WARN,
6745 FL("GETBCNMISSRATE: STA is not in connected state"));
6746 ret = -1;
6747 goto exit;
6748 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306749 request = hdd_request_alloc(&params);
6750 if (!request) {
6751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6752 ret = -ENOMEM;
6753 goto exit;
6754 }
6755 cookie = hdd_request_cookie(request);
6756 priv = hdd_request_priv(request);
6757 priv->bcn_miss_rate = -1;
c_hpothu92367912014-05-01 15:18:17 +05306758
6759 status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal),
6760 pAdapter->sessionId,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306761 (void *)get_bcn_miss_rate_cb,
6762 cookie);
c_hpothu92367912014-05-01 15:18:17 +05306763 if( eHAL_STATUS_SUCCESS != status)
6764 {
6765 hddLog(VOS_TRACE_LEVEL_INFO,
6766 FL("GETBCNMISSRATE: fail to post WDA cmd"));
6767 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306768 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306769 }
6770
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306771 ret = hdd_request_wait_for_response(request);
6772 if(ret)
c_hpothu92367912014-05-01 15:18:17 +05306773 {
6774 hddLog(VOS_TRACE_LEVEL_ERROR,
6775 FL("failed to wait on bcnMissRateComp %d"), ret);
6776
c_hpothu92367912014-05-01 15:18:17 +05306777 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306778 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306779 }
6780
6781 hddLog(VOS_TRACE_LEVEL_INFO,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306782 FL("GETBCNMISSRATE: bcnMissRate: %d"), priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306783
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306784 if (priv->bcn_miss_rate == -1) {
6785 ret = -EFAULT;
6786 goto free_bcn_miss_rate_req;
6787 }
6788
6789 len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d",
6790 priv->bcn_miss_rate);
c_hpothu92367912014-05-01 15:18:17 +05306791 if (copy_to_user(priv_data.buf, &buf, len + 1))
6792 {
6793 hddLog(VOS_TRACE_LEVEL_ERROR,
6794 "%s: failed to copy data to user buffer", __func__);
6795 ret = -EFAULT;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306796 goto free_bcn_miss_rate_req;
c_hpothu92367912014-05-01 15:18:17 +05306797 }
6798 ret = len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306799
6800free_bcn_miss_rate_req:
6801 hdd_request_put(request);
c_hpothu92367912014-05-01 15:18:17 +05306802 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306803#ifdef FEATURE_WLAN_TDLS
6804 else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) {
6805 tANI_U8 *value = command;
6806 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306807
6808 ret = hdd_drv_cmd_validate(command, 26);
6809 if (ret)
6810 goto exit;
6811
Atul Mittal87ec2422014-09-24 13:12:50 +05306812 /* Move pointer to ahead of TDLSOFFCH*/
6813 value += 26;
c_manjeebbc40212015-12-08 13:52:59 +05306814 if (!(sscanf(value, "%d", &set_value))) {
6815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6816 FL("No input identified"));
6817 ret = -EINVAL;
6818 goto exit;
6819 }
6820
Atul Mittal87ec2422014-09-24 13:12:50 +05306821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6822 "%s: Tdls offchannel offset:%d",
6823 __func__, set_value);
6824 ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
6825 if (ret < 0)
6826 {
6827 ret = -EINVAL;
6828 goto exit;
6829 }
6830
6831 } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) {
6832 tANI_U8 *value = command;
6833 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306834
6835 ret = hdd_drv_cmd_validate(command, 18);
6836 if (ret)
6837 goto exit;
6838
Atul Mittal87ec2422014-09-24 13:12:50 +05306839 /* Move pointer to ahead of tdlsoffchnmode*/
6840 value += 18;
c_manjee82323892015-12-08 12:40:34 +05306841 ret = sscanf(value, "%d", &set_value);
6842 if (ret != 1) {
6843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6844 FL("No input identified"));
6845 ret = -EINVAL;
6846 goto exit;
6847 }
Atul Mittal87ec2422014-09-24 13:12:50 +05306848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6849 "%s: Tdls offchannel mode:%d",
6850 __func__, set_value);
6851 ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
6852 if (ret < 0)
6853 {
6854 ret = -EINVAL;
6855 goto exit;
6856 }
6857 } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) {
6858 tANI_U8 *value = command;
6859 int set_value;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306860
6861 ret = hdd_drv_cmd_validate(command, 14);
6862 if (ret)
6863 goto exit;
6864
Atul Mittal87ec2422014-09-24 13:12:50 +05306865 /* Move pointer to ahead of TDLSOFFCH*/
6866 value += 14;
c_manjeef6ccaf52015-12-08 11:52:11 +05306867 ret = sscanf(value, "%d", &set_value);
6868 if (ret != 1) {
6869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6870 "Wrong value is given for hdd_set_tdls_offchannel");
6871 ret = -EINVAL;
6872 goto exit;
6873 }
6874
Atul Mittal87ec2422014-09-24 13:12:50 +05306875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6876 "%s: Tdls offchannel num: %d",
6877 __func__, set_value);
6878 ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
6879 if (ret < 0)
6880 {
6881 ret = -EINVAL;
6882 goto exit;
6883 }
6884 }
6885#endif
Satyanarayana Dash72806012014-12-02 14:30:08 +05306886 else if (strncmp(command, "GETFWSTATS", 10) == 0)
6887 {
6888 eHalStatus status;
6889 char *buf = NULL;
6890 char len;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306891 tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp),
6892 *fw_stats_result;
Satyanarayana Dash72806012014-12-02 14:30:08 +05306893 tANI_U8 *ptr = command;
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306894 int stats;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306895 void *cookie;
6896 struct hdd_request *request;
6897 struct fw_stats_priv *priv;
6898 static const struct hdd_request_params params = {
6899 .priv_size = sizeof(*priv),
6900 .timeout_ms = WLAN_WAIT_TIME_STATS,
6901 };
Satyanarayana Dash72806012014-12-02 14:30:08 +05306902
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05306903 ret = hdd_drv_cmd_validate(command, 10);
6904 if (ret)
6905 goto exit;
6906
6907 stats = *(ptr + 11) - '0';
Satyanarayana Dash72806012014-12-02 14:30:08 +05306908 hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats);
6909 if (!IS_FEATURE_FW_STATS_ENABLE)
6910 {
6911 hddLog(VOS_TRACE_LEVEL_INFO,
6912 FL("Get Firmware stats feature not supported"));
6913 ret = -EINVAL;
6914 goto exit;
6915 }
6916
6917 if (FW_STATS_MAX <= stats || 0 >= stats)
6918 {
6919 hddLog(VOS_TRACE_LEVEL_INFO,
6920 FL(" stats %d not supported"),stats);
6921 ret = -EINVAL;
6922 goto exit;
6923 }
6924
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306925 request = hdd_request_alloc(&params);
6926 if (!request) {
6927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
6928 ret = -ENOMEM;
6929 goto exit;
6930 }
6931 cookie = hdd_request_cookie(request);
6932
Satyanarayana Dash72806012014-12-02 14:30:08 +05306933 status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats,
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306934 cookie, hdd_fw_stats_cb);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306935 if (eHAL_STATUS_SUCCESS != status)
6936 {
6937 hddLog(VOS_TRACE_LEVEL_ERROR,
6938 FL(" fail to post WDA cmd status = %d"), status);
6939 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306940 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306941 goto exit;
6942 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306943 ret = hdd_request_wait_for_response(request);
6944 if (ret)
Satyanarayana Dash72806012014-12-02 14:30:08 +05306945 {
6946 hddLog(VOS_TRACE_LEVEL_ERROR,
6947 FL("failed to wait on GwtFwstats"));
Satyanarayana Dash72806012014-12-02 14:30:08 +05306948 ret = -EINVAL;
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306949 hdd_request_put(request);
Satyanarayana Dash72806012014-12-02 14:30:08 +05306950 goto exit;
6951 }
Hanumanth Reddy Pothula7aa4bea2018-04-09 17:19:03 +05306952
6953 priv = hdd_request_priv(request);
6954 fw_stats_result = priv->fw_stats;
6955 fwStatsRsp->type = 0;
6956 if (NULL != fw_stats_result)
6957 {
6958 switch (fw_stats_result->type )
6959 {
6960 case FW_UBSP_STATS:
6961 {
6962 tSirUbspFwStats *stats =
6963 &fwStatsRsp->fwStatsData.ubspStats;
6964 memcpy(fwStatsRsp, fw_stats_result,
6965 sizeof(tSirFwStatsResult));
6966 hddLog(VOS_TRACE_LEVEL_INFO,
6967 FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"),
6968 stats->ubsp_enter_cnt,
6969 stats->ubsp_jump_ddr_cnt);
6970 }
6971 break;
6972
6973 default:
6974 {
6975 hddLog(VOS_TRACE_LEVEL_ERROR,
6976 FL("No handling for stats type %d"),
6977 fw_stats_result->type);
6978 }
6979 }
6980 }
6981 hdd_request_put(request);
6982
Satyanarayana Dash72806012014-12-02 14:30:08 +05306983 if (fwStatsRsp->type)
6984 {
6985 buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL);
6986 if (!buf)
6987 {
6988 hddLog(VOS_TRACE_LEVEL_ERROR,
6989 FL(" failed to allocate memory"));
6990 ret = -ENOMEM;
6991 goto exit;
6992 }
6993 switch( fwStatsRsp->type )
6994 {
6995 case FW_UBSP_STATS:
6996 {
6997 len = snprintf(buf, FW_STATE_RSP_LEN,
6998 "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d",
Abhishek Singh08aa7762014-12-16 13:59:03 +05306999 fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt,
7000 fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt);
Satyanarayana Dash72806012014-12-02 14:30:08 +05307001 }
7002 break;
7003 default:
7004 {
7005 hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type);
7006 ret = -EFAULT;
7007 kfree(buf);
7008 goto exit;
7009 }
7010 }
7011 if (copy_to_user(priv_data.buf, buf, len + 1))
7012 {
7013 hddLog(VOS_TRACE_LEVEL_ERROR,
7014 FL(" failed to copy data to user buffer"));
7015 ret = -EFAULT;
7016 kfree(buf);
7017 goto exit;
7018 }
7019 ret = len;
7020 kfree(buf);
7021 }
7022 else
7023 {
7024 hddLog(VOS_TRACE_LEVEL_ERROR,
7025 FL("failed to fetch the stats"));
7026 ret = -EFAULT;
7027 goto exit;
7028 }
Satyanarayana Dash72806012014-12-02 14:30:08 +05307029 }
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307030 else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0)
7031 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307032 ret = hdd_drv_cmd_validate(command, 15);
7033 if (ret)
7034 goto exit;
7035
Agarwal Ashish8bd53ae2015-06-12 18:03:45 +05307036 /*
7037 * this command wld be called by user-space when it detects WLAN
7038 * ON after airplane mode is set. When APM is set, WLAN turns off.
7039 * But it can be turned back on. Otherwise; when APM is turned back
7040 * off, WLAN wld turn back on. So at that point the command is
7041 * expected to come down. 0 means disable, 1 means enable. The
7042 * constraint is removed when parameter 1 is set or different
7043 * country code is set
7044 */
7045 ret = hdd_cmd_setFccChannel(pHddCtx, command, 15);
7046 }
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307047 else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0)
7048 {
Rajeev Kumar Sirasanagandlaf740b1e2017-08-23 18:07:01 +05307049 ret = hdd_drv_cmd_validate(command, 16);
7050 if (ret)
7051 goto exit;
7052
Mahesh A Saptasagarbeca12c2015-09-07 16:21:06 +05307053 ret = hdd_enable_disable_ca_event(pHddCtx, command, 16);
7054 }
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307055 /*
7056 * command should be a string having format
7057 * SET_DISABLE_CHANNEL_LIST <num of channels>
7058 * <channels separated by spaces>
7059 */
7060 else if (strncmp(command, "SET_DISABLE_CHANNEL_LIST", 24) == 0) {
7061 tANI_U8 *ptr = command;
7062 ret = hdd_drv_cmd_validate(command, 24);
7063 if (ret)
7064 goto exit;
7065
7066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7067 " Received Command to disable Channels %s",
7068 __func__);
7069 ret = hdd_parse_disable_chan_cmd(pAdapter, ptr);
7070 if (ret)
7071 goto exit;
7072 }
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307073 else if (strncmp(command, "GET_DISABLE_CHANNEL_LIST", 24) == 0) {
7074 char extra[128] = {0};
7075 int len;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +05307076
Hanumanth Reddy Pothula8ae38bb2018-03-07 18:59:30 +05307077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7078 " Received Command to get disable Channels list %s",
7079 __func__);
7080
7081 len = hdd_get_disable_ch_list(pHddCtx, extra, sizeof(extra));
7082 if (len == 0) {
7083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7084 FL("disable channel list are not yet programed"));
7085 ret = -EINVAL;
7086 goto exit;
7087 }
7088
7089 len = VOS_MIN(priv_data.total_len, len + 1);
7090 if (copy_to_user(priv_data.buf, &extra, len)) {
7091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7092 "%s: failed to copy data to user buffer", __func__);
7093 ret = -EFAULT;
7094 goto exit;
7095 }
7096
7097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7098 FL("data:%s"), extra);
7099 }
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007100 else {
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307101 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7102 TRACE_CODE_HDD_UNSUPPORTED_IOCTL,
7103 pAdapter->sessionId, 0));
Satyanarayana Dash72806012014-12-02 14:30:08 +05307104 hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"),
7105 command);
Madan Mohan Koyyalamudif9bdd4e2012-10-30 18:05:03 -07007106 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007107 }
7108exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307109 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 if (command)
7111 {
7112 kfree(command);
7113 }
7114 return ret;
7115}
7116
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007117#ifdef CONFIG_COMPAT
7118static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7119{
7120 struct {
7121 compat_uptr_t buf;
7122 int used_len;
7123 int total_len;
7124 } compat_priv_data;
7125 hdd_priv_data_t priv_data;
7126 int ret = 0;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007127
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007128 /*
7129 * Note that pAdapter and ifr have already been verified by caller,
7130 * and HDD context has also been validated
7131 */
7132 if (copy_from_user(&compat_priv_data, ifr->ifr_data,
7133 sizeof(compat_priv_data))) {
7134 ret = -EFAULT;
7135 goto exit;
7136 }
7137 priv_data.buf = compat_ptr(compat_priv_data.buf);
7138 priv_data.used_len = compat_priv_data.used_len;
7139 priv_data.total_len = compat_priv_data.total_len;
7140 ret = hdd_driver_command(pAdapter, &priv_data);
7141 exit:
7142 return ret;
7143}
7144#else /* CONFIG_COMPAT */
7145static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7146{
7147 /* will never be invoked */
7148 return 0;
7149}
7150#endif /* CONFIG_COMPAT */
7151
7152static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr)
7153{
7154 hdd_priv_data_t priv_data;
7155 int ret = 0;
7156
7157 /*
7158 * Note that pAdapter and ifr have already been verified by caller,
7159 * and HDD context has also been validated
7160 */
7161 if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) {
7162 ret = -EFAULT;
7163 } else {
7164 ret = hdd_driver_command(pAdapter, &priv_data);
7165 }
7166 return ret;
7167}
7168
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307169int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007170{
7171 hdd_adapter_t *pAdapter;
7172 hdd_context_t *pHddCtx;
7173 int ret;
7174
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307175 ENTER();
7176
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007177 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7178 if (NULL == pAdapter) {
7179 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7180 "%s: HDD adapter context is Null", __func__);
7181 ret = -ENODEV;
7182 goto exit;
7183 }
7184 if (dev != pAdapter->dev) {
7185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7186 "%s: HDD adapter/dev inconsistency", __func__);
7187 ret = -ENODEV;
7188 goto exit;
7189 }
7190
7191 if ((!ifr) || (!ifr->ifr_data)) {
7192 ret = -EINVAL;
7193 goto exit;
7194 }
7195
7196 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7197 ret = wlan_hdd_validate_context(pHddCtx);
7198 if (ret) {
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007199 ret = -EBUSY;
7200 goto exit;
7201 }
7202
7203 switch (cmd) {
7204 case (SIOCDEVPRIVATE + 1):
7205 if (is_compat_task())
7206 ret = hdd_driver_compat_ioctl(pAdapter, ifr);
7207 else
7208 ret = hdd_driver_ioctl(pAdapter, ifr);
7209 break;
7210 default:
7211 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
7212 __func__, cmd);
7213 ret = -EINVAL;
7214 break;
7215 }
7216 exit:
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307217 EXIT();
Jeff Johnsond6e7b3f2014-03-20 12:12:11 -07007218 return ret;
7219}
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007220
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05307221int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7222{
7223 int ret;
7224
7225 vos_ssr_protect(__func__);
7226 ret = __hdd_ioctl(dev, ifr, cmd);
7227 vos_ssr_unprotect(__func__);
7228
7229 return ret;
7230}
7231
Katya Nigame7b69a82015-04-28 15:24:06 +05307232int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7233{
7234 return 0;
7235}
7236
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007237#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007238/**---------------------------------------------------------------------------
7239
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007240 \brief hdd_parse_ese_beacon_req() - Parse ese beacon request
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007241
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007242 This function parses the ese beacon request passed in the format
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007243 CCXBEACONREQ<space><Number of fields><space><Measurement token>
7244 <space>Channel 1<space>Scan Mode <space>Meas Duration<space>Channel N
7245 <space>Scan Mode N<space>Meas Duration N
7246 if the Number of bcn req fields (N) does not match with the actual number of fields passed
7247 then take N.
7248 <Meas Token><Channel><Scan Mode> and <Meas Duration> are treated as one pair
7249 For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40.
7250 This function does not take care of removing duplicate channels from the list
7251
7252 \param - pValue Pointer to data
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007253 \param - pEseBcnReq output pointer to store parsed ie information
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007254
7255 \return - 0 for success non-zero for failure
7256
7257 --------------------------------------------------------------------------*/
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007258static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
7259 tCsrEseBeaconReq *pEseBcnReq)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007260{
7261 tANI_U8 *inPtr = pValue;
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307262 uint8_t input = 0;
7263 uint32_t tempInt = 0;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007264 int j = 0, i = 0, v = 0;
7265 char buf[32];
7266
7267 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7268 /*no argument after the command*/
7269 if (NULL == inPtr)
7270 {
7271 return -EINVAL;
7272 }
7273 /*no space after the command*/
7274 else if (SPACE_ASCII_VALUE != *inPtr)
7275 {
7276 return -EINVAL;
7277 }
7278
7279 /*removing empty spaces*/
7280 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7281
7282 /*no argument followed by spaces*/
7283 if ('\0' == *inPtr) return -EINVAL;
7284
7285 /*getting the first argument ie measurement token*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007286 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007287 if (1 != v) return -EINVAL;
7288
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307289 v = kstrtos8(buf, 10, &input);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007290 if ( v < 0) return -EINVAL;
7291
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307292 input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS);
7293 pEseBcnReq->numBcnReqIe = input;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007294
Srinivas Girigowda725a88e2016-03-31 19:24:25 +05307295 hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe);
7296
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007297
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007298 for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007299 {
7300 for (i = 0; i < 4; i++)
7301 {
7302 /*inPtr pointing to the beginning of first space after number of ie fields*/
7303 inPtr = strpbrk( inPtr, " " );
7304 /*no ie data after the number of ie fields argument*/
7305 if (NULL == inPtr) return -EINVAL;
7306
7307 /*removing empty space*/
7308 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
7309
7310 /*no ie data after the number of ie fields argument and spaces*/
7311 if ( '\0' == *inPtr ) return -EINVAL;
7312
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007313 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007314 if (1 != v) return -EINVAL;
7315
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307316 v = kstrtou32(buf, 10, &tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007317 if (v < 0) return -EINVAL;
7318
7319 switch (i)
7320 {
7321 case 0: /* Measurement token */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307322 if (!tempInt)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007323 {
7324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307325 "Invalid Measurement Token: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007326 return -EINVAL;
7327 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007328 pEseBcnReq->bcnReq[j].measurementToken = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007329 break;
7330
7331 case 1: /* Channel number */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307332 if ((!tempInt) ||
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007333 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7334 {
7335 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307336 "Invalid Channel Number: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007337 return -EINVAL;
7338 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007339 pEseBcnReq->bcnReq[j].channel = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007340 break;
7341
7342 case 2: /* Scan mode */
Varun Reddy Yeturu0b18d5a2013-12-04 11:42:23 -08007343 if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007344 {
7345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307346 "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007347 return -EINVAL;
7348 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007349 pEseBcnReq->bcnReq[j].scanMode= tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007350 break;
7351
7352 case 3: /* Measurement duration */
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307353 if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) ||
7354 ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE)))
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007355 {
7356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Khandavalli9f3b4832016-06-30 16:58:38 +05307357 "Invalid Measurement Duration: %u", tempInt);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007358 return -EINVAL;
7359 }
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007360 pEseBcnReq->bcnReq[j].measurementDuration = tempInt;
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007361 break;
7362 }
7363 }
7364 }
7365
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007366 for (j = 0; j < pEseBcnReq->numBcnReqIe; j++)
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007367 {
7368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavallie8768212014-02-17 16:43:34 +05307369 "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n",
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007370 j,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007371 pEseBcnReq->bcnReq[j].measurementToken,
7372 pEseBcnReq->bcnReq[j].channel,
7373 pEseBcnReq->bcnReq[j].scanMode,
7374 pEseBcnReq->bcnReq[j].measurementDuration);
Srinivas Girigowda91ccbe82013-11-10 16:37:38 -08007375 }
7376
7377 return VOS_STATUS_SUCCESS;
7378}
7379
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307380struct tsm_priv {
7381 tAniTrafStrmMetrics tsm_metrics;
7382};
7383
7384static void hdd_get_tsm_stats_cb(tAniTrafStrmMetrics tsm_metrics,
7385 const tANI_U32 sta_id, void *context )
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007386{
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307387 struct hdd_request *request;
7388 struct tsm_priv *priv;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007389
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307390 ENTER();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007391
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307392 request = hdd_request_get(context);
7393 if (!request) {
7394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
7395 return;
7396 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007397
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307398 priv = hdd_request_priv(request);
7399 priv->tsm_metrics = tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007400
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307401 hdd_request_complete(request);
7402 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007403
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307404 EXIT();
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007405}
7406
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007407static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid,
7408 tAniTrafStrmMetrics* pTsmMetrics)
7409{
7410 hdd_station_ctx_t *pHddStaCtx = NULL;
7411 eHalStatus hstatus;
Jeff Johnson72a40512013-12-19 10:14:15 -08007412 VOS_STATUS vstatus = VOS_STATUS_SUCCESS;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007413 hdd_context_t *pHddCtx = NULL;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307414 int ret;
7415 void *cookie;
7416 struct hdd_request *request;
7417 struct tsm_priv *priv;
7418 static const struct hdd_request_params params = {
7419 .priv_size = sizeof(*priv),
7420 .timeout_ms = WLAN_WAIT_TIME_STATS,
7421 };
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007422
7423 if (NULL == pAdapter)
7424 {
7425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__);
7426 return VOS_STATUS_E_FAULT;
7427 }
7428
7429 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7430 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7431
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307432 request = hdd_request_alloc(&params);
7433 if (!request) {
7434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
7435 return VOS_STATUS_E_NOMEM;
7436 }
7437 cookie = hdd_request_cookie(request);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007438
7439 /* query tsm stats */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307440 hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_get_tsm_stats_cb,
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007441 pHddStaCtx->conn_info.staId[ 0 ],
7442 pHddStaCtx->conn_info.bssId,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307443 cookie, pHddCtx->pvosContext, tid);
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007444
7445 if (eHAL_STATUS_SUCCESS != hstatus)
7446 {
Jeff Johnson72a40512013-12-19 10:14:15 -08007447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics",
7448 __func__);
7449 vstatus = VOS_STATUS_E_FAULT;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007450 }
7451 else
7452 {
7453 /* request was sent -- wait for the response */
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307454 ret = hdd_request_wait_for_response(request);
7455 if (ret) {
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007456 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307457 "SME timeout while retrieving statistics");
Jeff Johnson72a40512013-12-19 10:14:15 -08007458 vstatus = VOS_STATUS_E_TIMEOUT;
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307459 } else {
7460 priv = hdd_request_priv(request);
7461 *pTsmMetrics = priv->tsm_metrics;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007462 }
7463 }
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007464
Hanumanth Reddy Pothula1ceb7032018-04-05 19:35:55 +05307465 hdd_request_put(request);
Jeff Johnson72a40512013-12-19 10:14:15 -08007466
Jeff Johnson72a40512013-12-19 10:14:15 -08007467 return vstatus;
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007468}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007469#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007470
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007471#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowdade697412013-02-14 16:31:48 -08007472void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand)
7473{
7474 eCsrBand band = -1;
7475 sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band);
7476 switch (band)
7477 {
7478 case eCSR_BAND_ALL:
7479 *pBand = WLAN_HDD_UI_BAND_AUTO;
7480 break;
7481
7482 case eCSR_BAND_24:
7483 *pBand = WLAN_HDD_UI_BAND_2_4_GHZ;
7484 break;
7485
7486 case eCSR_BAND_5G:
7487 *pBand = WLAN_HDD_UI_BAND_5_GHZ;
7488 break;
7489
7490 default:
7491 hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band);
7492 *pBand = -1;
7493 break;
7494 }
7495}
7496
7497/**---------------------------------------------------------------------------
7498
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007499 \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data
7500
7501 This function parses the send action frame data passed in the format
7502 SENDACTIONFRAME<space><bssid><space><channel><space><dwelltime><space><data>
7503
Srinivas Girigowda56076852013-08-20 14:00:50 -07007504 \param - pValue Pointer to input data
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007505 \param - pTargetApBssid Pointer to target Ap bssid
7506 \param - pChannel Pointer to the Target AP channel
7507 \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame
7508 \param - pBuf Pointer to data
7509 \param - pBufLen Pointer to data length
7510
7511 \return - 0 for success non-zero for failure
7512
7513 --------------------------------------------------------------------------*/
7514VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel,
7515 tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen)
7516{
7517 tANI_U8 *inPtr = pValue;
7518 tANI_U8 *dataEnd;
7519 int tempInt;
7520 int j = 0;
7521 int i = 0;
7522 int v = 0;
7523 tANI_U8 tempBuf[32];
7524 tANI_U8 tempByte = 0;
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007525 /* 12 hexa decimal digits, 5 ':' and '\0' */
7526 tANI_U8 macAddress[18];
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007527
7528 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7529 /*no argument after the command*/
7530 if (NULL == inPtr)
7531 {
7532 return -EINVAL;
7533 }
7534
7535 /*no space after the command*/
7536 else if (SPACE_ASCII_VALUE != *inPtr)
7537 {
7538 return -EINVAL;
7539 }
7540
7541 /*removing empty spaces*/
7542 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7543
7544 /*no argument followed by spaces*/
7545 if ('\0' == *inPtr)
7546 {
7547 return -EINVAL;
7548 }
7549
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007550 v = sscanf(inPtr, "%17s", macAddress);
7551 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007552 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7554 "Invalid MAC address or All hex inputs are not read (%d)", v);
7555 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007556 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007557
7558 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7559 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7560 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7561 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7562 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7563 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007564
7565 /* point to the next argument */
7566 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7567 /*no argument after the command*/
7568 if (NULL == inPtr) return -EINVAL;
7569
7570 /*removing empty spaces*/
7571 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7572
7573 /*no argument followed by spaces*/
7574 if ('\0' == *inPtr)
7575 {
7576 return -EINVAL;
7577 }
7578
7579 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007580 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007581 if (1 != v) return -EINVAL;
7582
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007583 v = kstrtos32(tempBuf, 10, &tempInt);
Agarwal Ashish353b3a82014-04-08 14:55:11 +05307584 if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX )
Kiet Lambe150c22013-11-21 16:30:32 +05307585 return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007586
7587 *pChannel = tempInt;
7588
7589 /* point to the next argument */
7590 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7591 /*no argument after the command*/
7592 if (NULL == inPtr) return -EINVAL;
7593 /*removing empty spaces*/
7594 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7595
7596 /*no argument followed by spaces*/
7597 if ('\0' == *inPtr)
7598 {
7599 return -EINVAL;
7600 }
7601
7602 /*getting the next argument ie the dwell time */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007603 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007604 if (1 != v) return -EINVAL;
7605
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007606 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda5a6e0672014-01-09 14:42:57 -08007607 if ( v < 0 || tempInt < 0) return -EINVAL;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007608
7609 *pDwellTime = tempInt;
7610
7611 /* point to the next argument */
7612 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7613 /*no argument after the command*/
7614 if (NULL == inPtr) return -EINVAL;
7615 /*removing empty spaces*/
7616 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7617
7618 /*no argument followed by spaces*/
7619 if ('\0' == *inPtr)
7620 {
7621 return -EINVAL;
7622 }
7623
7624 /* find the length of data */
7625 dataEnd = inPtr;
7626 while(('\0' != *dataEnd) )
7627 {
7628 dataEnd++;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007629 }
Kiet Lambe150c22013-11-21 16:30:32 +05307630 *pBufLen = dataEnd - inPtr ;
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007631 if ( *pBufLen <= 0) return -EINVAL;
7632
Srinivas Girigowdab5ae85d2013-06-03 10:51:45 -07007633 /* Allocate the number of bytes based on the number of input characters
7634 whether it is even or odd.
7635 if the number of input characters are even, then we need N/2 byte.
7636 if the number of input characters are odd, then we need do (N+1)/2 to
7637 compensate rounding off.
7638 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7639 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7640 *pBuf = vos_mem_malloc((*pBufLen + 1)/2);
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007641 if (NULL == *pBuf)
7642 {
7643 hddLog(VOS_TRACE_LEVEL_FATAL,
7644 "%s: vos_mem_alloc failed ", __func__);
7645 return -EINVAL;
7646 }
7647
7648 /* the buffer received from the upper layer is character buffer,
7649 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7650 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7651 and f0 in 3rd location */
7652 for (i = 0, j = 0; j < *pBufLen; j += 2)
7653 {
Kiet Lambe150c22013-11-21 16:30:32 +05307654 if( j+1 == *pBufLen)
7655 {
7656 tempByte = hdd_parse_hex(inPtr[j]);
7657 }
7658 else
7659 {
7660 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7661 }
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007662 (*pBuf)[i++] = tempByte;
7663 }
7664 *pBufLen = i;
7665 return VOS_STATUS_SUCCESS;
7666}
7667
Srinivas Girigowda100eb322013-03-15 16:48:20 -07007668/**---------------------------------------------------------------------------
7669
Srinivas Girigowdade697412013-02-14 16:31:48 -08007670 \brief hdd_parse_channellist() - HDD Parse channel list
7671
7672 This function parses the channel list passed in the format
7673 SETROAMSCANCHANNELS<space><Number of channels><space>Channel 1<space>Channel 2<space>Channel N
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007674 if the Number of channels (N) does not match with the actual number of channels passed
7675 then take the minimum of N and count of (Ch1, Ch2, ...Ch M)
7676 For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken.
7677 If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48.
7678 This function does not take care of removing duplicate channels from the list
Srinivas Girigowdade697412013-02-14 16:31:48 -08007679
7680 \param - pValue Pointer to input channel list
7681 \param - ChannelList Pointer to local output array to record channel list
7682 \param - pNumChannels Pointer to number of roam scan channels
7683
7684 \return - 0 for success non-zero for failure
7685
7686 --------------------------------------------------------------------------*/
7687VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels)
7688{
7689 tANI_U8 *inPtr = pValue;
7690 int tempInt;
7691 int j = 0;
7692 int v = 0;
7693 char buf[32];
7694
7695 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7696 /*no argument after the command*/
7697 if (NULL == inPtr)
7698 {
7699 return -EINVAL;
7700 }
7701
7702 /*no space after the command*/
7703 else if (SPACE_ASCII_VALUE != *inPtr)
7704 {
7705 return -EINVAL;
7706 }
7707
7708 /*removing empty spaces*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007709 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007710
7711 /*no argument followed by spaces*/
7712 if ('\0' == *inPtr)
7713 {
7714 return -EINVAL;
7715 }
7716
7717 /*getting the first argument ie the number of channels*/
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007718 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007719 if (1 != v) return -EINVAL;
7720
Srinivas Girigowdade697412013-02-14 16:31:48 -08007721 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007722 if ((v < 0) ||
7723 (tempInt <= 0) ||
7724 (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN))
7725 {
7726 return -EINVAL;
7727 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007728
7729 *pNumChannels = tempInt;
7730
7731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7732 "Number of channels are: %d", *pNumChannels);
7733
7734 for (j = 0; j < (*pNumChannels); j++)
7735 {
7736 /*inPtr pointing to the beginning of first space after number of channels*/
7737 inPtr = strpbrk( inPtr, " " );
7738 /*no channel list after the number of channels argument*/
7739 if (NULL == inPtr)
7740 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007741 if (0 != j)
7742 {
7743 *pNumChannels = j;
7744 return VOS_STATUS_SUCCESS;
7745 }
7746 else
7747 {
7748 return -EINVAL;
7749 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007750 }
7751
7752 /*removing empty space*/
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007753 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++;
Srinivas Girigowdade697412013-02-14 16:31:48 -08007754
7755 /*no channel list after the number of channels argument and spaces*/
7756 if ( '\0' == *inPtr )
7757 {
Srinivas Girigowdacf9a9b42013-03-21 11:55:24 -07007758 if (0 != j)
7759 {
7760 *pNumChannels = j;
7761 return VOS_STATUS_SUCCESS;
7762 }
7763 else
7764 {
7765 return -EINVAL;
7766 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007767 }
7768
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007769 v = sscanf(inPtr, "%31s ", buf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007770 if (1 != v) return -EINVAL;
7771
Srinivas Girigowdade697412013-02-14 16:31:48 -08007772 v = kstrtos32(buf, 10, &tempInt);
Jeff Johnsona1f9afb2013-04-03 09:13:31 -07007773 if ((v < 0) ||
7774 (tempInt <= 0) ||
7775 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7776 {
7777 return -EINVAL;
7778 }
Srinivas Girigowdade697412013-02-14 16:31:48 -08007779 pChannelList[j] = tempInt;
7780
7781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7782 "Channel %d added to preferred channel list",
7783 pChannelList[j] );
7784 }
7785
Srinivas Girigowdade697412013-02-14 16:31:48 -08007786 return VOS_STATUS_SUCCESS;
7787}
7788
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007789
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307790/**
7791 * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data
7792 * This function parses the reasoc command data passed in the format
7793 * REASSOC<space><bssid><space><channel>
7794 *
7795 * @pValue: Pointer to input data (its a NUL terminated string)
7796 * @pTargetApBssid: Pointer to target Ap bssid
7797 * @pChannel: Pointer to the Target AP channel
7798 *
7799 * Return: 0 for success non-zero for failure
7800 */
7801static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue,
7802 tANI_U8 *pTargetApBssid, tANI_U8 *pChannel)
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007803{
Selvaraj, Sridhar5aff1ed2016-06-18 01:26:23 +05307804 const tANI_U8 *inPtr = pValue;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007805 int tempInt;
7806 int v = 0;
7807 tANI_U8 tempBuf[32];
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007808 /* 12 hexa decimal digits, 5 ':' and '\0' */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007809 tANI_U8 macAddress[18];
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007810
7811 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7812 /*no argument after the command*/
7813 if (NULL == inPtr)
7814 {
7815 return -EINVAL;
7816 }
7817
7818 /*no space after the command*/
7819 else if (SPACE_ASCII_VALUE != *inPtr)
7820 {
7821 return -EINVAL;
7822 }
7823
7824 /*removing empty spaces*/
7825 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7826
7827 /*no argument followed by spaces*/
7828 if ('\0' == *inPtr)
7829 {
7830 return -EINVAL;
7831 }
7832
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007833 v = sscanf(inPtr, "%17s", macAddress);
7834 if (!((1 == v) && hdd_is_valid_mac_address(macAddress)))
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007835 {
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7837 "Invalid MAC address or All hex inputs are not read (%d)", v);
7838 return -EINVAL;
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007839 }
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007840
7841 pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]);
7842 pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]);
7843 pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]);
7844 pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]);
7845 pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]);
7846 pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]);
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007847
7848 /* point to the next argument */
7849 inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE);
7850 /*no argument after the command*/
7851 if (NULL == inPtr) return -EINVAL;
7852
7853 /*removing empty spaces*/
7854 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7855
7856 /*no argument followed by spaces*/
7857 if ('\0' == *inPtr)
7858 {
7859 return -EINVAL;
7860 }
7861
7862 /*getting the next argument ie the channel number */
Srinivas Girigowda4081bb12014-01-06 17:12:58 -08007863 v = sscanf(inPtr, "%31s ", tempBuf);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007864 if (1 != v) return -EINVAL;
7865
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007866 v = kstrtos32(tempBuf, 10, &tempInt);
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007867 if ((v < 0) ||
Padma, Santhosh Kumar0fa809b2014-11-13 14:56:56 +05307868 (tempInt < 0) ||
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007869 (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX))
7870 {
7871 return -EINVAL;
7872 }
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007873
7874 *pChannel = tempInt;
7875 return VOS_STATUS_SUCCESS;
7876}
7877
7878#endif
7879
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007880#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007881/**---------------------------------------------------------------------------
7882
7883 \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE
7884
7885 This function parses the SETCCKM IE command
7886 SETCCKMIE<space><ie data>
7887
7888 \param - pValue Pointer to input data
7889 \param - pCckmIe Pointer to output cckm Ie
7890 \param - pCckmIeLen Pointer to output cckm ie length
7891
7892 \return - 0 for success non-zero for failure
7893
7894 --------------------------------------------------------------------------*/
7895VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe,
7896 tANI_U8 *pCckmIeLen)
7897{
7898 tANI_U8 *inPtr = pValue;
7899 tANI_U8 *dataEnd;
7900 int j = 0;
7901 int i = 0;
7902 tANI_U8 tempByte = 0;
7903
7904 inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE);
7905 /*no argument after the command*/
7906 if (NULL == inPtr)
7907 {
7908 return -EINVAL;
7909 }
7910
7911 /*no space after the command*/
7912 else if (SPACE_ASCII_VALUE != *inPtr)
7913 {
7914 return -EINVAL;
7915 }
7916
7917 /*removing empty spaces*/
7918 while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++;
7919
7920 /*no argument followed by spaces*/
7921 if ('\0' == *inPtr)
7922 {
7923 return -EINVAL;
7924 }
7925
7926 /* find the length of data */
7927 dataEnd = inPtr;
7928 while(('\0' != *dataEnd) )
7929 {
7930 dataEnd++;
7931 ++(*pCckmIeLen);
7932 }
7933 if ( *pCckmIeLen <= 0) return -EINVAL;
7934
7935 /* Allocate the number of bytes based on the number of input characters
7936 whether it is even or odd.
7937 if the number of input characters are even, then we need N/2 byte.
7938 if the number of input characters are odd, then we need do (N+1)/2 to
7939 compensate rounding off.
7940 For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough.
7941 If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */
7942 *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2);
7943 if (NULL == *pCckmIe)
7944 {
7945 hddLog(VOS_TRACE_LEVEL_FATAL,
7946 "%s: vos_mem_alloc failed ", __func__);
7947 return -EINVAL;
7948 }
7949 vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2);
7950 /* the buffer received from the upper layer is character buffer,
7951 we need to prepare the buffer taking 2 characters in to a U8 hex decimal number
7952 for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st
7953 and f0 in 3rd location */
7954 for (i = 0, j = 0; j < *pCckmIeLen; j += 2)
7955 {
7956 tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1]));
7957 (*pCckmIe)[i++] = tempByte;
7958 }
7959 *pCckmIeLen = i;
7960
7961 return VOS_STATUS_SUCCESS;
7962}
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007963#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
Srinivas Girigowda5cecb202013-10-08 09:13:25 -07007964
Jeff Johnson295189b2012-06-20 16:38:30 -07007965/**---------------------------------------------------------------------------
7966
Srinivas Girigowda0c69aee2013-10-09 17:21:01 -07007967 \brief hdd_is_valid_mac_address() - Validate MAC address
7968
7969 This function validates whether the given MAC address is valid or not
7970 Expected MAC address is of the format XX:XX:XX:XX:XX:XX
7971 where X is the hexa decimal digit character and separated by ':'
7972 This algorithm works even if MAC address is not separated by ':'
7973
7974 This code checks given input string mac contains exactly 12 hexadecimal digits.
7975 and a separator colon : appears in the input string only after
7976 an even number of hex digits.
7977
7978 \param - pMacAddr pointer to the input MAC address
7979 \return - 1 for valid and 0 for invalid
7980
7981 --------------------------------------------------------------------------*/
7982
7983v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr)
7984{
7985 int xdigit = 0;
7986 int separator = 0;
7987 while (*pMacAddr)
7988 {
7989 if (isxdigit(*pMacAddr))
7990 {
7991 xdigit++;
7992 }
7993 else if (':' == *pMacAddr)
7994 {
7995 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
7996 break;
7997
7998 ++separator;
7999 }
8000 else
8001 {
8002 separator = -1;
8003 /* Invalid MAC found */
8004 return 0;
8005 }
8006 ++pMacAddr;
8007 }
8008 return (xdigit == 12 && (separator == 5 || separator == 0));
8009}
8010
8011/**---------------------------------------------------------------------------
8012
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308013 \brief __hdd_open() - HDD Open function
Jeff Johnson295189b2012-06-20 16:38:30 -07008014
8015 \param - dev Pointer to net_device structure
8016
8017 \return - 0 for success non-zero for failure
8018
8019 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308020int __hdd_open(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008021{
8022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8023 hdd_context_t *pHddCtx;
8024 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8025 VOS_STATUS status;
8026 v_BOOL_t in_standby = TRUE;
8027
8028 if (NULL == pAdapter)
8029 {
8030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308031 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008032 return -ENODEV;
8033 }
8034
8035 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308036 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
8037 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -07008038 if (NULL == pHddCtx)
8039 {
8040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008041 "%s: HDD context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008042 return -ENODEV;
8043 }
8044
8045 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8046 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8047 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008048 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8049 {
8050 hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby",
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308051 __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008052 in_standby = FALSE;
8053 break;
8054 }
8055 else
8056 {
8057 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8058 pAdapterNode = pNext;
8059 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 }
8061
8062 if (TRUE == in_standby)
8063 {
8064 if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter))
8065 {
8066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring "
8067 "wlan out of power save", __func__);
8068 return -EINVAL;
8069 }
8070 }
8071
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008072 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008073 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
8074 {
8075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008076 "%s: Enabling Tx Queues", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008077 /* Enable TX queues only when we are connected */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308078 hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 netif_tx_start_all_queues(dev);
8080 }
8081
8082 return 0;
8083}
8084
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308085/**---------------------------------------------------------------------------
8086
8087 \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR
8088
8089 This is called in response to ifconfig up
8090
8091 \param - dev Pointer to net_device structure
8092
8093 \return - 0 for success non-zero for failure
8094
8095 --------------------------------------------------------------------------*/
8096int hdd_open(struct net_device *dev)
8097{
8098 int ret;
8099
8100 vos_ssr_protect(__func__);
8101 ret = __hdd_open(dev);
8102 vos_ssr_unprotect(__func__);
8103
8104 return ret;
8105}
8106
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308107int __hdd_mon_open (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008108{
8109 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308110 hdd_adapter_t *sta_adapter;
8111 hdd_context_t *hdd_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008112
8113 if(pAdapter == NULL) {
8114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008115 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08008116 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 }
8118
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308119 if (vos_get_concurrency_mode() != VOS_STA_MON)
8120 return 0;
8121
8122 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
8123 if (wlan_hdd_validate_context(hdd_ctx))
8124 return -EINVAL;
8125
8126 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
8127 if (!sta_adapter) {
8128 hddLog(LOGE, FL("No valid STA interface"));
8129 return -EINVAL;
8130 }
8131
8132 if (!test_bit(DEVICE_IFACE_OPENED, &sta_adapter->event_flags)) {
8133 hddLog(LOGE, FL("STA Interface is not OPENED"));
8134 return -EINVAL;
8135 }
8136
8137 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
8138
Jeff Johnson295189b2012-06-20 16:38:30 -07008139 return 0;
8140}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308141
8142int hdd_mon_open (struct net_device *dev)
8143{
8144 int ret;
8145
8146 vos_ssr_protect(__func__);
8147 ret = __hdd_mon_open(dev);
8148 vos_ssr_unprotect(__func__);
8149
8150 return ret;
8151}
8152
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308153int __hdd_mon_stop (struct net_device *dev)
8154{
8155 hdd_adapter_t *mon_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8156 hdd_context_t *hdd_ctx;
8157
8158 if (vos_get_concurrency_mode() != VOS_STA_MON)
8159 return 0;
8160
8161 if(!mon_adapter) {
8162 hddLog(LOGE, FL("HDD adapter is Null"));
8163 return -EINVAL;
8164 }
8165
8166 hdd_ctx = WLAN_HDD_GET_CTX(mon_adapter);
8167 if (wlan_hdd_validate_context(hdd_ctx))
8168 return -EINVAL;
8169
8170 if (!test_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags)) {
8171 hddLog(LOGE, FL("NETDEV Interface is not OPENED"));
8172 return -ENODEV;
8173 }
8174
8175 clear_bit(DEVICE_IFACE_OPENED, &mon_adapter->event_flags);
8176 hdd_stop_adapter(hdd_ctx, mon_adapter, VOS_FALSE);
8177
8178 return 0;
8179}
8180
Katya Nigame7b69a82015-04-28 15:24:06 +05308181int hdd_mon_stop(struct net_device *dev)
8182{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308183 int ret;
8184
8185 vos_ssr_protect(__func__);
8186 ret = __hdd_mon_stop(dev);
8187 vos_ssr_unprotect(__func__);
8188
8189 return ret;
Katya Nigame7b69a82015-04-28 15:24:06 +05308190}
8191
Jeff Johnson295189b2012-06-20 16:38:30 -07008192/**---------------------------------------------------------------------------
8193
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308194 \brief __hdd_stop() - HDD stop function
Jeff Johnson295189b2012-06-20 16:38:30 -07008195
8196 \param - dev Pointer to net_device structure
8197
8198 \return - 0 for success non-zero for failure
8199
8200 --------------------------------------------------------------------------*/
8201
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308202int __hdd_stop (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008203{
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308204 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8206 hdd_context_t *pHddCtx;
8207 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8208 VOS_STATUS status;
8209 v_BOOL_t enter_standby = TRUE;
8210
8211 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008212 if (NULL == pAdapter)
8213 {
8214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Agarwal Ashish971c2882013-10-30 20:11:12 +05308215 "%s: pAdapter is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008216 return -ENODEV;
8217 }
Sachin Ahuja9b4958f2015-01-15 21:37:00 +05308218 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308219 pAdapter->sessionId, pAdapter->device_mode));
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308220
8221 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8222 ret = wlan_hdd_validate_context(pHddCtx);
8223 if (ret)
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 {
Vinay Krishna Eranna90f43532014-10-27 16:45:54 +05308225 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008226 }
8227
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308228 /* Nothing to be done if the interface is not opened */
8229 if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags))
8230 {
8231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8232 "%s: NETDEV Interface is not OPENED", __func__);
8233 return -ENODEV;
8234 }
8235
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308236 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308237 /*
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308238 * In STA + Monitor mode concurrency, no point in running
8239 * capture on monitor interface, when STA interface is stopped
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308240 */
Rajeev Kumar Sirasanagandlaa74e1222018-01-09 17:38:55 +05308241 wlan_hdd_stop_mon(pHddCtx, true);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308242 }
8243
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308244 /* Make sure the interface is marked as closed */
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008245 clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -07008246 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308247
8248 /* Disable TX on the interface, after this hard_start_xmit() will not
8249 * be called on that interface
8250 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05308251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 netif_tx_disable(pAdapter->dev);
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308253
8254 /* Mark the interface status as "down" for outside world */
Jeff Johnson295189b2012-06-20 16:38:30 -07008255 netif_carrier_off(pAdapter->dev);
8256
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308257 /* The interface is marked as down for outside world (aka kernel)
8258 * But the driver is pretty much alive inside. The driver needs to
8259 * tear down the existing connection on the netdev (session)
8260 * cleanup the data pipes and wait until the control plane is stabilized
8261 * for this interface. The call also needs to wait until the above
8262 * mentioned actions are completed before returning to the caller.
8263 * Notice that the hdd_stop_adapter is requested not to close the session
8264 * That is intentional to be able to scan if it is a STA/P2P interface
8265 */
8266 hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308267#ifdef FEATURE_WLAN_TDLS
8268 mutex_lock(&pHddCtx->tdls_lock);
8269#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308270 /* DeInit the adapter. This ensures datapath cleanup as well */
c_hpothu002231a2015-02-05 14:58:51 +05308271 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308272#ifdef FEATURE_WLAN_TDLS
8273 mutex_unlock(&pHddCtx->tdls_lock);
8274#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008275 /* SoftAP ifaces should never go in power save mode
8276 making sure same here. */
8277 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008278 || (WLAN_HDD_P2P_GO == pAdapter->device_mode )
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 )
8280 {
8281 /* SoftAP mode, so return from here */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8283 "%s: In SAP MODE", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 EXIT();
8285 return 0;
8286 }
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308287 /* Find if any iface is up. If any iface is up then can't put device to
8288 * sleep/power save mode
8289 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008290 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8291 while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) )
8292 {
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008293 if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags))
8294 {
8295 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot "
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308296 "put device to sleep", __func__);
Jeff Johnson6a81ca42013-04-05 10:37:08 -07008297 enter_standby = FALSE;
8298 break;
8299 }
8300 else
8301 {
8302 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8303 pAdapterNode = pNext;
8304 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008305 }
8306
8307 if (TRUE == enter_standby)
8308 {
8309 hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down "
8310 "entering standby", __func__);
8311 if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx))
8312 {
8313 /*log and return success*/
8314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put "
8315 "wlan in power save", __func__);
8316 }
8317 }
8318
8319 EXIT();
8320 return 0;
8321}
8322
8323/**---------------------------------------------------------------------------
8324
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308325 \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR
Jeff Johnson295189b2012-06-20 16:38:30 -07008326
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308327 This is called in response to ifconfig down
8328
8329 \param - dev Pointer to net_device structure
8330
8331 \return - 0 for success non-zero for failure
8332-----------------------------------------------------------------------------*/
8333int hdd_stop (struct net_device *dev)
8334{
8335 int ret;
8336
8337 vos_ssr_protect(__func__);
8338 ret = __hdd_stop(dev);
8339 vos_ssr_unprotect(__func__);
8340
8341 return ret;
8342}
8343
8344/**---------------------------------------------------------------------------
8345
8346 \brief __hdd_uninit() - HDD uninit function
Jeff Johnson295189b2012-06-20 16:38:30 -07008347
8348 \param - dev Pointer to net_device structure
8349
8350 \return - void
8351
8352 --------------------------------------------------------------------------*/
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308353static void __hdd_uninit (struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -07008354{
8355 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308356 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008357 ENTER();
8358
8359 do
8360 {
8361 if (NULL == pAdapter)
8362 {
8363 hddLog(VOS_TRACE_LEVEL_FATAL,
8364 "%s: NULL pAdapter", __func__);
8365 break;
8366 }
8367
8368 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8369 {
8370 hddLog(VOS_TRACE_LEVEL_FATAL,
8371 "%s: Invalid magic", __func__);
8372 break;
8373 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308374 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8375 if (NULL == pHddCtx)
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 {
8377 hddLog(VOS_TRACE_LEVEL_FATAL,
8378 "%s: NULL pHddCtx", __func__);
8379 break;
8380 }
8381
8382 if (dev != pAdapter->dev)
8383 {
8384 hddLog(VOS_TRACE_LEVEL_FATAL,
8385 "%s: Invalid device reference", __func__);
8386 /* we haven't validated all cases so let this go for now */
8387 }
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308388#ifdef FEATURE_WLAN_TDLS
8389 mutex_lock(&pHddCtx->tdls_lock);
8390#endif
c_hpothu002231a2015-02-05 14:58:51 +05308391 hdd_deinit_adapter(pHddCtx, pAdapter, TRUE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05308392#ifdef FEATURE_WLAN_TDLS
8393 mutex_unlock(&pHddCtx->tdls_lock);
8394#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008395
8396 /* after uninit our adapter structure will no longer be valid */
8397 pAdapter->dev = NULL;
8398 pAdapter->magic = 0;
Manjeet Singh47ee8472016-04-11 11:57:18 +05308399 pAdapter->pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008400 } while (0);
8401
8402 EXIT();
8403}
8404
8405/**---------------------------------------------------------------------------
8406
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308407 \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
8408
8409 This is called during the netdev unregister to uninitialize all data
8410associated with the device
8411
8412 \param - dev Pointer to net_device structure
8413
8414 \return - void
8415
8416 --------------------------------------------------------------------------*/
8417static void hdd_uninit (struct net_device *dev)
8418{
8419 vos_ssr_protect(__func__);
8420 __hdd_uninit(dev);
8421 vos_ssr_unprotect(__func__);
8422}
8423
8424/**---------------------------------------------------------------------------
8425
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 \brief hdd_release_firmware() -
8427
8428 This function calls the release firmware API to free the firmware buffer.
8429
8430 \param - pFileName Pointer to the File Name.
8431 pCtx - Pointer to the adapter .
8432
8433
8434 \return - 0 for success, non zero for failure
8435
8436 --------------------------------------------------------------------------*/
8437
8438VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx)
8439{
8440 VOS_STATUS status = VOS_STATUS_SUCCESS;
8441 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8442 ENTER();
8443
8444
8445 if (!strcmp(WLAN_FW_FILE, pFileName)) {
8446
8447 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName);
8448
8449 if(pHddCtx->fw) {
8450 release_firmware(pHddCtx->fw);
8451 pHddCtx->fw = NULL;
8452 }
8453 else
8454 status = VOS_STATUS_E_FAILURE;
8455 }
8456 else if (!strcmp(WLAN_NV_FILE,pFileName)) {
8457 if(pHddCtx->nv) {
8458 release_firmware(pHddCtx->nv);
8459 pHddCtx->nv = NULL;
8460 }
8461 else
8462 status = VOS_STATUS_E_FAILURE;
8463
8464 }
8465
8466 EXIT();
8467 return status;
8468}
8469
8470/**---------------------------------------------------------------------------
8471
8472 \brief hdd_request_firmware() -
8473
8474 This function reads the firmware file using the request firmware
8475 API and returns the the firmware data and the firmware file size.
8476
8477 \param - pfileName - Pointer to the file name.
8478 - pCtx - Pointer to the adapter .
8479 - ppfw_data - Pointer to the pointer of the firmware data.
8480 - pSize - Pointer to the file size.
8481
8482 \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure
8483
8484 --------------------------------------------------------------------------*/
8485
8486
8487VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize)
8488{
8489 int status;
8490 VOS_STATUS retval = VOS_STATUS_SUCCESS;
8491 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8492 ENTER();
8493
8494 if( (!strcmp(WLAN_FW_FILE, pfileName)) ) {
8495
8496 status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev);
8497
8498 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8499 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed",
8500 __func__, pfileName);
8501 retval = VOS_STATUS_E_FAILURE;
8502 }
8503
8504 else {
8505 *ppfw_data = (v_VOID_t *)pHddCtx->fw->data;
8506 *pSize = pHddCtx->fw->size;
8507 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d",
8508 __func__, *pSize);
8509 }
8510 }
8511 else if(!strcmp(WLAN_NV_FILE, pfileName)) {
8512
8513 status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev);
8514
8515 if(status || !pHddCtx->nv || !pHddCtx->nv->data) {
8516 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed",
8517 __func__, pfileName);
8518 retval = VOS_STATUS_E_FAILURE;
8519 }
8520
8521 else {
8522 *ppfw_data = (v_VOID_t *)pHddCtx->nv->data;
8523 *pSize = pHddCtx->nv->size;
8524 hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d",
8525 __func__, *pSize);
8526 }
8527 }
8528
8529 EXIT();
8530 return retval;
8531}
8532/**---------------------------------------------------------------------------
8533 \brief hdd_full_pwr_cbk() - HDD full power callbackfunction
8534
8535 This is the function invoked by SME to inform the result of a full power
8536 request issued by HDD
8537
8538 \param - callbackcontext - Pointer to cookie
8539 status - result of request
8540
8541 \return - None
8542
8543--------------------------------------------------------------------------*/
8544void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status)
8545{
8546 hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext;
8547
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008548 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008549 if(&pHddCtx->full_pwr_comp_var)
8550 {
8551 complete(&pHddCtx->full_pwr_comp_var);
8552 }
8553}
8554
Abhishek Singh00b71972016-01-07 10:51:04 +05308555#ifdef WLAN_FEATURE_RMC
8556static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo)
8557{
8558 int payload_len;
8559 struct sk_buff *skb;
8560 struct nlmsghdr *nlh;
8561 v_U8_t *data;
8562
8563 payload_len = ETH_ALEN;
8564
8565 if (0 == cesium_pid)
8566 {
8567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered",
8568 __func__);
8569 return;
8570 }
8571
8572 if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL)
8573 {
8574 hddLog(VOS_TRACE_LEVEL_ERROR,
8575 "%s: nlmsg_new() failed for msg size[%d]",
8576 __func__, NLMSG_SPACE(payload_len));
8577 return;
8578 }
8579
8580 nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST);
8581
8582 if (NULL == nlh)
8583 {
8584 hddLog(VOS_TRACE_LEVEL_ERROR,
8585 "%s: nlmsg_put() failed for msg size[%d]",
8586 __func__, NLMSG_SPACE(payload_len));
8587
8588 kfree_skb(skb);
8589 return;
8590 }
8591
8592 data = nlmsg_data(nlh);
8593 memcpy(data, MacAddr, ETH_ALEN);
8594
8595 if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0)
8596 {
8597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]",
8598 __func__, NLMSG_SPACE(payload_len));
8599 }
8600
8601 return;
8602}
8603
8604/**---------------------------------------------------------------------------
8605 \brief hdd_ParseuserParams - return a pointer to the next argument
8606
8607 \return - status
8608
8609--------------------------------------------------------------------------*/
8610static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg)
8611{
8612 tANI_U8 *pVal;
8613
8614 pVal = strchr(pValue, ' ');
8615
8616 if (NULL == pVal)
8617 {
8618 /* no argument remains */
8619 return -EINVAL;
8620 }
8621 else if (SPACE_ASCII_VALUE != *pVal)
8622 {
8623 /* no space after the current argument */
8624 return -EINVAL;
8625 }
8626
8627 pVal++;
8628
8629 /* remove empty spaces */
8630 while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal))
8631 {
8632 pVal++;
8633 }
8634
8635 /* no argument followed by spaces */
8636 if ('\0' == *pVal)
8637 {
8638 return -EINVAL;
8639 }
8640
8641 *ppArg = pVal;
8642
8643 return 0;
8644}
8645
8646/**----------------------------------------------------------------------------
8647 \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT
8648
8649 \return - status
8650
8651------------------------------------------------------------------------------*/
8652static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
8653 tANI_U8 *tx_fail_count,
8654 tANI_U16 *pid)
8655{
8656 tANI_U8 *param = NULL;
8657 int ret;
8658
8659 ret = hdd_ParseUserParams(pValue, &param);
8660
8661 if (0 == ret && NULL != param)
8662 {
8663 if (1 != sscanf(param, "%hhu", tx_fail_count))
8664 {
8665 ret = -EINVAL;
8666 goto done;
8667 }
8668 }
8669 else
8670 {
8671 goto done;
8672 }
8673
8674 if (0 == *tx_fail_count)
8675 {
8676 *pid = 0;
8677 goto done;
8678 }
8679
8680 pValue = param;
8681 pValue++;
8682
8683 ret = hdd_ParseUserParams(pValue, &param);
8684
8685 if (0 == ret)
8686 {
8687 if (1 != sscanf(param, "%hu", pid))
8688 {
8689 ret = -EINVAL;
8690 goto done;
8691 }
8692 }
8693 else
8694 {
8695 goto done;
8696 }
8697
8698done:
8699 return ret;
8700}
8701
8702static int hdd_open_cesium_nl_sock()
8703{
8704#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8705 struct netlink_kernel_cfg cfg = {
8706 .groups = WLAN_NLINK_MCAST_GRP_ID,
8707 .input = NULL
8708 };
8709#endif
8710 int ret = 0;
8711
8712#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8713 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8714#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
8715 THIS_MODULE,
8716#endif
8717 &cfg);
8718#else
8719 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
8720 WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE);
8721#endif
8722
8723 if (cesium_nl_srv_sock == NULL)
8724 {
8725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8726 "NLINK: cesium netlink_kernel_create failed");
8727 ret = -ECONNREFUSED;
8728 }
8729
8730 return ret;
8731}
8732
8733static void hdd_close_cesium_nl_sock()
8734{
8735 if (NULL != cesium_nl_srv_sock)
8736 {
8737 netlink_kernel_release(cesium_nl_srv_sock);
8738 cesium_nl_srv_sock = NULL;
8739 }
8740}
8741#endif /* WLAN_FEATURE_RMC */
Jeff Johnson295189b2012-06-20 16:38:30 -07008742/**---------------------------------------------------------------------------
8743
8744 \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function
8745
8746 This is the function invoked by SME to inform the result of BMPS
8747 request issued by HDD
8748
8749 \param - callbackcontext - Pointer to cookie
8750 status - result of request
8751
8752 \return - None
8753
8754--------------------------------------------------------------------------*/
8755void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status)
8756{
8757
8758 struct completion *completion_var = (struct completion*) callbackContext;
8759
Arif Hussain6d2a3322013-11-17 19:50:10 -08008760 hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008761 if(completion_var != NULL)
8762 {
8763 complete(completion_var);
8764 }
8765}
8766
8767/**---------------------------------------------------------------------------
8768
8769 \brief hdd_get_cfg_file_size() -
8770
8771 This function reads the configuration file using the request firmware
8772 API and returns the configuration file size.
8773
8774 \param - pCtx - Pointer to the adapter .
8775 - pFileName - Pointer to the file name.
8776 - pBufSize - Pointer to the buffer size.
8777
8778 \return - 0 for success, non zero for failure
8779
8780 --------------------------------------------------------------------------*/
8781
8782VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize)
8783{
8784 int status;
8785 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8786
8787 ENTER();
8788
8789 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8790
8791 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8792 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8793 status = VOS_STATUS_E_FAILURE;
8794 }
8795 else {
8796 *pBufSize = pHddCtx->fw->size;
8797 hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize);
8798 release_firmware(pHddCtx->fw);
8799 pHddCtx->fw = NULL;
8800 }
8801
8802 EXIT();
8803 return VOS_STATUS_SUCCESS;
8804}
8805
8806/**---------------------------------------------------------------------------
8807
8808 \brief hdd_read_cfg_file() -
8809
8810 This function reads the configuration file using the request firmware
8811 API and returns the cfg data and the buffer size of the configuration file.
8812
8813 \param - pCtx - Pointer to the adapter .
8814 - pFileName - Pointer to the file name.
8815 - pBuffer - Pointer to the data buffer.
8816 - pBufSize - Pointer to the buffer size.
8817
8818 \return - 0 for success, non zero for failure
8819
8820 --------------------------------------------------------------------------*/
8821
8822VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName,
8823 v_VOID_t *pBuffer, v_SIZE_t *pBufSize)
8824{
8825 int status;
8826 hdd_context_t *pHddCtx = (hdd_context_t*)pCtx;
8827
8828 ENTER();
8829
8830 status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev);
8831
8832 if(status || !pHddCtx->fw || !pHddCtx->fw->data) {
8833 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__);
8834 return VOS_STATUS_E_FAILURE;
8835 }
8836 else {
8837 if(*pBufSize != pHddCtx->fw->size) {
8838 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG "
8839 "file size", __func__);
8840 release_firmware(pHddCtx->fw);
8841 pHddCtx->fw = NULL;
8842 return VOS_STATUS_E_FAILURE;
8843 }
8844 else {
8845 if(pBuffer) {
8846 vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize);
8847 }
8848 release_firmware(pHddCtx->fw);
8849 pHddCtx->fw = NULL;
8850 }
8851 }
8852
8853 EXIT();
8854
8855 return VOS_STATUS_SUCCESS;
8856}
8857
8858/**---------------------------------------------------------------------------
8859
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308860 \brief __hdd_set_mac_address() -
Jeff Johnson295189b2012-06-20 16:38:30 -07008861
8862 This function sets the user specified mac address using
8863 the command ifconfig wlanX hw ether <mac adress>.
8864
8865 \param - dev - Pointer to the net device.
8866 - addr - Pointer to the sockaddr.
8867 \return - 0 for success, non zero for failure
8868
8869 --------------------------------------------------------------------------*/
8870
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308871static int __hdd_set_mac_address(struct net_device *dev, void *addr)
Jeff Johnson295189b2012-06-20 16:38:30 -07008872{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308873 hdd_adapter_t *pAdapter;
8874 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 struct sockaddr *psta_mac_addr = addr;
8876 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308877 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008878
8879 ENTER();
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308880 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8881 if (NULL == pAdapter)
8882 {
8883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8884 "%s: Adapter is NULL",__func__);
8885 return -EINVAL;
8886 }
8887 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8888 ret = wlan_hdd_validate_context(pHddCtx);
8889 if (0 != ret)
8890 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308891 return ret;
8892 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008893
8894 memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN);
Jeff Johnson295189b2012-06-20 16:38:30 -07008895 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
8896
8897 EXIT();
8898 return halStatus;
8899}
8900
Mahesh A Saptasgar64534612014-09-23 13:13:33 +05308901/**---------------------------------------------------------------------------
8902
8903 \brief hdd_set_mac_address() -
8904
8905 Wrapper function to protect __hdd_set_mac_address() function from ssr
8906
8907 \param - dev - Pointer to the net device.
8908 - addr - Pointer to the sockaddr.
8909 \return - 0 for success, non zero for failure
8910
8911 --------------------------------------------------------------------------*/
8912static int hdd_set_mac_address(struct net_device *dev, void *addr)
8913{
8914 int ret;
8915
8916 vos_ssr_protect(__func__);
8917 ret = __hdd_set_mac_address(dev, addr);
8918 vos_ssr_unprotect(__func__);
8919
8920 return ret;
8921}
8922
Jeff Johnson295189b2012-06-20 16:38:30 -07008923tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx)
8924{
8925 int i;
8926 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8927 {
Abhishek Singheb183782014-02-06 13:37:21 +05308928 if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 break;
8930 }
8931
8932 if( VOS_MAX_CONCURRENCY_PERSONA == i)
8933 return NULL;
8934
8935 pHddCtx->cfg_ini->intfAddrMask |= (1 << i);
8936 return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0];
8937}
8938
8939void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr)
8940{
8941 int i;
8942 for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
8943 {
8944 if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) )
8945 {
8946 pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i);
8947 break;
8948 }
8949 }
8950 return;
8951}
8952
8953#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
8954 static struct net_device_ops wlan_drv_ops = {
8955 .ndo_open = hdd_open,
8956 .ndo_stop = hdd_stop,
8957 .ndo_uninit = hdd_uninit,
8958 .ndo_start_xmit = hdd_hard_start_xmit,
8959 .ndo_tx_timeout = hdd_tx_timeout,
8960 .ndo_get_stats = hdd_stats,
8961 .ndo_do_ioctl = hdd_ioctl,
8962 .ndo_set_mac_address = hdd_set_mac_address,
8963 .ndo_select_queue = hdd_select_queue,
8964#ifdef WLAN_FEATURE_PACKET_FILTERING
8965#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0))
8966 .ndo_set_rx_mode = hdd_set_multicast_list,
8967#else
8968 .ndo_set_multicast_list = hdd_set_multicast_list,
8969#endif //LINUX_VERSION_CODE
8970#endif
8971 };
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 static struct net_device_ops wlan_mon_drv_ops = {
8973 .ndo_open = hdd_mon_open,
Katya Nigame7b69a82015-04-28 15:24:06 +05308974 .ndo_stop = hdd_mon_stop,
Jeff Johnson295189b2012-06-20 16:38:30 -07008975 .ndo_uninit = hdd_uninit,
8976 .ndo_start_xmit = hdd_mon_hard_start_xmit,
8977 .ndo_tx_timeout = hdd_tx_timeout,
8978 .ndo_get_stats = hdd_stats,
Katya Nigame7b69a82015-04-28 15:24:06 +05308979 .ndo_do_ioctl = hdd_mon_ioctl,
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 .ndo_set_mac_address = hdd_set_mac_address,
8981 };
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +05308982
Jeff Johnson295189b2012-06-20 16:38:30 -07008983#endif
8984
8985void hdd_set_station_ops( struct net_device *pWlanDev )
8986{
8987#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
Jeff Johnson295189b2012-06-20 16:38:30 -07008988 pWlanDev->netdev_ops = &wlan_drv_ops;
8989#else
8990 pWlanDev->open = hdd_open;
8991 pWlanDev->stop = hdd_stop;
8992 pWlanDev->uninit = hdd_uninit;
8993 pWlanDev->hard_start_xmit = NULL;
8994 pWlanDev->tx_timeout = hdd_tx_timeout;
8995 pWlanDev->get_stats = hdd_stats;
8996 pWlanDev->do_ioctl = hdd_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 pWlanDev->set_mac_address = hdd_set_mac_address;
8998#endif
8999}
9000
Katya Nigam1fd24402015-02-16 14:52:19 +05309001void hdd_set_ibss_ops( hdd_adapter_t *pAdapter )
9002{
9003 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9004 wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit;
9005 #else
9006 pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit;
9007 #endif
9008}
9009
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009010static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name )
Jeff Johnson295189b2012-06-20 16:38:30 -07009011{
9012 struct net_device *pWlanDev = NULL;
9013 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009014 /*
9015 * cfg80211 initialization and registration....
9016 */
Anand N Sunkadc34abbd2015-07-29 09:52:59 +05309017 pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name,
9018#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
9019 NET_NAME_UNKNOWN,
9020#endif
9021 ether_setup, NUM_TX_QUEUES);
Jeff Johnson295189b2012-06-20 16:38:30 -07009022 if(pWlanDev != NULL)
9023 {
9024
9025 //Save the pointer to the net_device in the HDD adapter
9026 pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev );
9027
Jeff Johnson295189b2012-06-20 16:38:30 -07009028 vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) );
9029
9030 pAdapter->dev = pWlanDev;
9031 pAdapter->pHddCtx = pHddCtx;
9032 pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Agarwal Ashish47d18112014-08-04 19:55:07 +05309033 spin_lock_init(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -07009034
Rajeev79dbe4c2013-10-05 11:03:42 +05309035#ifdef FEATURE_WLAN_BATCH_SCAN
Rajeev79dbe4c2013-10-05 11:03:42 +05309036 pAdapter->pBatchScanRsp = NULL;
9037 pAdapter->numScanList = 0;
Rajeev Kumar20140c12013-10-21 19:39:02 -07009038 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
Kiet Lamaa8e15a2014-02-11 23:30:06 -08009039 pAdapter->prev_batch_id = 0;
Rajeev79dbe4c2013-10-05 11:03:42 +05309040 mutex_init(&pAdapter->hdd_batch_scan_lock);
9041#endif
9042
Jeff Johnson295189b2012-06-20 16:38:30 -07009043 pAdapter->isLinkUpSvcNeeded = FALSE;
9044 pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE;
9045 //Init the net_device structure
9046 strlcpy(pWlanDev->name, name, IFNAMSIZ);
9047
9048 vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
9049 vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr));
9050 pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT;
9051 pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM;
9052
9053 hdd_set_station_ops( pAdapter->dev );
9054
9055 pWlanDev->destructor = free_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009056 pWlanDev->ieee80211_ptr = &pAdapter->wdev ;
9057 pAdapter->wdev.wiphy = pHddCtx->wiphy;
9058 pAdapter->wdev.netdev = pWlanDev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009059 /* set pWlanDev's parent to underlying device */
9060 SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev);
Kumar Anand82c009f2014-05-29 00:29:42 -07009061
9062 hdd_wmm_init( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009063 }
9064
9065 return pAdapter;
9066}
9067
9068VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held )
9069{
9070 struct net_device *pWlanDev = pAdapter->dev;
9071 //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9072 //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9073 //eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9074
9075 if( rtnl_lock_held )
9076 {
Madan Mohan Koyyalamudid8ac8662012-11-06 19:04:56 -08009077 if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) {
Jeff Johnson295189b2012-06-20 16:38:30 -07009078 if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 )
9079 {
9080 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__);
9081 return VOS_STATUS_E_FAILURE;
9082 }
9083 }
9084 if (register_netdevice(pWlanDev))
9085 {
9086 hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__);
9087 return VOS_STATUS_E_FAILURE;
9088 }
9089 }
9090 else
9091 {
9092 if(register_netdev(pWlanDev))
9093 {
9094 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__);
9095 return VOS_STATUS_E_FAILURE;
9096 }
9097 }
9098 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
9099
9100 return VOS_STATUS_SUCCESS;
9101}
9102
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009103static eHalStatus hdd_smeCloseSessionCallback(void *pContext)
Jeff Johnson295189b2012-06-20 16:38:30 -07009104{
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009105 hdd_adapter_t *pAdapter = pContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009106
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009107 if (NULL == pAdapter)
9108 {
9109 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__);
9110 return eHAL_STATUS_INVALID_PARAMETER;
Jeff Johnson295189b2012-06-20 16:38:30 -07009111 }
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009112
9113 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9114 {
9115 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__);
9116 return eHAL_STATUS_NOT_INITIALIZED;
9117 }
9118
9119 clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
9120
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009121#ifndef WLAN_OPEN_SOURCE
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009122 /* need to make sure all of our scheduled work has completed.
9123 * This callback is called from MC thread context, so it is safe to
9124 * to call below flush workqueue API from here.
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009125 *
9126 * Even though this is called from MC thread context, if there is a faulty
9127 * work item in the system, that can hang this call forever. So flushing
9128 * this global work queue is not safe; and now we make sure that
9129 * individual work queues are stopped correctly. But the cancel work queue
9130 * is a GPL only API, so the proprietary version of the driver would still
9131 * rely on the global work queue flush.
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009132 */
9133 flush_scheduled_work();
Sameer Thalappilbee426e2013-10-30 10:30:30 -07009134#endif
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009135
9136 /* We can be blocked while waiting for scheduled work to be
9137 * flushed, and the adapter structure can potentially be freed, in
9138 * which case the magic will have been reset. So make sure the
9139 * magic is still good, and hence the adapter structure is still
9140 * valid, before signaling completion */
9141 if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)
9142 {
9143 complete(&pAdapter->session_close_comp_var);
9144 }
9145
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 return eHAL_STATUS_SUCCESS;
9147}
Manjeet Singh47ee8472016-04-11 11:57:18 +05309148/**
9149 * hdd_close_tx_queues() - close tx queues
9150 * @hdd_ctx: hdd global context
9151 *
9152 * Return: None
9153 */
9154static void hdd_close_tx_queues(hdd_context_t *hdd_ctx)
9155{
9156 VOS_STATUS status;
9157 hdd_adapter_t *adapter;
9158 hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL;
9159 /* Not validating hdd_ctx as it's already done by the caller */
9160 ENTER();
9161 status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
9162 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) {
9163 adapter = adapter_node->pAdapter;
9164 if (adapter && adapter->dev) {
9165 netif_tx_disable (adapter->dev);
9166 netif_carrier_off(adapter->dev);
9167 }
9168 status = hdd_get_next_adapter(hdd_ctx, adapter_node,
9169 &next_adapter);
9170 adapter_node = next_adapter;
9171 }
9172 EXIT();
9173}
Jeff Johnson295189b2012-06-20 16:38:30 -07009174
9175VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter )
9176{
9177 struct net_device *pWlanDev = pAdapter->dev;
9178 hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
9179 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
9180 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
9181 VOS_STATUS status = VOS_STATUS_E_FAILURE;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309182 long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009183
Nirav Shah7e3c8132015-06-22 23:51:42 +05309184 spin_lock_init( &pAdapter->sta_hash_lock);
9185 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9186
Jeff Johnson295189b2012-06-20 16:38:30 -07009187 INIT_COMPLETION(pAdapter->session_open_comp_var);
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009188 sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 //Open a SME session for future operation
9190 halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter,
Kiran Kumar Lokere0ad5cd32013-06-25 11:26:22 -07009191 (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009192 if ( !HAL_STATUS_SUCCESS( halStatus ) )
9193 {
9194 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009195 "sme_OpenSession() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009196 halStatus, halStatus );
9197 status = VOS_STATUS_E_FAILURE;
9198 goto error_sme_open;
9199 }
9200
9201 //Block on a completion variable. Can't wait forever though.
Vinay Krishna Eranna0fe2e7c2014-04-09 21:32:08 +05309202 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009203 &pAdapter->session_open_comp_var,
9204 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309205 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009206 {
9207 hddLog(VOS_TRACE_LEVEL_FATAL,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309208 "Session is not opened within timeout period code %ld", rc );
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 status = VOS_STATUS_E_FAILURE;
9210 goto error_sme_open;
9211 }
9212
9213 // Register wireless extensions
9214 if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev)))
9215 {
9216 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009217 "hdd_register_wext() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009218 halStatus, halStatus );
9219 status = VOS_STATUS_E_FAILURE;
9220 goto error_register_wext;
9221 }
Katya Nigam1fd24402015-02-16 14:52:19 +05309222
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 //Safe to register the hard_start_xmit function again
Katya Nigam1fd24402015-02-16 14:52:19 +05309224 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29))
9225 wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit;
9226 #else
9227 pWlanDev->hard_start_xmit = hdd_hard_start_xmit;
9228 #endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009229
9230 //Set the Connection State to Not Connected
Abhishek Singhf4669da2014-05-26 15:07:49 +05309231 hddLog(VOS_TRACE_LEVEL_INFO,
9232 "%s: Set HDD connState to eConnectionState_NotConnected",
9233 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009234 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
9235
9236 //Set the default operation channel
9237 pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel;
9238
9239 /* Make the default Auth Type as OPEN*/
9240 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9241
9242 if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) )
9243 {
9244 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009245 "hdd_init_tx_rx() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009246 status, status );
9247 goto error_init_txrx;
9248 }
9249
9250 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9251
9252 if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) )
9253 {
9254 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009255 "hdd_wmm_adapter_init() failed with status code %08d [x%08x]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 status, status );
9257 goto error_wmm_init;
9258 }
9259
9260 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9261
9262 return VOS_STATUS_SUCCESS;
9263
9264error_wmm_init:
9265 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9266 hdd_deinit_tx_rx(pAdapter);
9267error_init_txrx:
9268 hdd_UnregisterWext(pWlanDev);
9269error_register_wext:
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009270 if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009271 {
9272 INIT_COMPLETION(pAdapter->session_close_comp_var);
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009273 if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal,
Agrawal Ashish5a3522c2016-03-02 15:08:28 +05309274 pAdapter->sessionId, FALSE, VOS_TRUE,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009275 hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -07009276 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309277 unsigned long rc;
9278
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309280 rc = wait_for_completion_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07009281 &pAdapter->session_close_comp_var,
Jeff Johnsonc6ab5b92013-04-15 17:02:05 -07009282 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309283 if (rc <= 0)
9284 hddLog(VOS_TRACE_LEVEL_ERROR,
9285 FL("Session is not opened within timeout period code %ld"), rc);
Jeff Johnson295189b2012-06-20 16:38:30 -07009286 }
9287}
9288error_sme_open:
9289 return status;
9290}
9291
Jeff Johnson295189b2012-06-20 16:38:30 -07009292void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter )
9293{
9294 hdd_cfg80211_state_t *cfgState;
9295
9296 cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );
9297
9298 if( NULL != cfgState->buf )
9299 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309300 long rc;
Jeff Johnson295189b2012-06-20 16:38:30 -07009301 INIT_COMPLETION(pAdapter->tx_action_cnf_event);
9302 rc = wait_for_completion_interruptible_timeout(
9303 &pAdapter->tx_action_cnf_event,
9304 msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309305 if (rc <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 {
Deepthi Gowri91b3e9c2015-08-25 13:14:58 +05309307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9308 "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld"
9309 , __func__, rc);
9310
9311 // Inform tx status as FAILURE to upper layer and free cfgState->buf
9312 hdd_sendActionCnf( pAdapter, FALSE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 }
9314 }
9315 return;
9316}
Jeff Johnson295189b2012-06-20 16:38:30 -07009317
c_hpothu002231a2015-02-05 14:58:51 +05309318void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
Jeff Johnson295189b2012-06-20 16:38:30 -07009319{
9320 ENTER();
9321 switch ( pAdapter->device_mode )
9322 {
Katya Nigam1fd24402015-02-16 14:52:19 +05309323 case WLAN_HDD_IBSS:
9324 {
9325 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9326 {
9327 hdd_ibss_deinit_tx_rx( pAdapter );
9328 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9329 }
9330 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 case WLAN_HDD_INFRA_STATION:
9332 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009333 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 {
9335 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9336 {
9337 hdd_deinit_tx_rx( pAdapter );
9338 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9339 }
9340
9341 if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9342 {
9343 hdd_wmm_adapter_close( pAdapter );
9344 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9345 }
9346
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 break;
9349 }
9350
9351 case WLAN_HDD_SOFTAP:
9352 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 {
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +05309354
9355 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
9356 {
9357 hdd_wmm_adapter_close( pAdapter );
9358 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
9359 }
9360
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009362
c_hpothu002231a2015-02-05 14:58:51 +05309363 hdd_unregister_hostapd(pAdapter, rtnl_held);
Agrawal Ashisha0584d42016-09-29 13:03:45 +05309364 /* set con_mode to STA only when no SAP concurrency mode */
9365 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
9366 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 break;
9368 }
9369
9370 case WLAN_HDD_MONITOR:
9371 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags))
9373 {
9374 hdd_deinit_tx_rx( pAdapter );
9375 clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
9376 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 break;
9378 }
9379
9380
9381 default:
9382 break;
9383 }
9384
9385 EXIT();
9386}
9387
9388void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held )
9389{
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -08009390 struct net_device *pWlanDev = NULL;
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309391
9392 ENTER();
9393 if (NULL == pAdapter)
9394 {
9395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9396 "%s: HDD adapter is Null", __func__);
9397 return;
9398 }
9399
9400 pWlanDev = pAdapter->dev;
Jeff Johnson295189b2012-06-20 16:38:30 -07009401
Rajeev79dbe4c2013-10-05 11:03:42 +05309402#ifdef FEATURE_WLAN_BATCH_SCAN
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309403 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9404 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Rajeev Kumarf999e582014-01-09 17:33:29 -08009405 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309406 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
9407 )
9408 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009409 if (pAdapter)
Rajeev79dbe4c2013-10-05 11:03:42 +05309410 {
Rajeev Kumarf999e582014-01-09 17:33:29 -08009411 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
9412 {
9413 hdd_deinit_batch_scan(pAdapter);
9414 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309415 }
Rajeev Kumarf999e582014-01-09 17:33:29 -08009416 }
Rajeev79dbe4c2013-10-05 11:03:42 +05309417#endif
9418
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) {
9420 if( rtnl_held )
9421 {
9422 unregister_netdevice(pWlanDev);
9423 }
9424 else
9425 {
9426 unregister_netdev(pWlanDev);
9427 }
9428 // note that the pAdapter is no longer valid at this point
9429 // since the memory has been reclaimed
9430 }
9431
Srinivas, Dasari693dfc52013-12-27 17:29:09 +05309432 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009433}
9434
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009435void hdd_set_pwrparams(hdd_context_t *pHddCtx)
9436{
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309437 VOS_STATUS status;
9438 hdd_adapter_t *pAdapter = NULL;
9439 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009440
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309441 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009442
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309443 /*loop through all adapters.*/
9444 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009445 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309446 pAdapter = pAdapterNode->pAdapter;
9447 if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
9448 && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) )
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009449
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309450 { // we skip this registration for modes other than STA and P2P client modes.
9451 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9452 pAdapterNode = pNext;
9453 continue;
9454 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009455
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309456 //Apply Dynamic DTIM For P2P
9457 //Only if ignoreDynamicDtimInP2pMode is not set in ini
9458 if ((pHddCtx->cfg_ini->enableDynamicDTIM ||
9459 pHddCtx->cfg_ini->enableModulatedDTIM) &&
9460 ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9461 ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) &&
9462 !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) &&
9463 (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) &&
9464 (eConnectionState_Associated ==
9465 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) &&
9466 (pHddCtx->cfg_ini->fIsBmpsEnabled))
9467 {
9468 tSirSetPowerParamsReq powerRequest = { 0 };
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009469
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309470 powerRequest.uIgnoreDTIM = 1;
9471 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
9472
9473 if (pHddCtx->cfg_ini->enableModulatedDTIM)
9474 {
9475 powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM;
9476 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
9477 }
9478 else
9479 {
9480 powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM;
9481 }
9482
9483 /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM
9484 * specified during Enter/Exit BMPS when LCD off*/
9485 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9486 NULL, eANI_BOOLEAN_FALSE);
9487 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9488 NULL, eANI_BOOLEAN_FALSE);
9489
9490 /* switch to the DTIM specified in cfg.ini */
9491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Abhishek Singh1e390cf2015-10-27 13:45:17 +05309492 "Switch to DTIM %d Listen interval %d",
9493 powerRequest.uDTIMPeriod,
9494 powerRequest.uListenInterval);
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309495 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9496 break;
9497
9498 }
9499
9500 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9501 pAdapterNode = pNext;
9502 }
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009503}
9504
9505void hdd_reset_pwrparams(hdd_context_t *pHddCtx)
9506{
9507 /*Switch back to DTIM 1*/
9508 tSirSetPowerParamsReq powerRequest = { 0 };
9509
9510 powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value;
9511 powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value;
Yue Mac24062f2013-05-13 17:01:29 -07009512 powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM;
Tushnim Bhattacharyya3a37def2013-02-24 11:11:15 -08009513
9514 /* Update ignoreDTIM and ListedInterval in CFG with default values */
9515 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM,
9516 NULL, eANI_BOOLEAN_FALSE);
9517 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval,
9518 NULL, eANI_BOOLEAN_FALSE);
9519
9520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9521 "Switch to DTIM%d",powerRequest.uListenInterval);
9522 sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE);
9523
9524}
9525
Jeff Johnson295189b2012-06-20 16:38:30 -07009526VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx)
9527{
9528 VOS_STATUS status = VOS_STATUS_SUCCESS;
Sushant Kaushik4928e542014-12-29 15:25:54 +05309529 if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx))
9530 {
9531 hddLog( LOGE, FL("Wlan Unload in progress"));
9532 return VOS_STATUS_E_PERM;
9533 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309534
9535 if (wlan_hdd_check_monitor_state(pHddCtx)) {
9536 hddLog(LOG1, FL("Monitor mode is started, cannot enable BMPS"));
9537 return VOS_STATUS_SUCCESS;
9538 }
9539
Jeff Johnson295189b2012-06-20 16:38:30 -07009540 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9541 {
9542 sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9543 }
9544
9545 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9546 {
9547 sme_StartAutoBmpsTimer(pHddCtx->hHal);
9548 }
9549
9550 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9551 {
9552 sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9553 }
9554
9555 return status;
9556}
9557
9558VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type)
9559{
9560 hdd_adapter_t *pAdapter = NULL;
9561 eHalStatus halStatus;
9562 VOS_STATUS status = VOS_STATUS_E_INVAL;
9563 v_BOOL_t disableBmps = FALSE;
9564 v_BOOL_t disableImps = FALSE;
9565
9566 switch(session_type)
9567 {
9568 case WLAN_HDD_INFRA_STATION:
9569 case WLAN_HDD_SOFTAP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 case WLAN_HDD_P2P_CLIENT:
9571 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 //Exit BMPS -> Is Sta/P2P Client is already connected
9573 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
9574 if((NULL != pAdapter)&&
9575 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9576 {
9577 disableBmps = TRUE;
9578 }
9579
9580 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT);
9581 if((NULL != pAdapter)&&
9582 hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
9583 {
9584 disableBmps = TRUE;
9585 }
9586
9587 //Exit both Bmps and Imps incase of Go/SAP Mode
9588 if((WLAN_HDD_SOFTAP == session_type) ||
9589 (WLAN_HDD_P2P_GO == session_type))
9590 {
9591 disableBmps = TRUE;
9592 disableImps = TRUE;
9593 }
9594
9595 if(TRUE == disableImps)
9596 {
9597 if (pHddCtx->cfg_ini->fIsImpsEnabled)
9598 {
9599 sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
9600 }
9601 }
9602
9603 if(TRUE == disableBmps)
9604 {
9605 if(pHddCtx->cfg_ini->fIsBmpsEnabled)
9606 {
9607 halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
9608
9609 if(eHAL_STATUS_SUCCESS != halStatus)
9610 {
9611 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009612 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 VOS_ASSERT(0);
9614 return status;
9615 }
9616 }
9617
9618 if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled)
9619 {
9620 halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal);
9621
9622 if(eHAL_STATUS_SUCCESS != halStatus)
9623 {
9624 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009625 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009626 VOS_ASSERT(0);
9627 return status;
9628 }
9629 }
9630 }
9631
9632 if((TRUE == disableBmps) ||
9633 (TRUE == disableImps))
9634 {
9635 /* Now, get the chip into Full Power now */
9636 INIT_COMPLETION(pHddCtx->full_pwr_comp_var);
9637 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk,
9638 pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD);
9639
9640 if(halStatus != eHAL_STATUS_SUCCESS)
9641 {
9642 if(halStatus == eHAL_STATUS_PMC_PENDING)
9643 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309644 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 //Block on a completion variable. Can't wait forever though
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309646 ret = wait_for_completion_interruptible_timeout(
9647 &pHddCtx->full_pwr_comp_var,
9648 msecs_to_jiffies(1000));
9649 if (ret <= 0)
9650 {
9651 hddLog(VOS_TRACE_LEVEL_ERROR,
9652 "%s: wait on full_pwr_comp_var failed %ld",
9653 __func__, ret);
9654 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 }
9656 else
9657 {
9658 status = VOS_STATUS_E_FAILURE;
Arif Hussain6d2a3322013-11-17 19:50:10 -08009659 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 VOS_ASSERT(0);
9661 return status;
9662 }
9663 }
9664
9665 status = VOS_STATUS_SUCCESS;
9666 }
9667
9668 break;
9669 }
9670 return status;
9671}
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309672
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309673void hdd_mon_post_msg_cb(void *context)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309674{
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309675 struct hdd_request *request;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309676
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309677 request = hdd_request_get(context);
9678 if (!request) {
9679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
9680 return;
9681 }
9682
9683 hdd_request_complete(request);
9684 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +05309685}
9686
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +05309687
Katya Nigame7b69a82015-04-28 15:24:06 +05309688void hdd_init_mon_mode (hdd_adapter_t *pAdapter)
9689 {
9690 hdd_mon_ctx_t *pMonCtx = NULL;
Katya Nigame7b69a82015-04-28 15:24:06 +05309691
Rajeev Kumar Sirasanagandla54447612018-03-06 15:49:56 +05309692 spin_lock_init(&pAdapter->sta_hash_lock);
9693 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
9694
9695 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
Katya Nigame7b69a82015-04-28 15:24:06 +05309696 pMonCtx->state = 0;
9697 pMonCtx->ChannelNo = 1;
9698 pMonCtx->ChannelBW = 20;
Katya Nigamd7d3a1f2015-06-11 14:04:24 +05309699 pMonCtx->crcCheckEnabled = 1;
9700 pMonCtx->typeSubtypeBitmap = 0xFFFF00000000;
9701 pMonCtx->is80211to803ConReq = 1;
Katya Nigame7b69a82015-04-28 15:24:06 +05309702 pMonCtx->numOfMacFilters = 0;
9703 }
9704
Jeff Johnson295189b2012-06-20 16:38:30 -07009705
9706hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type,
Jeff Johnsoneed415b2013-01-18 16:11:20 -08009707 const char *iface_name, tSirMacAddr macAddr,
Jeff Johnson295189b2012-06-20 16:38:30 -07009708 tANI_U8 rtnl_held )
9709{
9710 hdd_adapter_t *pAdapter = NULL;
9711 hdd_adapter_list_node_t *pHddAdapterNode = NULL;
9712 VOS_STATUS status = VOS_STATUS_E_FAILURE;
9713 VOS_STATUS exitbmpsStatus;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309714 v_CONTEXT_t pVosContext = NULL;
9715
9716 /* No need to check for NULL, reaching this step
9717 * means vos context is initialized
9718 */
9719 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009720
Arif Hussain6d2a3322013-11-17 19:50:10 -08009721 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009722
Nirav Shah436658f2014-02-28 17:05:45 +05309723 if(macAddr == NULL)
9724 {
9725 /* Not received valid macAddr */
9726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9727 "%s:Unable to add virtual intf: Not able to get"
9728 "valid mac address",__func__);
9729 return NULL;
9730 }
9731
Jeff Johnson295189b2012-06-20 16:38:30 -07009732 //Disable BMPS incase of Concurrency
9733 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type);
9734
9735 if(VOS_STATUS_E_FAILURE == exitbmpsStatus)
9736 {
9737 //Fail to Exit BMPS
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309738 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 VOS_ASSERT(0);
9740 return NULL;
9741 }
9742
9743 switch(session_type)
9744 {
9745 case WLAN_HDD_INFRA_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -07009747 case WLAN_HDD_P2P_DEVICE:
Jeff Johnson295189b2012-06-20 16:38:30 -07009748 {
9749 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9750
9751 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309752 {
9753 hddLog(VOS_TRACE_LEVEL_FATAL,
9754 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009755 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309756 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009757
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309758#ifdef FEATURE_WLAN_TDLS
9759 /* A Mutex Lock is introduced while changing/initializing the mode to
9760 * protect the concurrent access for the Adapters by TDLS module.
9761 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309762 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309763#endif
9764
Jeff Johnsone7245742012-09-05 17:12:55 -07009765 pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ?
9766 NL80211_IFTYPE_P2P_CLIENT:
9767 NL80211_IFTYPE_STATION;
Jeff Johnson295189b2012-06-20 16:38:30 -07009768
Jeff Johnson295189b2012-06-20 16:38:30 -07009769 pAdapter->device_mode = session_type;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309770#ifdef FEATURE_WLAN_TDLS
9771 mutex_unlock(&pHddCtx->tdls_lock);
9772#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309773
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309774 hdd_initialize_adapter_common(pAdapter);
Sunil Dutt66485cb2013-12-19 19:05:03 +05309775 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 if( VOS_STATUS_SUCCESS != status )
9777 goto err_free_netdev;
9778
9779 status = hdd_register_interface( pAdapter, rtnl_held );
9780 if( VOS_STATUS_SUCCESS != status )
9781 {
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309782#ifdef FEATURE_WLAN_TDLS
9783 mutex_lock(&pHddCtx->tdls_lock);
9784#endif
c_hpothu002231a2015-02-05 14:58:51 +05309785 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +05309786#ifdef FEATURE_WLAN_TDLS
9787 mutex_unlock(&pHddCtx->tdls_lock);
9788#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 goto err_free_netdev;
9790 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309791
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309792 // Workqueue which gets scheduled in IPv4 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309793 vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue);
Vinay Krishna Eranna4d055d42013-12-17 17:02:01 +05309794
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309795#ifdef WLAN_NS_OFFLOAD
9796 // Workqueue which gets scheduled in IPv6 notification callback.
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309797 vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +05309798#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309800 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 netif_tx_disable(pAdapter->dev);
9802 //netif_tx_disable(pWlanDev);
9803 netif_carrier_off(pAdapter->dev);
9804
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309805 if (WLAN_HDD_P2P_CLIENT == session_type ||
9806 WLAN_HDD_P2P_DEVICE == session_type)
9807 {
9808 /* Initialize the work queue to defer the
9809 * back to back RoC request */
Anand N Sunkaddc63c792015-06-03 14:33:24 +05309810 vos_init_delayed_work(&pAdapter->roc_work,
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309811 hdd_p2p_roc_work_queue);
9812 }
9813
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 break;
9815 }
9816
Jeff Johnson295189b2012-06-20 16:38:30 -07009817 case WLAN_HDD_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009818 case WLAN_HDD_SOFTAP:
9819 {
9820 pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name );
9821 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309822 {
9823 hddLog(VOS_TRACE_LEVEL_FATAL,
9824 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309826 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009827
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ?
9829 NL80211_IFTYPE_AP:
9830 NL80211_IFTYPE_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009831 pAdapter->device_mode = session_type;
9832
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309833 hdd_initialize_adapter_common(pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +05309834 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -07009835 if( VOS_STATUS_SUCCESS != status )
9836 goto err_free_netdev;
9837
Nirav Shah7e3c8132015-06-22 23:51:42 +05309838 status = hdd_sta_id_hash_attach(pAdapter);
9839 if (VOS_STATUS_SUCCESS != status)
9840 {
9841 hddLog(VOS_TRACE_LEVEL_FATAL,
9842 FL("failed to attach hash for session %d"), session_type);
9843 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
9844 goto err_free_netdev;
9845 }
9846
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 status = hdd_register_hostapd( pAdapter, rtnl_held );
9848 if( VOS_STATUS_SUCCESS != status )
9849 {
c_hpothu002231a2015-02-05 14:58:51 +05309850 hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held);
Jeff Johnson295189b2012-06-20 16:38:30 -07009851 goto err_free_netdev;
9852 }
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309853 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009854 netif_tx_disable(pAdapter->dev);
9855 netif_carrier_off(pAdapter->dev);
9856
9857 hdd_set_conparam( 1 );
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309858
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +05309859 // Workqueue which gets scheduled in IPv4 notification callback.
9860 vos_init_work(&pAdapter->ipv4NotifierWorkQueue,
9861 hdd_ipv4_notifier_work_queue);
9862
9863#ifdef WLAN_NS_OFFLOAD
9864 // Workqueue which gets scheduled in IPv6 notification callback.
9865 vos_init_work(&pAdapter->ipv6NotifierWorkQueue,
9866 hdd_ipv6_notifier_work_queue);
9867#endif
9868
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +05309869 if (WLAN_HDD_P2P_GO == session_type)
9870 {
9871 /* Initialize the work queue to
9872 * defer the back to back RoC request */
9873 INIT_DELAYED_WORK(&pAdapter->roc_work,
9874 hdd_p2p_roc_work_queue);
9875 }
Bhargav Shahd0715912015-10-01 18:17:37 +05309876
Jeff Johnson295189b2012-06-20 16:38:30 -07009877 break;
9878 }
9879 case WLAN_HDD_MONITOR:
9880 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9882 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309883 {
9884 hddLog(VOS_TRACE_LEVEL_FATAL,
9885 FL("failed to allocate adapter for session %d"), session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009886 return NULL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309887 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009888
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309889 pAdapter->device_mode = session_type;
9890 pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
9891
Katya Nigame7b69a82015-04-28 15:24:06 +05309892 // Register wireless extensions
9893 if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev)))
9894 {
9895 hddLog(VOS_TRACE_LEVEL_FATAL,
9896 "hdd_register_wext() failed with status code %08d [x%08x]",
9897 status, status );
9898 status = VOS_STATUS_E_FAILURE;
9899 }
9900
Jeff Johnson295189b2012-06-20 16:38:30 -07009901#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)
9902 pAdapter->dev->netdev_ops = &wlan_mon_drv_ops;
9903#else
9904 pAdapter->dev->open = hdd_mon_open;
9905 pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit;
Katya Nigame7b69a82015-04-28 15:24:06 +05309906 pAdapter->dev->stop = hdd_mon_stop;
9907 pAdapter->dev->do_ioctl = hdd_mon_ioctl;
Jeff Johnson295189b2012-06-20 16:38:30 -07009908#endif
Katya Nigame7b69a82015-04-28 15:24:06 +05309909 hdd_init_mon_mode( pAdapter );
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309910 hdd_initialize_adapter_common(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 hdd_init_tx_rx( pAdapter );
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309912
9913 if (VOS_MONITOR_MODE != hdd_get_conparam())
9914 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
9915
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309917 status = hdd_register_interface( pAdapter, rtnl_held );
Katya Nigame7b69a82015-04-28 15:24:06 +05309918 //Stop the Interface TX queue.
9919 netif_tx_disable(pAdapter->dev);
9920 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 }
9922 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 case WLAN_HDD_FTM:
9924 {
9925 pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name );
9926
9927 if( NULL == pAdapter )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309928 {
9929 hddLog(VOS_TRACE_LEVEL_FATAL,
9930 FL("failed to allocate adapter for session %d"), session_type);
9931 return NULL;
9932 }
9933
Jeff Johnson295189b2012-06-20 16:38:30 -07009934 /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning
9935 * message while loading driver in FTM mode. */
9936 pAdapter->wdev.iftype = NL80211_IFTYPE_STATION;
9937 pAdapter->device_mode = session_type;
9938 status = hdd_register_interface( pAdapter, rtnl_held );
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309939
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309940 hdd_initialize_adapter_common(pAdapter);
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309941 hdd_init_tx_rx( pAdapter );
9942
9943 //Stop the Interface TX queue.
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +05309944 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Madan Mohan Koyyalamudif89ac9f2013-09-19 16:58:12 +05309945 netif_tx_disable(pAdapter->dev);
9946 netif_carrier_off(pAdapter->dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07009947 }
9948 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009949 default:
9950 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309951 hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d",
9952 __func__, session_type);
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 VOS_ASSERT(0);
9954 return NULL;
9955 }
9956 }
9957
Jeff Johnson295189b2012-06-20 16:38:30 -07009958 if( VOS_STATUS_SUCCESS == status )
9959 {
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +05309960 //Add it to the hdd's session list.
Jeff Johnson295189b2012-06-20 16:38:30 -07009961 pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) );
9962 if( NULL == pHddAdapterNode )
9963 {
9964 status = VOS_STATUS_E_NOMEM;
9965 }
9966 else
9967 {
9968 pHddAdapterNode->pAdapter = pAdapter;
9969 status = hdd_add_adapter_back ( pHddCtx,
9970 pHddAdapterNode );
9971 }
9972 }
9973
9974 if( VOS_STATUS_SUCCESS != status )
9975 {
9976 if( NULL != pAdapter )
9977 {
9978 hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held );
9979 pAdapter = NULL;
9980 }
9981 if( NULL != pHddAdapterNode )
9982 {
9983 vos_mem_free( pHddAdapterNode );
9984 }
9985
9986 goto resume_bmps;
9987 }
9988
9989 if(VOS_STATUS_SUCCESS == status)
9990 {
9991 wlan_hdd_set_concurrency_mode(pHddCtx, session_type);
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07009992 //Initialize the WoWL service
9993 if(!hdd_init_wowl(pAdapter))
9994 {
9995 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__);
9996 goto err_free_netdev;
9997 }
Manjeet Singh3ed79242017-01-11 19:04:32 +05309998 //Initialize the TSF capture data
9999 wlan_hdd_tsf_init(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010000 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010001 return pAdapter;
10002
10003err_free_netdev:
10004 free_netdev(pAdapter->dev);
10005 wlan_hdd_release_intf_addr( pHddCtx,
10006 pAdapter->macAddressCurrent.bytes );
10007
10008resume_bmps:
10009 //If bmps disabled enable it
10010 if(VOS_STATUS_SUCCESS == exitbmpsStatus)
10011 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010012 if (pHddCtx->hdd_wlan_suspended)
10013 {
10014 hdd_set_pwrparams(pHddCtx);
10015 }
10016 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 }
10018 return NULL;
10019}
10020
10021VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10022 tANI_U8 rtnl_held )
10023{
10024 hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext;
10025 VOS_STATUS status;
10026
10027 status = hdd_get_front_adapter ( pHddCtx, &pCurrent );
10028 if( VOS_STATUS_SUCCESS != status )
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010029 {
10030 hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d",
10031 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010033 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010034
10035 while ( pCurrent->pAdapter != pAdapter )
10036 {
10037 status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext );
10038 if( VOS_STATUS_SUCCESS != status )
10039 break;
10040
10041 pCurrent = pNext;
10042 }
10043 pAdapterNode = pCurrent;
10044 if( VOS_STATUS_SUCCESS == status )
10045 {
10046 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10047 hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010048
10049#ifdef FEATURE_WLAN_TDLS
10050
10051 /* A Mutex Lock is introduced while changing/initializing the mode to
10052 * protect the concurrent access for the Adapters by TDLS module.
10053 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010054 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010055#endif
10056
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 hdd_remove_adapter( pHddCtx, pAdapterNode );
10058 vos_mem_free( pAdapterNode );
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080010059 pAdapterNode = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010060
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010061#ifdef FEATURE_WLAN_TDLS
10062 mutex_unlock(&pHddCtx->tdls_lock);
10063#endif
10064
Jeff Johnson295189b2012-06-20 16:38:30 -070010065
10066 /* If there is a single session of STA/P2P client, re-enable BMPS */
Agarwal Ashish51325b52014-06-16 16:50:49 +053010067 if ((!vos_concurrent_open_sessions_running()) &&
10068 ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) ||
10069 (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1)))
Jeff Johnson295189b2012-06-20 16:38:30 -070010070 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010071 if (pHddCtx->hdd_wlan_suspended)
10072 {
10073 hdd_set_pwrparams(pHddCtx);
10074 }
10075 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 }
10077
10078 return VOS_STATUS_SUCCESS;
10079 }
10080
10081 return VOS_STATUS_E_FAILURE;
10082}
10083
10084VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx )
10085{
10086 hdd_adapter_list_node_t *pHddAdapterNode;
10087 VOS_STATUS status;
10088
10089 ENTER();
10090
10091 do
10092 {
10093 status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode );
10094 if( pHddAdapterNode && VOS_STATUS_SUCCESS == status )
10095 {
10096 hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE );
10097 vos_mem_free( pHddAdapterNode );
10098 }
10099 }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status );
10100
10101 EXIT();
10102
10103 return VOS_STATUS_SUCCESS;
10104}
10105
10106void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter)
10107{
10108 v_U8_t addIE[1] = {0};
10109
10110 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10111 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL,
10112 eANI_BOOLEAN_FALSE) )
10113 {
10114 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010115 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010116 }
10117
10118 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10119 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10120 eANI_BOOLEAN_FALSE) )
10121 {
10122 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010123 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 }
10125
10126 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10127 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10128 eANI_BOOLEAN_FALSE) )
10129 {
10130 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010131 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 }
10133}
10134
Anurag Chouhan83026002016-12-13 22:46:21 +053010135VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter)
10136{
10137#ifdef DHCP_SERVER_OFFLOAD
10138 vos_event_destroy(&adapter->dhcp_status.vos_event);
10139#endif
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010140#ifdef MDNS_OFFLOAD
10141 vos_event_destroy(&adapter->mdns_status.vos_event);
10142#endif
Anurag Chouhan83026002016-12-13 22:46:21 +053010143 return VOS_STATUS_SUCCESS;
10144}
10145
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010146int wlan_hdd_stop_mon(hdd_context_t *hdd_ctx, bool wait)
10147{
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010148 hdd_adapter_t *adapter;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010149 hdd_mon_ctx_t *mon_ctx;
10150 void (*func_ptr)(void *context) = NULL;
10151 int ret = 0;
10152 void *cookie = NULL;
10153 struct hdd_request *request;
10154 static const struct hdd_request_params params = {
10155 .priv_size = 0,
10156 .timeout_ms = MON_MODE_MSG_TIMEOUT,
10157 };
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010158
10159 adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10160 if (!adapter) {
10161 hddLog(LOGE, FL("Invalid STA + MON mode"));
10162 return -EINVAL;
10163 }
10164
10165 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(adapter);
10166 if (!mon_ctx)
10167 return 0;
10168
10169 if (mon_ctx->state != MON_MODE_START)
10170 return 0;
10171
10172 mon_ctx->state = MON_MODE_STOP;
10173 if (wait) {
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010174 func_ptr = hdd_mon_post_msg_cb;
10175 request = hdd_request_alloc(&params);
10176 if (!request) {
10177 hddLog(VOS_TRACE_LEVEL_ERROR,
10178 FL("Request allocation failure"));
10179 return -ENOMEM;
10180 }
10181 cookie = hdd_request_cookie(request);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010182 }
10183
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010184 /*
10185 * If func_ptr is NULL, on receiving WDI_MON_START_RSP or
10186 * WDI_MON_STOP_RSP hdd_mon_post_msg_cb() won't be invoked
10187 * and so uninitialized cookie won't be accessed.
10188 */
10189 if (VOS_STATUS_SUCCESS != wlan_hdd_mon_postMsg(cookie,
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010190 mon_ctx,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010191 func_ptr)) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010192 hddLog(LOGE, FL("failed to stop MON MODE"));
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010193 ret = -EINVAL;
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010194 }
10195
10196 if (!wait)
10197 goto bmps_roaming;
10198
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010199 if (!ret)
10200 ret = hdd_request_wait_for_response(request);
10201 hdd_request_put(request);
10202 if (ret) {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010203 hddLog(LOGE,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053010204 FL("timeout on stop monitor mode completion %d"), ret);
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010205 return -EINVAL;
10206 }
10207
10208bmps_roaming:
10209 hddLog(LOG1, FL("Enable BMPS"));
10210 hdd_enable_bmps_imps(hdd_ctx);
10211 hdd_restore_roaming(hdd_ctx);
10212
10213 return 0;
10214}
10215
10216bool wlan_hdd_check_monitor_state(hdd_context_t *hdd_ctx)
10217{
10218 hdd_adapter_t *mon_adapter;
10219 hdd_mon_ctx_t *mon_ctx;
10220
10221 if (hdd_ctx->concurrency_mode != VOS_STA_MON)
10222 return false;
10223
10224 mon_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_MONITOR);
10225 if (!mon_adapter) {
10226 hddLog(LOGE, FL("Invalid concurrency mode"));
10227 return false;
10228 }
10229
10230 mon_ctx = WLAN_HDD_GET_MONITOR_CTX_PTR(mon_adapter);
10231 if (mon_ctx->state == MON_MODE_START)
10232 return true;
10233
10234 return false;
10235}
10236
10237int wlan_hdd_check_and_stop_mon(hdd_adapter_t *sta_adapter, bool wait)
10238{
10239 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(sta_adapter);
10240
10241 if ((sta_adapter->device_mode != WLAN_HDD_INFRA_STATION) ||
10242 !wlan_hdd_check_monitor_state(hdd_ctx))
10243 return 0;
10244
10245 if (wlan_hdd_stop_mon(hdd_ctx, wait))
10246 return -EINVAL;
10247
10248 return 0;
10249}
10250
10251void hdd_disable_roaming(hdd_context_t *hdd_ctx)
10252{
10253 if (!hdd_ctx)
10254 return;
10255
10256 if (!hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled) {
10257 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10258 return;
10259 }
10260
10261 hddLog(LOG1, FL("Disable driver and firmware roaming"));
10262
10263 hdd_ctx->roaming_ini_original =
10264 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled;
10265
10266 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10267 CFG_LFR_FEATURE_ENABLED_MIN;
10268
10269 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10270 CFG_LFR_FEATURE_ENABLED_MIN);
10271}
10272
10273void hdd_restore_roaming(hdd_context_t *hdd_ctx)
10274{
10275 if (!hdd_ctx->roaming_ini_original)
10276 return;
10277
10278 hddLog(LOG1, FL("Enable driver and firmware roaming"));
10279
10280 hdd_ctx->cfg_ini->isFastRoamIniFeatureEnabled =
10281 CFG_LFR_FEATURE_ENABLED_MAX;
10282
10283 hdd_ctx->roaming_ini_original = CFG_LFR_FEATURE_ENABLED_MIN;
10284
10285 sme_UpdateIsFastRoamIniFeatureEnabled(hdd_ctx->hHal,
10286 CFG_LFR_FEATURE_ENABLED_MAX);
10287}
Anurag Chouhan83026002016-12-13 22:46:21 +053010288
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010289VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter,
10290 const v_BOOL_t bCloseSession )
Jeff Johnson295189b2012-06-20 16:38:30 -070010291{
10292 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
10293 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010294 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010295 union iwreq_data wrqu;
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010296 v_U8_t retry = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010297 long ret;
Nirav Shah7e3c8132015-06-22 23:51:42 +053010298 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010299
Anand N Sunkad26d71b92014-12-24 18:08:22 +053010300 if (pHddCtx->isLogpInProgress) {
10301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10302 "%s:LOGP in Progress. Ignore!!!",__func__);
10303 return VOS_STATUS_E_FAILURE;
10304 }
10305
Jeff Johnson295189b2012-06-20 16:38:30 -070010306 ENTER();
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010307
Kaushik, Sushant4975a572014-10-21 16:07:48 +053010308 pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -070010309 switch(pAdapter->device_mode)
10310 {
Nirav Shah0cf4d892015-11-05 16:27:27 +053010311 case WLAN_HDD_IBSS:
10312 if ( VOS_TRUE == bCloseSession )
10313 {
10314 status = hdd_sta_id_hash_detach(pAdapter);
10315 if (status != VOS_STATUS_SUCCESS)
10316 hddLog(VOS_TRACE_LEVEL_ERROR,
10317 FL("sta id hash detach failed"));
10318 }
10319
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 case WLAN_HDD_INFRA_STATION:
10321 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070010322 case WLAN_HDD_P2P_DEVICE:
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010323 {
10324 hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagare4d05d42015-07-02 16:17:20 +053010325#ifdef FEATURE_WLAN_TDLS
10326 mutex_lock(&pHddCtx->tdls_lock);
10327 wlan_hdd_tdls_exit(pAdapter, TRUE);
10328 mutex_unlock(&pHddCtx->tdls_lock);
10329#endif
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010330 if( hdd_connIsConnected(pstation) ||
10331 (pstation->conn_info.connState == eConnectionState_Connecting) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010332 {
Abhishek Singhe21a5212017-06-09 09:42:58 +053010333 /*
10334 * Indicate sme of disconnect so that in progress connection
10335 * or preauth can be aborted.
10336 */
10337 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10338 pAdapter->sessionId);
Abhishek Singh99f17b82017-02-06 16:57:56 +053010339 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010340 if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS)
10341 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10342 pAdapter->sessionId,
10343 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10344 else
10345 halStatus = sme_RoamDisconnect(pHddCtx->hHal,
10346 pAdapter->sessionId,
10347 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh7b52ed52016-02-11 17:45:54 +053010348 /* Success implies disconnect command got queued up successfully
10349 * Or cmd not queued as scan for SSID is in progress
10350 */
10351 if((eHAL_STATUS_SUCCESS == halStatus) ||
10352 (eHAL_STATUS_CMD_NOT_QUEUED == halStatus))
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010354 ret = wait_for_completion_interruptible_timeout(
10355 &pAdapter->disconnect_comp_var,
10356 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singh7b52ed52016-02-11 17:45:54 +053010357 if (ret <= 0 &&
10358 (eHAL_STATUS_CMD_NOT_QUEUED != halStatus))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010359 {
10360 hddLog(VOS_TRACE_LEVEL_ERROR,
10361 "%s: wait on disconnect_comp_var failed %ld",
10362 __func__, ret);
10363 }
10364 }
10365 else
10366 {
10367 hddLog(LOGE, "%s: failed to post disconnect event to SME",
10368 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 }
10370 memset(&wrqu, '\0', sizeof(wrqu));
10371 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
10372 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
10373 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
10374 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010375 else if(pstation->conn_info.connState ==
10376 eConnectionState_Disconnecting)
10377 {
10378 ret = wait_for_completion_interruptible_timeout(
10379 &pAdapter->disconnect_comp_var,
10380 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10381 if (ret <= 0)
10382 {
10383 hddLog(VOS_TRACE_LEVEL_ERROR,
10384 FL("wait on disconnect_comp_var failed %ld"), ret);
10385 }
10386 }
Sachin Ahuja27dd2402016-08-01 20:30:31 +053010387 if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending)
Jeff Johnson295189b2012-06-20 16:38:30 -070010388 {
Mahesh A Saptasagar0b61dcc2016-02-15 14:23:38 +053010389 wlan_hdd_scan_abort(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010390 }
Abhishek Singh3ac179b2015-09-21 10:01:34 +053010391 if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) &&
10392 (pAdapter->device_mode != WLAN_HDD_IBSS))
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010393 {
10394 while (pAdapter->is_roc_inprogress)
10395 {
10396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10397 "%s: ROC in progress for session %d!!!",
10398 __func__, pAdapter->sessionId);
10399 // waiting for ROC to expire
10400 msleep(500);
10401 /* In GO present case , if retry exceeds 3,
10402 it means something went wrong. */
10403 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION )
10404 {
10405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10406 "%s: ROC completion is not received.!!!", __func__);
Deepthi Gowri70498252015-01-20 15:56:45 +053010407 if (eHAL_STATUS_SUCCESS !=
10408 sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter),
10409 pAdapter->sessionId ))
10410 {
10411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10412 FL("Failed to Cancel Remain on Channel"));
10413 }
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010414 wait_for_completion_interruptible_timeout(
10415 &pAdapter->cancel_rem_on_chan_var,
10416 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10417 break;
10418 }
10419 }
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010420 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010421 }
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010422#ifdef WLAN_NS_OFFLOAD
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010423 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
Vinay Krishna Erannad5b2be22013-12-01 17:00:15 +053010424#endif
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010425
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010426 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053010427
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010428 /* It is possible that the caller of this function does not
10429 * wish to close the session
10430 */
10431 if (VOS_TRUE == bCloseSession &&
10432 test_bit(SME_SESSION_OPENED, &pAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010433 {
10434 INIT_COMPLETION(pAdapter->session_close_comp_var);
10435 if (eHAL_STATUS_SUCCESS ==
Agrawal Ashish5a3522c2016-03-02 15:08:28 +053010436 sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE,
10437 VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010439 unsigned long ret;
10440
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 //Block on a completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010442 ret = wait_for_completion_timeout(
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010443 &pAdapter->session_close_comp_var,
10444 msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010445 if ( 0 >= ret)
10446 {
10447 hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld",
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010448 __func__, ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010449 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 }
10451 }
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010452 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010453 break;
10454
10455 case WLAN_HDD_SOFTAP:
10456 case WLAN_HDD_P2P_GO:
Nirav Shah0cf4d892015-11-05 16:27:27 +053010457 if ( VOS_TRUE == bCloseSession )
10458 {
10459 status = hdd_sta_id_hash_detach(pAdapter);
10460 if (status != VOS_STATUS_SUCCESS)
10461 hddLog(VOS_TRACE_LEVEL_ERROR,
10462 FL("sta id hash detach failed"));
10463 }
10464
Jeff Johnson295189b2012-06-20 16:38:30 -070010465 //Any softap specific cleanup here...
Anurag Chouhan83026002016-12-13 22:46:21 +053010466 hdd_cleanup_ap_events(pAdapter);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010467 if (pAdapter->device_mode == WLAN_HDD_P2P_GO) {
10468 while (pAdapter->is_roc_inprogress) {
10469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10470 "%s: ROC in progress for session %d!!!",
10471 __func__, pAdapter->sessionId);
10472 msleep(500);
10473 if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) {
10474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10475 "%s: ROC completion is not received.!!!", __func__);
10476 WLANSAP_CancelRemainOnChannel(
10477 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
10478 wait_for_completion_interruptible_timeout(
10479 &pAdapter->cancel_rem_on_chan_var,
10480 msecs_to_jiffies(WAIT_CANCEL_REM_CHAN));
10481 break;
10482 }
10483 }
Ganesh Kondabattinibabfb492014-12-17 20:25:29 +053010484
Anand N Sunkaddc63c792015-06-03 14:33:24 +053010485 vos_flush_delayed_work(&pAdapter->roc_work);
Kaushik, Sushant7005e372014-04-08 11:36:54 +053010486 }
Agrawal Ashish17ef5082016-10-17 18:33:21 +053010487#ifdef SAP_AUTH_OFFLOAD
10488 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
10489 hdd_set_sap_auth_offload(pAdapter, FALSE);
10490#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 mutex_lock(&pHddCtx->sap_lock);
10492 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10493 {
10494 VOS_STATUS status;
10495 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10496
10497 //Stop Bss.
10498 status = WLANSAP_StopBss(pHddCtx->pvosContext);
10499 if (VOS_IS_STATUS_SUCCESS(status))
10500 {
10501 hdd_hostapd_state_t *pHostapdState =
10502 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10503
10504 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10505
10506 if (!VOS_IS_STATUS_SUCCESS(status))
10507 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010508 hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d",
10509 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 }
10511 }
10512 else
10513 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010514 hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 }
10516 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010517 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010518
10519 if (eHAL_STATUS_FAILURE ==
10520 ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
10521 0, NULL, eANI_BOOLEAN_FALSE))
10522 {
10523 hddLog(LOGE,
10524 "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070010525 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 }
10527
10528 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
10529 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10530 eANI_BOOLEAN_FALSE) )
10531 {
10532 hddLog(LOGE,
10533 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
10534 }
10535
10536 // Reset WNI_CFG_PROBE_RSP Flags
10537 wlan_hdd_reset_prob_rspies(pAdapter);
10538 kfree(pAdapter->sessionCtx.ap.beacon);
10539 pAdapter->sessionCtx.ap.beacon = NULL;
10540 }
10541 mutex_unlock(&pHddCtx->sap_lock);
Hanumanth Reddy Pothulab4537b82018-03-02 12:20:38 +053010542
10543#ifdef WLAN_NS_OFFLOAD
10544 vos_flush_work(&pAdapter->ipv6NotifierWorkQueue);
10545#endif
10546 vos_flush_work(&pAdapter->ipv4NotifierWorkQueue);
10547
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010549
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 case WLAN_HDD_MONITOR:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053010551 if (VOS_MONITOR_MODE != hdd_get_conparam())
10552 wlan_hdd_stop_mon(pHddCtx, true);
10553 break;
Sameer Thalappilbee426e2013-10-30 10:30:30 -070010554
Jeff Johnson295189b2012-06-20 16:38:30 -070010555 default:
10556 break;
10557 }
10558
10559 EXIT();
10560 return VOS_STATUS_SUCCESS;
10561}
10562
Kapil Gupta137ef892016-12-13 19:38:00 +053010563/**
10564 * wlan_hdd_restart_sap() - to restart SAP in driver internally
10565 * @ap_adapter: - Pointer to SAP hdd_adapter_t structure
10566 *
10567 * wlan_hdd_restart_sap first delete SAP and do cleanup.
10568 * After that WLANSAP_StartBss start re-start process of SAP.
10569 *
10570 * Return: None
10571 */
10572static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter)
10573{
10574 hdd_ap_ctx_t *pHddApCtx;
10575 hdd_hostapd_state_t *pHostapdState;
10576 VOS_STATUS vos_status;
10577 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010578#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010579 struct station_del_parameters delStaParams;
10580#endif
10581 tsap_Config_t *pConfig;
10582
10583 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
10584 pConfig = &pHddApCtx->sapConfig;
10585
10586 mutex_lock(&pHddCtx->sap_lock);
10587 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010588#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053010589 delStaParams.mac = NULL;
10590 delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
10591 delStaParams.reason_code = eCsrForcedDeauthSta;
10592 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10593 &delStaParams);
10594#else
10595 wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev,
10596 NULL);
10597#endif
10598 hdd_cleanup_actionframe(pHddCtx, ap_adapter);
10599
10600 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
10601 vos_event_reset(&pHostapdState->vosEvent);
10602
10603 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10604 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10605 10000);
10606 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10607 hddLog(LOGE, FL("SAP Stop Failed"));
10608 goto end;
10609 }
10610 }
10611 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10612 wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode);
10613 hddLog(LOG1, FL("SAP Stop Success"));
10614
10615 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
10616 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10617 goto end;
10618 }
10619
10620 if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB,
10621 pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) {
10622 hddLog(LOGE, FL("SAP Start Bss fail"));
10623 goto end;
10624 }
10625
10626 hddLog(LOG1, FL("Waiting for SAP to start"));
10627 vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
10628 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10629 hddLog(LOGE, FL("SAP Start failed"));
10630 goto end;
10631 }
10632 hddLog(LOG1, FL("SAP Start Success"));
10633 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
10634 wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode);
10635 pHostapdState->bCommit = TRUE;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010636 if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) {
10637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!"));
10638 vos_event_reset(&pHostapdState->vosEvent);
10639 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10640 vos_status = vos_wait_single_event(&pHostapdState->vosEvent,
10641 10000);
10642 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
10643 hddLog(LOGE, FL("SAP Stop Failed"));
10644 goto end;
10645 }
10646 }
10647 }
Kapil Gupta137ef892016-12-13 19:38:00 +053010648 }
10649end:
10650 mutex_unlock(&pHddCtx->sap_lock);
10651 return;
10652}
10653
10654/**
10655 * __hdd_sap_restart_handle() - to handle restarting of SAP
10656 * @work: name of the work
10657 *
10658 * Purpose of this function is to trigger sap start. this function
10659 * will be called from workqueue.
10660 *
10661 * Return: void.
10662 */
10663static void __hdd_sap_restart_handle(struct work_struct *work)
10664{
10665 hdd_adapter_t *sap_adapter;
10666 hdd_context_t *hdd_ctx = container_of(work,
10667 hdd_context_t,
10668 sap_start_work);
10669 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
10670 vos_ssr_unprotect(__func__);
10671 return;
10672 }
10673 sap_adapter = hdd_get_adapter(hdd_ctx,
10674 WLAN_HDD_SOFTAP);
10675 if (sap_adapter == NULL) {
10676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10677 FL("sap_adapter is NULL"));
10678 vos_ssr_unprotect(__func__);
10679 return;
10680 }
10681
10682 if (hdd_ctx->is_ch_avoid_in_progress) {
10683 sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT;
10684 wlan_hdd_restart_sap(sap_adapter);
10685 hdd_change_ch_avoidance_status(hdd_ctx, false);
10686 }
Agrawal Ashish574b3e62017-02-09 18:58:34 +053010687 if (hdd_ctx->cfg_ini->enable_sap_auth_offload)
10688 wlan_hdd_restart_sap(sap_adapter);
Kapil Gupta137ef892016-12-13 19:38:00 +053010689}
10690
10691/**
10692 * hdd_sap_restart_handle() - to handle restarting of SAP
10693 * @work: name of the work
10694 *
10695 * Purpose of this function is to trigger sap start. this function
10696 * will be called from workqueue.
10697 *
10698 * Return: void.
10699 */
10700static void hdd_sap_restart_handle(struct work_struct *work)
10701{
10702 vos_ssr_protect(__func__);
10703 __hdd_sap_restart_handle(work);
10704 vos_ssr_unprotect(__func__);
10705}
10706
10707
Abhishek Singh78c691f2017-11-30 13:48:44 +053010708/**
10709 * __hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10710 * @work: name of the work
10711 *
10712 * Purpose of this function is to force SCC using ECSA. This function
10713 * will be called from workqueue.
10714 *
10715 * Return: void.
10716 */
10717static void
10718__hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10719{
10720 hdd_adapter_t *sap_adapter;
10721 hdd_station_ctx_t *sta_ctx;
10722 hdd_adapter_t *sta_adapter;
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010723 ptSapContext sap_ctx = NULL;
10724 v_CONTEXT_t vos_ctx;
10725 tANI_U8 target_channel;
10726 tsap_Config_t *sap_config;
10727 bool sta_sap_scc_on_dfs_chan;
10728 eNVChannelEnabledType chan_state;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010729 hdd_context_t *hdd_ctx = container_of(to_delayed_work(work),
10730 hdd_context_t,
10731 ecsa_chan_change_work);
10732
10733 if (wlan_hdd_validate_context(hdd_ctx))
10734 return;
10735
10736 sap_adapter = hdd_get_adapter(hdd_ctx,
10737 WLAN_HDD_SOFTAP);
10738 if (!sap_adapter) {
10739 hddLog(LOGE, FL("sap_adapter is NULL"));
10740 return;
10741 }
10742
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010743 vos_ctx = hdd_ctx->pvosContext;
10744 if (!vos_ctx) {
10745 hddLog(LOGE, FL("vos_ctx is NULL"));
10746 return;
10747 }
10748
10749 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10750 if (!sap_ctx) {
10751 hddLog(LOGE, FL("sap_ctx is NULL"));
10752 return;
10753 }
10754
10755 sap_config = &sap_adapter->sessionCtx.ap.sapConfig;
10756
10757 sta_sap_scc_on_dfs_chan = hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_ctx);
10758
Abhishek Singh78c691f2017-11-30 13:48:44 +053010759 sta_adapter = hdd_get_adapter(hdd_ctx,
10760 WLAN_HDD_INFRA_STATION);
10761 if (!sta_adapter) {
10762 hddLog(LOGE, FL("sta_adapter is NULL"));
10763 return;
10764 }
Abhishek Singh78c691f2017-11-30 13:48:44 +053010765
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010766 if (wlansap_chk_n_set_chan_change_in_progress(sap_ctx))
Abhishek Singh78c691f2017-11-30 13:48:44 +053010767 return;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010768 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
10769
10770 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
10771 if (sta_ctx->conn_info.connState != eConnectionState_Associated) {
10772 if (sta_ctx->conn_info.connState == eConnectionState_NotConnected) {
10773 chan_state = vos_nv_getChannelEnabledState(sap_ctx->channel);
10774 hddLog(LOG1, FL("sta not in connected state %d, sta_sap_scc_on_dfs_chan %d, chan_state %d"),
10775 sta_ctx->conn_info.connState, sta_sap_scc_on_dfs_chan,
10776 chan_state);
10777 if (sta_sap_scc_on_dfs_chan &&
10778 (chan_state == NV_CHANNEL_DFS)) {
10779 hddLog(LOGE, FL("Switch SAP to user configured channel"));
10780 target_channel = sap_config->user_config_channel;
10781 goto switch_channel;
10782 }
10783 }
10784 goto abort;
Abhishek Singh78c691f2017-11-30 13:48:44 +053010785 }
10786
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010787 target_channel = sta_ctx->conn_info.operationChannel;
10788switch_channel:
10789 hddLog(LOGE, FL("Switch SAP to %d channel"),
10790 target_channel);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010791 if (!wlansap_set_channel_change(vos_ctx, target_channel, true))
10792 return;
10793
10794abort:
10795 wlansap_reset_chan_change_in_progress(sap_ctx);
10796 complete(&sap_ctx->ecsa_info.chan_switch_comp);
Abhishek Singh78c691f2017-11-30 13:48:44 +053010797}
10798
10799/**
10800 * hdd_force_scc_with_ecsa_handle() - to handle force scc using ecsa
10801 * @work: name of the work
10802 *
10803 * Purpose of this function is to force SCC using ECSA. This function
10804 * will be called from workqueue.
10805 *
10806 * Return: void.
10807 */
10808static void
10809hdd_force_scc_with_ecsa_handle(struct work_struct *work)
10810{
10811 vos_ssr_protect(__func__);
10812 __hdd_force_scc_with_ecsa_handle(work);
10813 vos_ssr_unprotect(__func__);
10814}
10815
Abhishek Singh10e17cf2018-03-12 14:34:22 +053010816int hdd_wait_for_ecsa_complete(hdd_context_t *hdd_ctx)
10817{
10818 int ret;
10819 ptSapContext sap_ctx = NULL;
10820 v_CONTEXT_t vos_ctx;
10821
10822 vos_ctx = hdd_ctx->pvosContext;
10823 if (!vos_ctx) {
10824 hddLog(LOGE, FL("vos_ctx is NULL"));
10825 return 0;
10826 }
10827
10828 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
10829 if (!sap_ctx) {
10830 hddLog(LOG1, FL("sap_ctx is NULL"));
10831 return 0;
10832 }
10833 if(!sap_ctx->isSapSessionOpen) {
10834 hddLog(LOG1, FL("sap session not opened, SAP in state %d"),
10835 sap_ctx->sapsMachine);
10836 return 0;
10837 }
10838
10839 if (!wlansap_get_change_in_progress(sap_ctx)) {
10840 hddLog(LOG1, FL("channel switch not in progress"));
10841 return 0;
10842 }
10843 ret = wait_for_completion_timeout(&sap_ctx->ecsa_info.chan_switch_comp,
10844 msecs_to_jiffies(HDD_SAP_CHAN_CNG_WAIT_TIME));
10845 if (!ret)
10846 {
10847 hddLog(LOGE, FL("Timeout waiting for SAP channel switch"));
10848 return ret;
10849 }
10850
10851 return 0;
10852}
10853
10854
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010855/**
10856 * hdd_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc allowed on
10857 * dfs chan
10858 * @hdd_ctx: pointer to hdd context
10859 *
10860 * This function used to check if sta+sap scc allowed on DFS channel.
10861 *
10862 * Return: None
10863 */
10864bool hdd_is_sta_sap_scc_allowed_on_dfs_chan(hdd_context_t *hdd_ctx)
10865{
10866 if (hdd_ctx->cfg_ini->force_scc_with_ecsa &&
10867 hdd_ctx->cfg_ini->sta_sap_scc_on_dfs_chan)
10868 return true;
10869 else
10870 return false;
10871}
10872
Jeff Johnson295189b2012-06-20 16:38:30 -070010873VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx )
10874{
10875 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10876 VOS_STATUS status;
10877 hdd_adapter_t *pAdapter;
10878
10879 ENTER();
10880
10881 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10882
10883 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10884 {
10885 pAdapter = pAdapterNode->pAdapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070010886
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010887 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -070010888
10889 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10890 pAdapterNode = pNext;
10891 }
10892
10893 EXIT();
10894
10895 return VOS_STATUS_SUCCESS;
10896}
10897
Rajeev Kumarf999e582014-01-09 17:33:29 -080010898
10899#ifdef FEATURE_WLAN_BATCH_SCAN
10900/**---------------------------------------------------------------------------
10901
10902 \brief hdd_deinit_batch_scan () - This function cleans up batch scan data
10903 structures
10904
10905 \param - pAdapter Pointer to HDD adapter
10906
10907 \return - None
10908
10909 --------------------------------------------------------------------------*/
10910void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter)
10911{
10912 tHddBatchScanRsp *pNode;
10913 tHddBatchScanRsp *pPrev;
10914
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010915 if (NULL == pAdapter)
Rajeev Kumarf999e582014-01-09 17:33:29 -080010916 {
Siddharth Bhalb3e9b792014-02-24 15:14:16 +053010917 hddLog(VOS_TRACE_LEVEL_ERROR,
10918 "%s: Adapter context is Null", __func__);
10919 return;
10920 }
10921
10922 pNode = pAdapter->pBatchScanRsp;
10923 while (pNode)
10924 {
10925 pPrev = pNode;
10926 pNode = pNode->pNext;
10927 vos_mem_free((v_VOID_t * )pPrev);
Rajeev Kumarf999e582014-01-09 17:33:29 -080010928 }
10929
10930 pAdapter->pBatchScanRsp = NULL;
10931 pAdapter->numScanList = 0;
10932 pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED;
10933 pAdapter->prev_batch_id = 0;
10934
10935 return;
10936}
10937#endif
10938
10939
Jeff Johnson295189b2012-06-20 16:38:30 -070010940VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx )
10941{
10942 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10943 VOS_STATUS status;
10944 hdd_adapter_t *pAdapter;
10945
10946 ENTER();
10947
10948 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10949
10950 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10951 {
10952 pAdapter = pAdapterNode->pAdapter;
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053010953 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010954 netif_tx_disable(pAdapter->dev);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010955
10956 if (pHddCtx->cfg_ini->sap_internal_restart &&
10957 pAdapter->device_mode == WLAN_HDD_SOFTAP) {
10958 hddLog(LOG1, FL("driver supports sap restart"));
10959 vos_flush_work(&pHddCtx->sap_start_work);
10960 hdd_sap_indicate_disconnect_for_sta(pAdapter);
10961 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053010962 hdd_softap_deinit_tx_rx(pAdapter, true);
10963 hdd_sap_destroy_timers(pAdapter);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053010964 } else {
10965 netif_carrier_off(pAdapter->dev);
10966 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010967
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010968 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053010969
10970 if (pAdapter->device_mode == WLAN_HDD_MONITOR)
10971 pAdapter->sessionCtx.monitor.state = MON_MODE_STOP;
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070010972
Jeff Johnson295189b2012-06-20 16:38:30 -070010973 hdd_deinit_tx_rx(pAdapter);
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010974
Katya Nigam1fd24402015-02-16 14:52:19 +053010975 if(pAdapter->device_mode == WLAN_HDD_IBSS )
10976 hdd_ibss_deinit_tx_rx(pAdapter);
10977
Nirav Shah7e3c8132015-06-22 23:51:42 +053010978 status = hdd_sta_id_hash_detach(pAdapter);
10979 if (status != VOS_STATUS_SUCCESS)
10980 hddLog(VOS_TRACE_LEVEL_ERROR,
10981 FL("sta id hash detach failed for session id %d"),
10982 pAdapter->sessionId);
10983
Agarwal Ashish6267caa2014-08-06 19:16:21 +053010984 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10985
Madan Mohan Koyyalamudi8c6dec82013-09-26 15:56:13 +053010986 if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags))
10987 {
10988 hdd_wmm_adapter_close( pAdapter );
10989 clear_bit(WMM_INIT_DONE, &pAdapter->event_flags);
10990 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010991
Siddharth Bhal2db319d2014-12-03 12:37:18 +053010992 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
10993 {
10994 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
10995 }
10996
Rajeev Kumarf999e582014-01-09 17:33:29 -080010997#ifdef FEATURE_WLAN_BATCH_SCAN
10998 if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState)
10999 {
11000 hdd_deinit_batch_scan(pAdapter);
11001 }
11002#endif
11003
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011004#ifdef FEATURE_WLAN_TDLS
11005 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI2d4d5c42015-03-03 14:34:19 +053011006 wlan_hdd_tdls_exit(pAdapter, TRUE);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +053011007 mutex_unlock(&pHddCtx->tdls_lock);
11008#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011009 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11010 pAdapterNode = pNext;
11011 }
11012
11013 EXIT();
11014
11015 return VOS_STATUS_SUCCESS;
11016}
11017
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011018/**
Abhishek Singh5a597e62016-12-05 15:16:30 +053011019 * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid
11020 * @wiphy: wiphy
11021 * @channel: channel of the BSS to find
11022 * @bssid: bssid of the BSS to find
11023 * @ssid: ssid of the BSS to find
11024 * @ssid_len: ssid len of of the BSS to find
11025 *
11026 * The API is a wrapper to get bss from kernel matching the chan,
11027 * bssid and ssid
11028 *
11029 * Return: Void
11030 */
11031#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
11032 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
11033
11034struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11035 struct ieee80211_channel *channel,
11036 const u8 *bssid,
11037 const u8 *ssid, size_t ssid_len)
11038{
11039 return cfg80211_get_bss(wiphy, channel, bssid,
11040 ssid, ssid_len,
11041 WLAN_CAPABILITY_ESS,
11042 WLAN_CAPABILITY_ESS);
11043}
11044#else
11045struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy,
11046 struct ieee80211_channel *channel,
11047 const u8 *bssid,
11048 const u8 *ssid, size_t ssid_len)
11049{
11050 return cfg80211_get_bss(wiphy, channel, bssid,
11051 ssid, ssid_len,
11052 IEEE80211_BSS_TYPE_ESS,
11053 IEEE80211_PRIVACY_ANY);
11054}
11055#endif
11056
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011057#if defined(CFG80211_CONNECT_BSS) || \
11058 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
11059
11060#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || \
11061 defined (CFG80211_CONNECT_TIMEOUT_REASON_CODE)
11062/**
11063 * hdd_connect_bss() - helper function to send connection status to supplicant
11064 * @dev: network device
11065 * @bssid: bssid to which we want to associate
11066 * @bss: information about connected bss
11067 * @req_ie: Request Information Element
11068 * @req_ie_len: len of the req IE
11069 * @resp_ie: Response IE
11070 * @resp_ie_len: len of ht response IE
11071 * @status: status
11072 * @gfp: Kernel Flag
11073 *
11074 * This is a helper function to send connection status to supplicant
11075 * and gets invoked from wrapper API
11076 *
11077 * Return: Void
11078 */
11079static void hdd_connect_bss(struct net_device *dev,
11080 const u8 *bssid,
11081 struct cfg80211_bss *bss,
11082 const u8 *req_ie,
11083 size_t req_ie_len,
11084 const u8 *resp_ie,
11085 size_t resp_ie_len,
11086 u16 status,
11087 gfp_t gfp)
11088{
11089 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11090 resp_ie, resp_ie_len, status, gfp, NL80211_TIMEOUT_UNSPECIFIED);
11091}
11092#else
11093/**
11094 * hdd_connect_bss() - helper function to send connection status to supplicant
11095 * @dev: network device
11096 * @bssid: bssid to which we want to associate
11097 * @bss: information about connected bss
11098 * @req_ie: Request Information Element
11099 * @req_ie_len: len of the req IE
11100 * @resp_ie: Response IE
11101 * @resp_ie_len: len of ht response IE
11102 * @status: status
11103 * @gfp: Kernel Flag
11104 *
11105 * This is a helper function to send connection status to supplicant
11106 * and gets invoked from wrapper API
11107 *
11108 * Return: Void
11109 */
11110static void hdd_connect_bss(struct net_device *dev,
11111 const u8 *bssid,
11112 struct cfg80211_bss *bss,
11113 const u8 *req_ie,
11114 size_t req_ie_len,
11115 const u8 *resp_ie,
11116 size_t resp_ie_len,
11117 u16 status,
11118 gfp_t gfp)
11119{
11120 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
11121 resp_ie, resp_ie_len, status, gfp);
11122}
11123#endif
11124
Abhishek Singh5a597e62016-12-05 15:16:30 +053011125/**
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011126 * hdd_connect_result() - API to send connection status to supplicant
11127 * @dev: network device
11128 * @bssid: bssid to which we want to associate
11129 * @roam_info: information about connected bss
11130 * @req_ie: Request Information Element
11131 * @req_ie_len: len of the req IE
11132 * @resp_ie: Response IE
11133 * @resp_ie_len: len of ht response IE
11134 * @status: status
11135 * @gfp: Kernel Flag
11136 *
11137 * The API is a wrapper to send connection status to supplicant
11138 *
11139 * Return: Void
11140 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011141void hdd_connect_result(struct net_device *dev,
11142 const u8 *bssid,
11143 tCsrRoamInfo *roam_info,
11144 const u8 *req_ie,
11145 size_t req_ie_len,
11146 const u8 *resp_ie,
11147 size_t resp_ie_len,
11148 u16 status,
11149 gfp_t gfp)
11150{
11151 hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev);
11152 struct cfg80211_bss *bss = NULL;
11153
11154 if (WLAN_STATUS_SUCCESS == status) {
11155 struct ieee80211_channel *chan;
11156 int freq;
11157 int chan_no = roam_info->pBssDesc->channelId;;
11158
11159 if (chan_no <= 14)
11160 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011161 HDD_NL80211_BAND_2GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011162 else
11163 freq = ieee80211_channel_to_frequency(chan_no,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011164 HDD_NL80211_BAND_5GHZ);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011165
11166 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
Abhishek Singh5a597e62016-12-05 15:16:30 +053011167 bss = hdd_get_bss_entry(padapter->wdev.wiphy,
11168 chan, bssid,
11169 roam_info->u.pConnectedProfile->SSID.ssId,
11170 roam_info->u.pConnectedProfile->SSID.length);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011171 }
11172
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011173 hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
11174 status, gfp);
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011175}
11176#else
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053011177/**
11178 * hdd_connect_result() - API to send connection status to supplicant
11179 * @dev: network device
11180 * @bssid: bssid to which we want to associate
11181 * @roam_info: information about connected bss
11182 * @req_ie: Request Information Element
11183 * @req_ie_len: len of the req IE
11184 * @resp_ie: Response IE
11185 * @resp_ie_len: len of ht response IE
11186 * @status: status
11187 * @gfp: Kernel Flag
11188 *
11189 * The API is a wrapper to send connection status to supplicant
11190 *
11191 * Return: Void
11192 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011193void hdd_connect_result(struct net_device *dev,
11194 const u8 *bssid,
11195 tCsrRoamInfo *roam_info,
11196 const u8 *req_ie,
11197 size_t req_ie_len,
11198 const u8 * resp_ie,
11199 size_t resp_ie_len,
11200 u16 status,
11201 gfp_t gfp)
11202{
11203 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
11204 resp_ie, resp_ie_len, status, gfp);
11205}
11206#endif
11207
Jeff Johnson295189b2012-06-20 16:38:30 -070011208VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx )
11209{
11210 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11211 VOS_STATUS status;
11212 hdd_adapter_t *pAdapter;
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011213 eConnectionState connState;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011214 v_CONTEXT_t pVosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011215
11216 ENTER();
11217
11218 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11219
11220 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11221 {
11222 pAdapter = pAdapterNode->pAdapter;
11223
Kumar Anand82c009f2014-05-29 00:29:42 -070011224 hdd_wmm_init( pAdapter );
11225
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 switch(pAdapter->device_mode)
11227 {
11228 case WLAN_HDD_INFRA_STATION:
11229 case WLAN_HDD_P2P_CLIENT:
Jeff Johnsone7245742012-09-05 17:12:55 -070011230 case WLAN_HDD_P2P_DEVICE:
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011231
11232 connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState;
11233
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 hdd_init_station_mode(pAdapter);
11235 /* Open the gates for HDD to receive Wext commands */
11236 pAdapter->isLinkUpSvcNeeded = FALSE;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011237 pHddCtx->scan_info.mScanPending = FALSE;
11238 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011239
11240 //Trigger the initial scan
Mukul Sharmae74e42c2015-08-06 23:55:49 +053011241 if (!pHddCtx->isLogpInProgress)
11242 hdd_wlan_initial_scan(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011243
11244 //Indicate disconnect event to supplicant if associated previously
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011245 if (eConnectionState_Associated == connState ||
11246 eConnectionState_IbssConnected == connState )
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 {
11248 union iwreq_data wrqu;
11249 memset(&wrqu, '\0', sizeof(wrqu));
11250 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
11251 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
11252 wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL);
Srinivas Girigowda66c05eb2013-07-14 13:06:01 -070011253 pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011254
Jeff Johnson295189b2012-06-20 16:38:30 -070011255 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagar9ff4bcc2016-06-01 17:17:50 +053011256 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false,
Mahesh A Saptasagarb5a15142016-05-25 11:27:43 +053011257 WLAN_REASON_UNSPECIFIED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011258 }
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011259 else if (eConnectionState_Connecting == connState)
11260 {
11261 /*
11262 * Indicate connect failure to supplicant if we were in the
11263 * process of connecting
11264 */
Abhishek Singhbbe0b2a2016-12-05 11:57:36 +053011265 hdd_connect_result(pAdapter->dev, NULL, NULL,
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011266 NULL, 0, NULL, 0,
11267 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
11268 GFP_KERNEL);
11269 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 break;
11271
11272 case WLAN_HDD_SOFTAP:
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011273 if (pHddCtx->cfg_ini->sap_internal_restart) {
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011274 hdd_init_ap_mode(pAdapter, true);
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053011275 status = hdd_sta_id_hash_attach(pAdapter);
11276 if (VOS_STATUS_SUCCESS != status)
11277 {
11278 hddLog(VOS_TRACE_LEVEL_FATAL,
11279 FL("failed to attach hash for"));
11280 }
11281 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 break;
11283
11284 case WLAN_HDD_P2P_GO:
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011285 hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant",
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 __func__);
Sameer Thalappiledf0d792013-08-09 14:31:03 -070011287 cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -070011288 break;
11289
11290 case WLAN_HDD_MONITOR:
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011291 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
11292
11293 hddLog(VOS_TRACE_LEVEL_INFO, FL("[SSR] monitor mode"));
11294 if (!pVosContext) {
11295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos context is NULL"));
11296 break;
11297 }
11298
11299 hdd_init_tx_rx(pAdapter);
11300 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk);
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 break;
Hanumanth Reddy Pothulada449f12018-03-13 18:19:19 +053011302
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 default:
11304 break;
11305 }
11306
11307 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11308 pAdapterNode = pNext;
11309 }
11310
11311 EXIT();
11312
11313 return VOS_STATUS_SUCCESS;
11314}
11315
11316VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx )
11317{
11318 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11319 hdd_adapter_t *pAdapter;
11320 VOS_STATUS status;
11321 v_U32_t roamId;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011322 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011323
11324 ENTER();
11325
11326 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11327
11328 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11329 {
11330 pAdapter = pAdapterNode->pAdapter;
11331
11332 if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11333 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11334 {
11335 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11336 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11337
Abhishek Singhf4669da2014-05-26 15:07:49 +053011338 hddLog(VOS_TRACE_LEVEL_INFO,
11339 "%s: Set HDD connState to eConnectionState_NotConnected",
11340 __func__);
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011341 spin_lock_bh(&pAdapter->lock_for_active_session);
11342 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
11343 {
11344 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
11345 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011346 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Ganesh Kondabattini04338412015-09-14 15:39:09 +053011347 spin_unlock_bh(&pAdapter->lock_for_active_session);
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 init_completion(&pAdapter->disconnect_comp_var);
11349 sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId,
11350 eCSR_DISCONNECT_REASON_UNSPECIFIED);
11351
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011352 ret = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011353 &pAdapter->disconnect_comp_var,
11354 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011355 if (0 >= ret)
11356 hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld",
11357 __func__, ret);
Jeff Johnson295189b2012-06-20 16:38:30 -070011358
11359 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
11360 pHddCtx->isAmpAllowed = VOS_FALSE;
11361 sme_RoamConnect(pHddCtx->hHal,
11362 pAdapter->sessionId, &(pWextState->roamProfile),
11363 &roamId);
11364 }
11365
11366 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11367 pAdapterNode = pNext;
11368 }
11369
11370 EXIT();
11371
11372 return VOS_STATUS_SUCCESS;
11373}
11374
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011375void hdd_dump_concurrency_info(hdd_context_t *pHddCtx)
11376{
11377 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11378 VOS_STATUS status;
11379 hdd_adapter_t *pAdapter;
11380 hdd_station_ctx_t *pHddStaCtx;
11381 hdd_ap_ctx_t *pHddApCtx;
11382 hdd_hostapd_state_t * pHostapdState;
11383 tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 };
11384 v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
11385 const char *p2pMode = "DEV";
11386 const char *ccMode = "Standalone";
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011387
11388 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11389 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11390 {
11391 pAdapter = pAdapterNode->pAdapter;
11392 switch (pAdapter->device_mode) {
11393 case WLAN_HDD_INFRA_STATION:
11394 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11395 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11396 staChannel = pHddStaCtx->conn_info.operationChannel;
11397 memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid));
11398 }
11399 break;
11400 case WLAN_HDD_P2P_CLIENT:
11401 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11402 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
11403 p2pChannel = pHddStaCtx->conn_info.operationChannel;
11404 memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid));
11405 p2pMode = "CLI";
11406 }
11407 break;
11408 case WLAN_HDD_P2P_GO:
11409 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11410 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11411 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11412 p2pChannel = pHddApCtx->operatingChannel;
11413 memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid));
11414 }
11415 p2pMode = "GO";
11416 break;
11417 case WLAN_HDD_SOFTAP:
11418 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11419 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11420 if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) {
11421 apChannel = pHddApCtx->operatingChannel;
11422 memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid));
11423 }
11424 break;
11425 default:
11426 break;
11427 }
11428 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11429 pAdapterNode = pNext;
11430 }
11431 if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) {
11432 ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC";
11433 }
Yeshwanth Sriram Guntuka0004c0b2017-12-06 14:43:49 +053011434 hddLog(VOS_TRACE_LEVEL_ERROR, "wlan(%d) " MAC_ADDRESS_STR " %s",
11435 staChannel, MAC_ADDR_ARRAY(staBssid), ccMode);
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011436 if (p2pChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011437 hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011438 p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid));
11439 }
11440 if (apChannel > 0) {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +053011441 hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR,
Sudhir Sattayappa Kohalli90e4c752013-03-21 14:25:04 -070011442 apChannel, MAC_ADDR_ARRAY(apBssid));
11443 }
11444
11445 if (p2pChannel > 0 && apChannel > 0) {
11446 hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel);
11447 }
11448}
11449
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011450bool hdd_is_ssr_required( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070011451{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011452 return (isSsrRequired == HDD_SSR_REQUIRED);
Jeff Johnson295189b2012-06-20 16:38:30 -070011453}
11454
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011455/* Once SSR is disabled then it cannot be set. */
11456void hdd_set_ssr_required( e_hdd_ssr_required value)
Jeff Johnson295189b2012-06-20 16:38:30 -070011457{
Madan Mohan Koyyalamudib5da5332012-10-15 17:23:21 -070011458 if (HDD_SSR_DISABLED == isSsrRequired)
11459 return;
11460
Jeff Johnson295189b2012-06-20 16:38:30 -070011461 isSsrRequired = value;
11462}
11463
Hema Aparna Medicharla6b4d4f32015-06-23 04:09:12 +053011464void hdd_set_pre_close( hdd_context_t *pHddCtx)
11465{
11466 sme_PreClose(pHddCtx->hHal);
11467}
11468
Jeff Johnson295189b2012-06-20 16:38:30 -070011469VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx,
11470 hdd_adapter_list_node_t** ppAdapterNode)
11471{
11472 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011473 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 status = hdd_list_peek_front ( &pHddCtx->hddAdapters,
11475 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011476 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011477 return status;
11478}
11479
11480VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx,
11481 hdd_adapter_list_node_t* pAdapterNode,
11482 hdd_adapter_list_node_t** pNextAdapterNode)
11483{
11484 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011485 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 status = hdd_list_peek_next ( &pHddCtx->hddAdapters,
11487 (hdd_list_node_t*) pAdapterNode,
11488 (hdd_list_node_t**)pNextAdapterNode );
11489
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011490 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011491 return status;
11492}
11493
11494VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx,
11495 hdd_adapter_list_node_t* pAdapterNode)
11496{
11497 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011498 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011499 status = hdd_list_remove_node ( &pHddCtx->hddAdapters,
11500 &pAdapterNode->node );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011501 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 return status;
11503}
11504
11505VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx,
11506 hdd_adapter_list_node_t** ppAdapterNode)
11507{
11508 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011509 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 status = hdd_list_remove_front( &pHddCtx->hddAdapters,
11511 (hdd_list_node_t**) ppAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011512 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011513 return status;
11514}
11515
11516VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx,
11517 hdd_adapter_list_node_t* pAdapterNode)
11518{
11519 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011520 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011521 status = hdd_list_insert_back ( &pHddCtx->hddAdapters,
11522 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011523 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 return status;
11525}
11526
11527VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx,
11528 hdd_adapter_list_node_t* pAdapterNode)
11529{
11530 VOS_STATUS status;
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011531 spin_lock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011532 status = hdd_list_insert_front ( &pHddCtx->hddAdapters,
11533 (hdd_list_node_t*) pAdapterNode );
Mukul Sharmaae1266d2015-06-26 15:29:53 +053011534 spin_unlock_bh(&pHddCtx->hddAdapters.lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011535 return status;
11536}
11537
11538hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx,
11539 tSirMacAddr macAddr )
11540{
11541 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11542 hdd_adapter_t *pAdapter;
11543 VOS_STATUS status;
11544
11545 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11546
11547 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11548 {
11549 pAdapter = pAdapterNode->pAdapter;
11550
11551 if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes,
11552 macAddr, sizeof(tSirMacAddr) ) )
11553 {
11554 return pAdapter;
11555 }
11556 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11557 pAdapterNode = pNext;
11558 }
11559
11560 return NULL;
11561
11562}
11563
11564hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name )
11565{
11566 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11567 hdd_adapter_t *pAdapter;
11568 VOS_STATUS status;
11569
11570 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11571
11572 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11573 {
11574 pAdapter = pAdapterNode->pAdapter;
11575
11576 if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name,
11577 IFNAMSIZ ) )
11578 {
11579 return pAdapter;
11580 }
11581 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11582 pAdapterNode = pNext;
11583 }
11584
11585 return NULL;
11586
11587}
11588
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053011589hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
11590 tANI_U32 sme_session_id )
11591{
11592 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11593 hdd_adapter_t *pAdapter;
11594 VOS_STATUS vos_status;
11595
11596
11597 vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
11598
11599 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
11600 {
11601 pAdapter = pAdapterNode->pAdapter;
11602
11603 if (pAdapter->sessionId == sme_session_id)
11604 return pAdapter;
11605
11606 vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
11607 pAdapterNode = pNext;
11608 }
11609
11610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11611 "%s: sme_session_id %d does not exist with host",
11612 __func__, sme_session_id);
11613
11614 return NULL;
11615}
11616
Jeff Johnson295189b2012-06-20 16:38:30 -070011617hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
11618{
11619 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11620 hdd_adapter_t *pAdapter;
11621 VOS_STATUS status;
11622
11623 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11624
11625 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11626 {
11627 pAdapter = pAdapterNode->pAdapter;
11628
11629 if( pAdapter && (mode == pAdapter->device_mode) )
11630 {
11631 return pAdapter;
11632 }
11633 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11634 pAdapterNode = pNext;
11635 }
11636
11637 return NULL;
11638
11639}
11640
11641//Remove this function later
11642hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx )
11643{
11644 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11645 hdd_adapter_t *pAdapter;
11646 VOS_STATUS status;
11647
11648 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11649
11650 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11651 {
11652 pAdapter = pAdapterNode->pAdapter;
11653
11654 if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode )
11655 {
11656 return pAdapter;
11657 }
11658
11659 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11660 pAdapterNode = pNext;
11661 }
11662
11663 return NULL;
11664
11665}
11666
Jeff Johnson295189b2012-06-20 16:38:30 -070011667/**---------------------------------------------------------------------------
11668
Mahesh A Saptasgar64534612014-09-23 13:13:33 +053011669 \brief hdd_get_operating_channel() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011670
11671 This API returns the operating channel of the requested device mode
11672
11673 \param - pHddCtx - Pointer to the HDD context.
11674 - mode - Device mode for which operating channel is required
11675 suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT
11676 WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO.
11677 \return - channel number. "0" id the requested device is not found OR it is not connected.
11678 --------------------------------------------------------------------------*/
11679v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode )
11680{
11681 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11682 VOS_STATUS status;
11683 hdd_adapter_t *pAdapter;
11684 v_U8_t operatingChannel = 0;
11685
11686 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11687
11688 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11689 {
11690 pAdapter = pAdapterNode->pAdapter;
11691
11692 if( mode == pAdapter->device_mode )
11693 {
11694 switch(pAdapter->device_mode)
11695 {
11696 case WLAN_HDD_INFRA_STATION:
11697 case WLAN_HDD_P2P_CLIENT:
11698 if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) )
11699 operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel;
11700 break;
11701 case WLAN_HDD_SOFTAP:
11702 case WLAN_HDD_P2P_GO:
11703 /*softap connection info */
11704 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11705 operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel;
11706 break;
11707 default:
11708 break;
11709 }
11710
11711 break; //Found the device of interest. break the loop
11712 }
11713
11714 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11715 pAdapterNode = pNext;
11716 }
11717 return operatingChannel;
11718}
11719
11720#ifdef WLAN_FEATURE_PACKET_FILTERING
11721/**---------------------------------------------------------------------------
11722
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011723 \brief __hdd_set_multicast_list() -
Jeff Johnson295189b2012-06-20 16:38:30 -070011724
11725 This used to set the multicast address list.
11726
11727 \param - dev - Pointer to the WLAN device.
11728 - skb - Pointer to OS packet (sk_buff).
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011729 \return - success/fail
Jeff Johnson295189b2012-06-20 16:38:30 -070011730
11731 --------------------------------------------------------------------------*/
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011732static void __hdd_set_multicast_list(struct net_device *dev)
Jeff Johnson295189b2012-06-20 16:38:30 -070011733{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011734 hdd_adapter_t *pAdapter;
11735 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011736 int mc_count;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011737 int i = 0, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 struct netdev_hw_addr *ha;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011739
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011740 ENTER();
11741
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011742 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011743 if (NULL == pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 {
11745 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011746 "%s: Adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011747 return;
11748 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011749 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11750 ret = wlan_hdd_validate_context(pHddCtx);
11751 if (0 != ret)
11752 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011753 return;
11754 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011755 if (dev->flags & IFF_ALLMULTI)
11756 {
11757 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011758 "%s: allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011759 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011761 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011762 {
11763 mc_count = netdev_mc_count(dev);
11764 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011765 "%s: mc_count = %u", __func__, mc_count);
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST)
11767 {
11768 hddLog(VOS_TRACE_LEVEL_INFO,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011769 "%s: No free filter available; allow all multicast frames", __func__);
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011770 pAdapter->mc_addr_list.mc_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011771 return;
11772 }
11773
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011774 pAdapter->mc_addr_list.mc_cnt = mc_count;
Jeff Johnson295189b2012-06-20 16:38:30 -070011775
11776 netdev_for_each_mc_addr(ha, dev) {
11777 if (i == mc_count)
11778 break;
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011779 memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN);
11780 memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN);
Arif Hussain6d2a3322013-11-17 19:50:10 -080011781 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR,
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053011782 __func__, i,
Gopichand Nakkala0f276812013-02-24 14:45:51 +053011783 MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i]));
Jeff Johnson295189b2012-06-20 16:38:30 -070011784 i++;
11785 }
11786 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011787
Ganesh Kondabattinifb37e652015-10-09 15:46:47 +053011788 if (pHddCtx->hdd_wlan_suspended)
11789 {
11790 /*
11791 * Configure the Mcast address list to FW
11792 * If wlan is already in suspend mode
11793 */
11794 wlan_hdd_set_mc_addr_list(pAdapter, TRUE);
11795 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011796 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011797 return;
11798}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011799
11800static void hdd_set_multicast_list(struct net_device *dev)
11801{
11802 vos_ssr_protect(__func__);
11803 __hdd_set_multicast_list(dev);
11804 vos_ssr_unprotect(__func__);
11805}
Jeff Johnson295189b2012-06-20 16:38:30 -070011806#endif
11807
11808/**---------------------------------------------------------------------------
11809
11810 \brief hdd_select_queue() -
11811
11812 This function is registered with the Linux OS for network
11813 core to decide which queue to use first.
11814
11815 \param - dev - Pointer to the WLAN device.
11816 - skb - Pointer to OS packet (sk_buff).
11817 \return - ac, Queue Index/access category corresponding to UP in IP header
11818
11819 --------------------------------------------------------------------------*/
11820v_U16_t hdd_select_queue(struct net_device *dev,
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053011821 struct sk_buff *skb
11822#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
11823 , void *accel_priv
11824#endif
11825#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
11826 , select_queue_fallback_t fallback
11827#endif
11828)
Jeff Johnson295189b2012-06-20 16:38:30 -070011829{
11830 return hdd_wmm_select_queue(dev, skb);
11831}
11832
11833
11834/**---------------------------------------------------------------------------
11835
11836 \brief hdd_wlan_initial_scan() -
11837
11838 This function triggers the initial scan
11839
11840 \param - pAdapter - Pointer to the HDD adapter.
11841
11842 --------------------------------------------------------------------------*/
11843void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter)
11844{
11845 tCsrScanRequest scanReq;
11846 tCsrChannelInfo channelInfo;
11847 eHalStatus halStatus;
Jeff Johnson02797792013-10-26 19:17:13 -070011848 tANI_U32 scanId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011849 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11850
11851 vos_mem_zero(&scanReq, sizeof(tCsrScanRequest));
11852 vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff);
11853 scanReq.BSSType = eCSR_BSS_TYPE_ANY;
11854
11855 if(sme_Is11dSupported(pHddCtx->hHal))
11856 {
11857 halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo );
11858 if ( HAL_STATUS_SUCCESS( halStatus ) )
11859 {
11860 scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels);
11861 if( !scanReq.ChannelInfo.ChannelList )
11862 {
11863 hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__);
11864 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011865 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011866 return;
11867 }
11868 vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList,
11869 channelInfo.numOfChannels);
11870 scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels;
11871 vos_mem_free(channelInfo.ChannelList);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -080011872 channelInfo.ChannelList = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011873 }
11874
11875 scanReq.scanType = eSIR_PASSIVE_SCAN;
11876 scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN;
11877 scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime;
11878 scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime;
11879 }
11880 else
11881 {
11882 scanReq.scanType = eSIR_ACTIVE_SCAN;
11883 scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11884 scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime;
11885 scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime;
11886 }
11887
11888 halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL);
11889 if ( !HAL_STATUS_SUCCESS( halStatus ) )
11890 {
11891 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d",
11892 __func__, halStatus );
11893 }
11894
11895 if(sme_Is11dSupported(pHddCtx->hHal))
11896 vos_mem_free(scanReq.ChannelInfo.ChannelList);
11897}
11898
Jeff Johnson295189b2012-06-20 16:38:30 -070011899/**---------------------------------------------------------------------------
11900
11901 \brief hdd_full_power_callback() - HDD full power callback function
11902
11903 This is the function invoked by SME to inform the result of a full power
11904 request issued by HDD
11905
11906 \param - callbackcontext - Pointer to cookie
11907 \param - status - result of request
11908
11909 \return - None
11910
11911 --------------------------------------------------------------------------*/
11912static void hdd_full_power_callback(void *callbackContext, eHalStatus status)
11913{
Jeff Johnson72a40512013-12-19 10:14:15 -080011914 struct statsContext *pContext = callbackContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011915
11916 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011917 "%s: context = %pK, status = %d", __func__, pContext, status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011918
11919 if (NULL == callbackContext)
11920 {
11921 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070011922 "%s: Bad param, context [%pK]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011923 __func__, callbackContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070011924 return;
11925 }
11926
Jeff Johnson72a40512013-12-19 10:14:15 -080011927 /* there is a race condition that exists between this callback
11928 function and the caller since the caller could time out either
11929 before or while this code is executing. we use a spinlock to
11930 serialize these actions */
11931 spin_lock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011932
11933 if (POWER_CONTEXT_MAGIC != pContext->magic)
11934 {
11935 /* the caller presumably timed out so there is nothing we can do */
Jeff Johnson72a40512013-12-19 10:14:15 -080011936 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 hddLog(VOS_TRACE_LEVEL_WARN,
11938 "%s: Invalid context, magic [%08x]",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011939 __func__, pContext->magic);
Jeff Johnson295189b2012-06-20 16:38:30 -070011940 return;
11941 }
11942
Jeff Johnson72a40512013-12-19 10:14:15 -080011943 /* context is valid so caller is still waiting */
11944
11945 /* paranoia: invalidate the magic */
11946 pContext->magic = 0;
11947
11948 /* notify the caller */
Jeff Johnson295189b2012-06-20 16:38:30 -070011949 complete(&pContext->completion);
Jeff Johnson72a40512013-12-19 10:14:15 -080011950
11951 /* serialization is complete */
11952 spin_unlock(&hdd_context_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070011953}
11954
Katya Nigamf0511f62015-05-05 16:40:57 +053011955void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type)
11956{
11957 pMonCtx->typeSubtypeBitmap = 0;
11958 if( type%10 ) /* Management Packets */
11959 pMonCtx->typeSubtypeBitmap |= 0xFFFF;
11960 type/=10;
11961 if( type%10 ) /* Control Packets */
11962 pMonCtx->typeSubtypeBitmap |= 0xFFFF0000;
11963 type/=10;
11964 if( type%10 ) /* Data Packets */
11965 pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000;
11966}
11967
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053011968VOS_STATUS wlan_hdd_mon_postMsg(void *context, hdd_mon_ctx_t *pMonCtx,
11969 void* callback)
Katya Nigamf0511f62015-05-05 16:40:57 +053011970{
11971 vos_msg_t monMsg;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011972 tSirMonModeReq *pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053011973
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011974 if (MON_MODE_START == pMonCtx->state)
11975 monMsg.type = WDA_MON_START_REQ;
11976 else if (MON_MODE_STOP == pMonCtx->state)
11977 monMsg.type = WDA_MON_STOP_REQ;
11978 else {
11979 hddLog(VOS_TRACE_LEVEL_ERROR,
11980 FL("invalid monitor state %d"), pMonCtx->state);
Katya Nigamf0511f62015-05-05 16:40:57 +053011981 return VOS_STATUS_E_FAILURE;
11982 }
11983
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011984 pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq));
11985 if (pMonModeReq == NULL) {
11986 hddLog(VOS_TRACE_LEVEL_ERROR,
11987 FL("fail to allocate memory for monitor mode req"));
11988 return VOS_STATUS_E_FAILURE;
11989 }
Katya Nigamf0511f62015-05-05 16:40:57 +053011990
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053011991 pMonModeReq->context = context;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011992 pMonModeReq->data = pMonCtx;
11993 pMonModeReq->callback = callback;
Katya Nigamf0511f62015-05-05 16:40:57 +053011994
Katya Nigamf0511f62015-05-05 16:40:57 +053011995 monMsg.reserved = 0;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053011996 monMsg.bodyptr = pMonModeReq;
Katya Nigamf0511f62015-05-05 16:40:57 +053011997 monMsg.bodyval = 0;
11998
11999 if (VOS_STATUS_SUCCESS != vos_mq_post_message(
12000 VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) {
12001 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012002 vos_mem_free(pMonModeReq);
Katya Nigamf0511f62015-05-05 16:40:57 +053012003 }
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012004 return VOS_STATUS_SUCCESS;
Katya Nigamf0511f62015-05-05 16:40:57 +053012005}
12006
Katya Nigame7b69a82015-04-28 15:24:06 +053012007void wlan_hdd_mon_close(hdd_context_t *pHddCtx)
12008{
12009 VOS_STATUS vosStatus;
12010 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012011 hdd_mon_ctx_t *pMonCtx = NULL;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012012 int ret;
12013 void *cookie;
12014 struct hdd_request *request;
12015 static const struct hdd_request_params params = {
12016 .priv_size = 0,
12017 .timeout_ms = MON_MODE_MSG_TIMEOUT,
12018 };
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012019
Katya Nigame7b69a82015-04-28 15:24:06 +053012020 hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
12021 if(pAdapter == NULL || pVosContext == NULL)
12022 {
12023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__);
12024 return ;
12025 }
Katya Nigamf0511f62015-05-05 16:40:57 +053012026
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012027 pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
12028 if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) {
12029 pMonCtx->state = MON_MODE_STOP;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012030 request = hdd_request_alloc(&params);
12031 if (!request) {
12032 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
12033 return;
12034 }
12035 cookie = hdd_request_cookie(request);
12036
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012037 if (VOS_STATUS_SUCCESS !=
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012038 wlan_hdd_mon_postMsg(cookie, pMonCtx,
12039 hdd_mon_post_msg_cb)) {
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12041 FL("failed to post MON MODE REQ"));
12042 pMonCtx->state = MON_MODE_START;
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012043 goto req_put;
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012044 }
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012045
12046 ret = hdd_request_wait_for_response(request);
12047 if (ret)
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulab8be9ab2018-04-12 20:03:05 +053012049 FL("timeout on monitor mode completion %d"), ret);
12050
12051req_put:
12052 hdd_request_put(request);
Hanumantha Reddy Pothula91cdd7f2015-09-03 21:25:16 +053012053 }
12054
Katya Nigame7b69a82015-04-28 15:24:06 +053012055 hdd_UnregisterWext(pAdapter->dev);
12056
12057 vos_mon_stop( pVosContext );
12058
12059 vosStatus = vos_sched_close( pVosContext );
12060 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12061 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12062 "%s: Failed to close VOSS Scheduler",__func__);
12063 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12064 }
12065
12066 vosStatus = vos_nv_close();
12067 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12068 {
12069 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12070 "%s: Failed to close NV", __func__);
12071 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12072 }
12073
12074 vos_close(pVosContext);
12075
12076 #ifdef WLAN_KD_READY_NOTIFIER
12077 nl_srv_exit(pHddCtx->ptt_pid);
12078 #else
12079 nl_srv_exit();
12080 #endif
12081
Katya Nigame7b69a82015-04-28 15:24:06 +053012082 hdd_close_all_adapters( pHddCtx );
Katya Nigame7b69a82015-04-28 15:24:06 +053012083}
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012084/**
12085 * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy
12086 * @ wiphy: the wiphy to validate against
12087 *
12088 * Return: void
12089 */
12090void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy)
12091{
12092 int i =0;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053012093 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012094 {
12095 if (NULL != wiphy->bands[i] &&
12096 (NULL != wiphy->bands[i]->channels))
12097 {
12098 vos_mem_free(wiphy->bands[i]->channels);
12099 wiphy->bands[i]->channels = NULL;
12100 }
12101 }
12102}
Jeff Johnson295189b2012-06-20 16:38:30 -070012103/**---------------------------------------------------------------------------
12104
12105 \brief hdd_wlan_exit() - HDD WLAN exit function
12106
12107 This is the driver exit point (invoked during rmmod)
12108
12109 \param - pHddCtx - Pointer to the HDD Context
12110
12111 \return - None
12112
12113 --------------------------------------------------------------------------*/
12114void hdd_wlan_exit(hdd_context_t *pHddCtx)
12115{
12116 eHalStatus halStatus;
12117 v_CONTEXT_t pVosContext = pHddCtx->pvosContext;
12118 VOS_STATUS vosStatus;
Gopichand Nakkala66923aa2013-03-06 23:17:24 +053012119 struct wiphy *wiphy = pHddCtx->wiphy;
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012120 hdd_adapter_t* pAdapter = NULL;
Jeff Johnson72a40512013-12-19 10:14:15 -080012121 struct statsContext powerContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012122 long lrc;
c_hpothu5ab05e92014-06-13 17:34:05 +053012123 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012124
12125 ENTER();
12126
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053012127
Katya Nigame7b69a82015-04-28 15:24:06 +053012128 if (VOS_MONITOR_MODE == hdd_get_conparam())
12129 {
12130 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__);
12131 wlan_hdd_mon_close(pHddCtx);
Hanumantha Reddy Pothulac99bc062015-09-08 14:59:26 +053012132 goto free_hdd_ctx;
Katya Nigame7b69a82015-04-28 15:24:06 +053012133 }
12134 else if (VOS_FTM_MODE != hdd_get_conparam())
Jeff Johnson88ba7742013-02-27 14:36:02 -080012135 {
12136 // Unloading, restart logic is no more required.
12137 wlan_hdd_restart_deinit(pHddCtx);
Jeff Johnsone7245742012-09-05 17:12:55 -070012138
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012139#ifdef FEATURE_WLAN_TDLS
12140 /* At the time of driver unloading; if tdls connection is present;
12141 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer.
12142 * wlan_hdd_tdls_find_peer always checks for valid context;
12143 * as load/unload in progress there can be a race condition.
12144 * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only
12145 * when tdls state is enabled.
12146 * As soon as driver set load/unload flag; tdls flag also needs
12147 * to be disabled so that hdd_rx_packet_cbk won't call
12148 * wlan_hdd_tdls_find_peer.
12149 */
Masti, Narayanraddi20494af2015-12-17 20:56:42 +053012150 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE,
12151 HDD_SET_TDLS_MODE_SOURCE_USER);
Agarwal Ashishb20e0ff2014-12-17 22:50:19 +053012152#endif
12153
c_hpothu5ab05e92014-06-13 17:34:05 +053012154 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12155 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
Jeff Johnson295189b2012-06-20 16:38:30 -070012156 {
c_hpothu5ab05e92014-06-13 17:34:05 +053012157 pAdapter = pAdapterNode->pAdapter;
12158 if (NULL != pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 {
Mahesh A Saptasagar305e2632015-03-04 12:57:33 +053012160 /* Disable TX on the interface, after this hard_start_xmit() will
12161 * not be called on that interface
12162 */
12163 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
12164 netif_tx_disable(pAdapter->dev);
12165
12166 /* Mark the interface status as "down" for outside world */
12167 netif_carrier_off(pAdapter->dev);
12168
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012169 /* DeInit the adapter. This ensures that all data packets
12170 * are freed.
12171 */
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012172#ifdef FEATURE_WLAN_TDLS
12173 mutex_lock(&pHddCtx->tdls_lock);
12174#endif
c_hpothu002231a2015-02-05 14:58:51 +053012175 hdd_deinit_adapter(pHddCtx, pAdapter, FALSE);
Mahesh A Saptasagar02e36e82015-01-14 20:39:19 +053012176#ifdef FEATURE_WLAN_TDLS
12177 mutex_unlock(&pHddCtx->tdls_lock);
12178#endif
Masti, Narayanraddi26378462016-01-05 18:20:28 +053012179 vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work);
12180
12181 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +053012182
c_hpothu5ab05e92014-06-13 17:34:05 +053012183 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012184 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
12185 WLAN_HDD_MONITOR == pAdapter->device_mode)
c_hpothu5ab05e92014-06-13 17:34:05 +053012186 {
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012187 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12188 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
12189 wlan_hdd_cfg80211_deregister_frames(pAdapter);
12190
c_hpothu5ab05e92014-06-13 17:34:05 +053012191 hdd_UnregisterWext(pAdapter->dev);
12192 }
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012193
Jeff Johnson295189b2012-06-20 16:38:30 -070012194 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012195 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12196 pAdapterNode = pNext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012197 }
mukul sharmabab477d2015-06-11 17:14:55 +053012198
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012199 // Cancel any outstanding scan requests. We are about to close all
12200 // of our adapters, but an adapter structure is what SME passes back
12201 // to our callback function. Hence if there are any outstanding scan
12202 // requests then there is a race condition between when the adapter
12203 // is closed and when the callback is invoked.We try to resolve that
12204 // race condition here by canceling any outstanding scans before we
12205 // close the adapters.
12206 // Note that the scans may be cancelled in an asynchronous manner,
12207 // so ideally there needs to be some kind of synchronization. Rather
12208 // than introduce a new synchronization here, we will utilize the
12209 // fact that we are about to Request Full Power, and since that is
12210 // synchronized, the expectation is that by the time Request Full
12211 // Power has completed all scans will be cancelled.
12212 if (pHddCtx->scan_info.mScanPending)
12213 {
Hema Aparna Medicharlaf05f6cd2015-01-21 14:44:19 +053012214 if(NULL != pAdapter)
12215 {
12216 hddLog(VOS_TRACE_LEVEL_INFO,
12217 FL("abort scan mode: %d sessionId: %d"),
12218 pAdapter->device_mode,
12219 pAdapter->sessionId);
12220 }
12221 hdd_abort_mac_scan(pHddCtx,
12222 pHddCtx->scan_info.sessionId,
12223 eCSR_SCAN_ABORT_DEFAULT);
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012224 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012225 }
c_hpothu5ab05e92014-06-13 17:34:05 +053012226 else
Jeff Johnson88ba7742013-02-27 14:36:02 -080012227 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012228 hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__);
Hanumantha Reddy Pothula45af96b2015-02-12 16:07:58 +053012229 if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING)
12230 {
12231 INIT_COMPLETION(pHddCtx->ftm.startCmpVar);
12232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12233 "%s: in middle of FTM START", __func__);
12234 lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar,
12235 msecs_to_jiffies(20000));
12236 if(!lrc)
12237 {
12238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12239 "%s: timedout on ftmStartCmpVar fatal error", __func__);
12240 }
12241 }
Jeff Johnson88ba7742013-02-27 14:36:02 -080012242 wlan_hdd_ftm_close(pHddCtx);
12243 goto free_hdd_ctx;
12244 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012245
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 /* DeRegister with platform driver as client for Suspend/Resume */
12247 vosStatus = hddDeregisterPmOps(pHddCtx);
12248 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12249 {
12250 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__);
12251 VOS_ASSERT(0);
12252 }
12253
12254 vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx);
12255 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
12256 {
12257 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__);
12258 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012259
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012260 //Stop the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012261 if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING ==
12262 vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012263 {
12264 vos_timer_stop(&pHddCtx->tx_rx_trafficTmr);
12265 }
12266
12267 // Destroy the traffic monitor timer
Mahesh A Saptasagard461e432016-07-20 15:01:40 +053012268 if ((pHddCtx->cfg_ini->dynSplitscan) &&
12269 (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12270 &pHddCtx->tx_rx_trafficTmr))))
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070012271 {
12272 hddLog(VOS_TRACE_LEVEL_ERROR,
12273 "%s: Cannot deallocate Traffic monitor timer", __func__);
12274 }
12275
Bhargav Shahd0715912015-10-01 18:17:37 +053012276 if (VOS_TIMER_STATE_RUNNING ==
12277 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
12278 vos_timer_stop(&pHddCtx->delack_timer);
12279 }
12280
12281 if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(
12282 &pHddCtx->delack_timer))) {
12283 hddLog(VOS_TRACE_LEVEL_ERROR,
12284 "%s: Cannot deallocate Bus bandwidth timer", __func__);
12285 }
12286
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012287 if (VOS_TIMER_STATE_RUNNING ==
12288 vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) {
12289 vos_timer_stop(&pHddCtx->tdls_source_timer);
12290 }
12291
Abhishek Singh8a3e4dc2017-01-02 10:39:18 +053012292 vos_set_snoc_high_freq_voting(false);
12293
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053012294 vos_timer_destroy(&pHddCtx->tdls_source_timer);
12295
Jeff Johnson295189b2012-06-20 16:38:30 -070012296 //Disable IMPS/BMPS as we do not want the device to enter any power
12297 //save mode during shutdown
12298 sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE);
12299 sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE);
12300 sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE);
12301
12302 //Ensure that device is in full power as we will touch H/W during vos_Stop
12303 init_completion(&powerContext.completion);
12304 powerContext.magic = POWER_CONTEXT_MAGIC;
12305
12306 halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback,
12307 &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD);
12308
12309 if (eHAL_STATUS_SUCCESS != halStatus)
12310 {
12311 if (eHAL_STATUS_PMC_PENDING == halStatus)
12312 {
12313 /* request was sent -- wait for the response */
12314 lrc = wait_for_completion_interruptible_timeout(
12315 &powerContext.completion,
12316 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
Jeff Johnson295189b2012-06-20 16:38:30 -070012317 if (lrc <= 0)
12318 {
12319 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012320 __func__, (0 == lrc) ? "timeout" : "interrupt");
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 }
12322 }
12323 else
12324 {
12325 hddLog(VOS_TRACE_LEVEL_ERROR,
12326 "%s: Request for Full Power failed, status %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012327 __func__, halStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -070012328 /* continue -- need to clean up as much as possible */
12329 }
12330 }
Hanumantha Reddy Pothula81b42b22015-05-12 13:52:00 +053012331 if ((eHAL_STATUS_SUCCESS == halStatus) ||
12332 (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0))
12333 {
12334 /* This will issue a dump command which will clean up
12335 BTQM queues and unblock MC thread */
12336 vos_fwDumpReq(274, 0, 0, 0, 0, 1);
12337 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012338
Jeff Johnson72a40512013-12-19 10:14:15 -080012339 /* either we never sent a request, we sent a request and received a
12340 response or we sent a request and timed out. if we never sent a
12341 request or if we sent a request and got a response, we want to
12342 clear the magic out of paranoia. if we timed out there is a
12343 race condition such that the callback function could be
12344 executing at the same time we are. of primary concern is if the
12345 callback function had already verified the "magic" but had not
12346 yet set the completion variable when a timeout occurred. we
12347 serialize these activities by invalidating the magic while
12348 holding a shared spinlock which will cause us to block if the
12349 callback is currently executing */
12350 spin_lock(&hdd_context_lock);
12351 powerContext.magic = 0;
12352 spin_unlock(&hdd_context_lock);
12353
Hema Aparna Medicharlaa6cf65e2015-06-01 16:23:28 +053012354 /* If Device is shutdown, no point for SME to wait for responses
12355 from device. Pre Close SME */
12356 if(wcnss_device_is_shutdown())
12357 {
12358 sme_PreClose(pHddCtx->hHal);
12359 }
Yue Ma0d4891e2013-08-06 17:01:45 -070012360 hdd_debugfs_exit(pHddCtx);
12361
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012362#ifdef WLAN_NS_OFFLOAD
Ratheesh S P36dbc932015-08-07 14:28:57 +053012363 hddLog(LOG1, FL("Unregister IPv6 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012364 unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier);
12365#endif
Ratheesh S P36dbc932015-08-07 14:28:57 +053012366 hddLog(LOG1, FL("Unregister IPv4 notifier"));
Ratheesh S P35ed8b12015-04-27 14:01:07 +053012367 unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier);
12368
Jeff Johnson295189b2012-06-20 16:38:30 -070012369 // Unregister the Net Device Notifier
12370 unregister_netdevice_notifier(&hdd_netdev_notifier);
12371
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 hdd_stop_all_adapters( pHddCtx );
12373
Jeff Johnson295189b2012-06-20 16:38:30 -070012374#ifdef WLAN_BTAMP_FEATURE
12375 vosStatus = WLANBAP_Stop(pVosContext);
12376 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12377 {
12378 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12379 "%s: Failed to stop BAP",__func__);
12380 }
12381#endif //WLAN_BTAMP_FEATURE
12382
12383 //Stop all the modules
12384 vosStatus = vos_stop( pVosContext );
12385 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12386 {
12387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12388 "%s: Failed to stop VOSS",__func__);
12389 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053012390 if (isSsrPanicOnFailure())
12391 VOS_BUG(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012392 }
12393
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 //This requires pMac access, Call this before vos_close().
Jeff Johnson295189b2012-06-20 16:38:30 -070012395 hdd_unregister_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012396
12397 //Close the scheduler before calling vos_close to make sure no thread is
12398 // scheduled after the each module close is called i.e after all the data
12399 // structures are freed.
12400 vosStatus = vos_sched_close( pVosContext );
12401 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
12402 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
12403 "%s: Failed to close VOSS Scheduler",__func__);
12404 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12405 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012406#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
12407 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012408 vos_wake_lock_destroy(&pHddCtx->rx_wake_lock);
Jeff Johnsone7245742012-09-05 17:12:55 -070012409#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080012410 /* Destroy the wake lock */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012411 vos_wake_lock_destroy(&pHddCtx->sap_wake_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070012412
Mihir Shete7a24b5f2013-12-21 12:18:31 +053012413#ifdef CONFIG_ENABLE_LINUX_REG
12414 vosStatus = vos_nv_close();
12415 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
12416 {
12417 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
12418 "%s: Failed to close NV", __func__);
12419 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
12420 }
12421#endif
12422
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 //Close VOSS
12424 //This frees pMac(HAL) context. There should not be any call that requires pMac access after this.
12425 vos_close(pVosContext);
12426
Jeff Johnson295189b2012-06-20 16:38:30 -070012427 //Close Watchdog
12428 if(pHddCtx->cfg_ini->fIsLogpEnabled)
12429 vos_watchdog_close(pVosContext);
12430
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012431 //Clean up HDD Nlink Service
12432 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
Gopichand Nakkalaa0358482013-06-12 17:05:47 +053012433
Manjeet Singh47ee8472016-04-11 11:57:18 +053012434 hdd_close_tx_queues(pHddCtx);
c_manjeecfd1efb2015-09-25 19:32:34 +053012435 wlan_free_fwr_mem_dump_buffer();
12436 memdump_deinit();
12437
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012438#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053012439 if (pHddCtx->cfg_ini->wlanLoggingEnable)
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053012440 {
12441 wlan_logging_sock_deactivate_svc();
12442 }
12443#endif
12444
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012445#ifdef WLAN_KD_READY_NOTIFIER
12446 nl_srv_exit(pHddCtx->ptt_pid);
12447#else
12448 nl_srv_exit();
12449#endif /* WLAN_KD_READY_NOTIFIER */
12450
Abhishek Singh00b71972016-01-07 10:51:04 +053012451#ifdef WLAN_FEATURE_RMC
12452 hdd_close_cesium_nl_sock();
12453#endif /* WLAN_FEATURE_RMC */
Vinay Krishna Erannaef30b522014-08-26 17:48:16 +053012454
Jeff Johnson295189b2012-06-20 16:38:30 -070012455 hdd_close_all_adapters( pHddCtx );
12456
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012457 vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work);
Abhishek Singh78c691f2017-11-30 13:48:44 +053012458 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Kapil Gupta137ef892016-12-13 19:38:00 +053012459 vos_flush_work(&pHddCtx->sap_start_work);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053012460
Hanumantha Reddy Pothula97f9bc92015-08-10 17:21:20 +053012461free_hdd_ctx:
Jeff Johnson295189b2012-06-20 16:38:30 -070012462 /* free the power on lock from platform driver */
12463 if (free_riva_power_on_lock("wlan"))
12464 {
12465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock",
12466 __func__);
12467 }
12468
c_hpothu78c7b602014-05-17 17:35:49 +053012469 //Free up dynamically allocated members inside HDD Adapter
12470 if (pHddCtx->cfg_ini)
12471 {
12472 kfree(pHddCtx->cfg_ini);
12473 pHddCtx->cfg_ini= NULL;
12474 }
12475
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053012476 hdd_request_manager_deinit();
12477
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012478 /* FTM/MONITOR mode, WIPHY did not registered
Leo Changf04ddad2013-09-18 13:46:38 -070012479 If un-register here, system crash will happen */
Hanumantha Reddy Pothula6fe221c2016-01-28 15:01:09 +053012480 if (!(VOS_FTM_MODE == hdd_get_conparam() ||
12481 VOS_MONITOR_MODE == hdd_get_conparam()))
Leo Changf04ddad2013-09-18 13:46:38 -070012482 {
12483 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053012484 hdd_wlan_free_wiphy_channels(wiphy);
Leo Changf04ddad2013-09-18 13:46:38 -070012485 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012486 wiphy_free(wiphy) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070012487 if (hdd_is_ssr_required())
12488 {
12489 /* WDI timeout had happened during unload, so SSR is needed here */
Madan Mohan Koyyalamudi3246f5b2012-10-15 15:40:02 -070012490 subsystem_restart("wcnss");
Jeff Johnson295189b2012-06-20 16:38:30 -070012491 msleep(5000);
12492 }
12493 hdd_set_ssr_required (VOS_FALSE);
12494}
12495
12496
12497/**---------------------------------------------------------------------------
12498
12499 \brief hdd_update_config_from_nv() - Function to update the contents of
12500 the running configuration with parameters taken from NV storage
12501
12502 \param - pHddCtx - Pointer to the HDD global context
12503
12504 \return - VOS_STATUS_SUCCESS if successful
12505
12506 --------------------------------------------------------------------------*/
12507static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx)
12508{
Jeff Johnson295189b2012-06-20 16:38:30 -070012509 v_BOOL_t itemIsValid = VOS_FALSE;
12510 VOS_STATUS status;
12511 v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA];
12512 v_U8_t macLoop;
12513
12514 /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/
12515 status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid);
12516 if(status != VOS_STATUS_SUCCESS)
12517 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012518 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012519 return VOS_STATUS_E_FAILURE;
12520 }
12521
12522 if (itemIsValid == VOS_TRUE)
12523 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012524 hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV");
Jeff Johnson295189b2012-06-20 16:38:30 -070012525 status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0],
12526 VOS_MAX_CONCURRENCY_PERSONA);
12527 if(status != VOS_STATUS_SUCCESS)
12528 {
12529 /* Get MAC from NV fail, not update CFG info
12530 * INI MAC value will be used for MAC setting */
Arif Hussain6d2a3322013-11-17 19:50:10 -080012531 hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed");
Jeff Johnson295189b2012-06-20 16:38:30 -070012532 return VOS_STATUS_E_FAILURE;
12533 }
12534
12535 /* If first MAC is not valid, treat all others are not valid
12536 * Then all MACs will be got from ini file */
12537 if(vos_is_macaddr_zero(&macFromNV[0]))
12538 {
12539 /* MAC address in NV file is not configured yet */
12540 hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file");
12541 return VOS_STATUS_E_INVAL;
12542 }
12543
12544 /* Get MAC address from NV, update CFG info */
12545 for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++)
12546 {
12547 if(vos_is_macaddr_zero(&macFromNV[macLoop]))
12548 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012549 hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop);
Jeff Johnson295189b2012-06-20 16:38:30 -070012550 /* This MAC is not valid, skip it
12551 * This MAC will be got from ini file */
12552 }
12553 else
12554 {
12555 vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0],
12556 (v_U8_t *)&macFromNV[macLoop].bytes[0],
12557 VOS_MAC_ADDR_SIZE);
12558 }
12559 }
12560 }
12561 else
12562 {
12563 hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid");
12564 return VOS_STATUS_E_FAILURE;
12565 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012566
Jeff Johnson295189b2012-06-20 16:38:30 -070012567
12568 return VOS_STATUS_SUCCESS;
12569}
12570
12571/**---------------------------------------------------------------------------
12572
12573 \brief hdd_post_voss_start_config() - HDD post voss start config helper
12574
12575 \param - pAdapter - Pointer to the HDD
12576
12577 \return - None
12578
12579 --------------------------------------------------------------------------*/
12580VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx)
12581{
12582 eHalStatus halStatus;
12583 v_U32_t listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012584 tANI_U32 ignoreDtim;
Jeff Johnson295189b2012-06-20 16:38:30 -070012585
Jeff Johnson295189b2012-06-20 16:38:30 -070012586
12587 // Send ready indication to the HDD. This will kick off the MAC
12588 // into a 'running' state and should kick off an initial scan.
12589 halStatus = sme_HDDReadyInd( pHddCtx->hHal );
12590 if ( !HAL_STATUS_SUCCESS( halStatus ) )
12591 {
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053012592 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status "
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 "code %08d [x%08x]",__func__, halStatus, halStatus );
12594 return VOS_STATUS_E_FAILURE;
12595 }
12596
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012597 // Set default LI and ignoreDtim into HDD context,
Jeff Johnson295189b2012-06-20 16:38:30 -070012598 // otherwise under some race condition, HDD will set 0 LI value into RIVA,
12599 // And RIVA will crash
12600 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval);
12601 pHddCtx->hdd_actual_LI_value = listenInterval;
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012602 wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim);
12603 pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim;
12604
12605
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 return VOS_STATUS_SUCCESS;
12607}
12608
Jeff Johnson295189b2012-06-20 16:38:30 -070012609/* wake lock APIs for HDD */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012610void hdd_prevent_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012611{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012612
12613 vos_wake_lock_acquire(&wlan_wake_lock, reason);
12614
Jeff Johnson295189b2012-06-20 16:38:30 -070012615}
12616
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012617void hdd_allow_suspend(uint32_t reason)
Jeff Johnson295189b2012-06-20 16:38:30 -070012618{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012619
12620 vos_wake_lock_release(&wlan_wake_lock, reason);
12621
Jeff Johnson295189b2012-06-20 16:38:30 -070012622}
12623
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012624void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason)
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012625{
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012626
12627 vos_wake_lock_timeout_release(&wlan_wake_lock, timeout,
12628 reason);
12629
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012630}
12631
Jeff Johnson295189b2012-06-20 16:38:30 -070012632/**---------------------------------------------------------------------------
12633
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012634 \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability
12635 information between Host and Riva
12636
12637 This function gets reported version of FW
12638 It also finds the version of Riva headers used to compile the host
12639 It compares the above two and prints a warning if they are different
12640 It gets the SW and HW version string
12641 Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg
12642 indicating the features they support through a bitmap
12643
12644 \param - pHddCtx - Pointer to HDD context
12645
12646 \return - void
12647
12648 --------------------------------------------------------------------------*/
12649
12650void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx)
12651{
12652
12653 tSirVersionType versionCompiled;
12654 tSirVersionType versionReported;
12655 tSirVersionString versionString;
12656 tANI_U8 fwFeatCapsMsgSupported = 0;
12657 VOS_STATUS vstatus;
12658
Mingcheng Zhu87f22fc2014-01-30 19:23:32 -080012659 memset(&versionCompiled, 0, sizeof(versionCompiled));
12660 memset(&versionReported, 0, sizeof(versionReported));
12661
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012662 /* retrieve and display WCNSS version information */
12663 do {
12664
12665 vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal,
12666 &versionCompiled);
12667 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12668 {
12669 hddLog(VOS_TRACE_LEVEL_FATAL,
12670 "%s: unable to retrieve WCNSS WLAN compiled version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012671 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012672 break;
12673 }
12674
12675 vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal,
12676 &versionReported);
12677 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12678 {
12679 hddLog(VOS_TRACE_LEVEL_FATAL,
12680 "%s: unable to retrieve WCNSS WLAN reported version",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012681 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012682 break;
12683 }
12684
12685 if ((versionCompiled.major != versionReported.major) ||
12686 (versionCompiled.minor != versionReported.minor) ||
12687 (versionCompiled.version != versionReported.version) ||
12688 (versionCompiled.revision != versionReported.revision))
12689 {
12690 pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, "
12691 "Host expected %u.%u.%u.%u\n",
12692 WLAN_MODULE_NAME,
12693 (int)versionReported.major,
12694 (int)versionReported.minor,
12695 (int)versionReported.version,
12696 (int)versionReported.revision,
12697 (int)versionCompiled.major,
12698 (int)versionCompiled.minor,
12699 (int)versionCompiled.version,
12700 (int)versionCompiled.revision);
12701 }
12702 else
12703 {
12704 pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n",
12705 WLAN_MODULE_NAME,
12706 (int)versionReported.major,
12707 (int)versionReported.minor,
12708 (int)versionReported.version,
12709 (int)versionReported.revision);
12710 }
12711
12712 vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal,
12713 versionString,
12714 sizeof(versionString));
12715 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12716 {
12717 hddLog(VOS_TRACE_LEVEL_FATAL,
12718 "%s: unable to retrieve WCNSS software version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012719 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012720 break;
12721 }
12722
12723 pr_info("%s: WCNSS software version %s\n",
12724 WLAN_MODULE_NAME, versionString);
Sushant Kaushik084f6592015-09-10 13:11:56 +053012725 vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString));
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012726
12727 vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal,
12728 versionString,
12729 sizeof(versionString));
12730 if (!VOS_IS_STATUS_SUCCESS(vstatus))
12731 {
12732 hddLog(VOS_TRACE_LEVEL_FATAL,
12733 "%s: unable to retrieve WCNSS hardware version string",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012734 __func__);
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012735 break;
12736 }
12737
12738 pr_info("%s: WCNSS hardware version %s\n",
12739 WLAN_MODULE_NAME, versionString);
12740
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012741 /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message
12742 2.Host-FW capability exchange message is only present on riva 1.1 so
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012743 send the message only if it the riva is 1.1
12744 minor numbers for different riva branches:
12745 0 -> (1.0)Mainline Build
12746 1 -> (1.1)Mainline Build
12747 2->(1.04) Stability Build
12748 */
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012749 if (((versionReported.major>0) || (versionReported.minor>1) ||
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012750 ((versionReported.minor>=1) && (versionReported.version>=1)))
12751 && ((versionReported.major == 1) && (versionReported.minor >= 1)))
12752 fwFeatCapsMsgSupported = 1;
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070012753
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012754 if (fwFeatCapsMsgSupported)
Yathish9f22e662012-12-10 14:21:35 -080012755 {
12756#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
12757 if(!pHddCtx->cfg_ini->fEnableActiveModeOffload)
12758 sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD);
12759#endif
Ravi Joshid2ca7c42013-07-23 08:37:49 -070012760 /* Indicate if IBSS heartbeat monitoring needs to be offloaded */
12761 if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload)
12762 {
12763 sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD);
12764 }
12765
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012766 sme_featureCapsExchange(pHddCtx->hHal);
Yathish9f22e662012-12-10 14:21:35 -080012767 }
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012768
12769 } while (0);
12770
12771}
Neelansh Mittaledafed22014-09-04 18:54:39 +053012772void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len)
12773{
12774 struct sk_buff *skb;
12775 struct nlmsghdr *nlh;
12776 tAniMsgHdr *ani_hdr;
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012777 int flags = GFP_KERNEL;
Bhargav shah23c94942015-10-13 12:48:35 +053012778 void *nl_data = NULL;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012779
Hanumantha Reddy Pothulacf2c7ea2015-04-27 14:50:47 +053012780 if (in_interrupt() || irqs_disabled() || in_atomic())
12781 flags = GFP_ATOMIC;
12782
12783 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
Neelansh Mittaledafed22014-09-04 18:54:39 +053012784
12785 if(skb == NULL) {
12786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12787 "%s: alloc_skb failed", __func__);
12788 return;
12789 }
12790
12791 nlh = (struct nlmsghdr *)skb->data;
12792 nlh->nlmsg_pid = 0; /* from kernel */
12793 nlh->nlmsg_flags = 0;
12794 nlh->nlmsg_seq = 0;
12795 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12796
12797 ani_hdr = NLMSG_DATA(nlh);
12798 ani_hdr->type = type;
12799
12800 switch(type) {
12801 case WLAN_SVC_SAP_RESTART_IND:
12802 ani_hdr->length = 0;
12803 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
12804 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr)));
12805 break;
Bhargav Shahd0715912015-10-01 18:17:37 +053012806 case WLAN_SVC_WLAN_TP_IND:
12807 ani_hdr->length = len;
12808 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)
12809 + len));
12810 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12811 memcpy(nl_data, data, len);
12812 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12813 break;
Bhargav shah23c94942015-10-13 12:48:35 +053012814 case WLAN_MSG_RPS_ENABLE_IND:
12815 ani_hdr->length = len;
12816 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12817 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12818 memcpy(nl_data, data, len);
12819 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len));
12820 break;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012821 default:
12822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12823 "Attempt to send unknown nlink message %d", type);
12824 kfree_skb(skb);
12825 return;
12826 }
12827
12828 nl_srv_bcast(skb);
12829
12830 return;
12831}
12832
Bhargav Shahd0715912015-10-01 18:17:37 +053012833/**
12834 * hdd_request_tcp_delack() - Find the Delack value based on RX packet
12835 * @pHddCtx: Valid Global HDD context pointer
12836 * @rx_packets: Number of RX packet in perticular time
12837 *
12838 * Based on the RX packet this function calculate next value of tcp delack.
12839 * This function compare rx packet value to high and low threshold limit.
12840 *
12841 * Return: void
12842 */
12843void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets)
12844{
12845 /* average of rx_packets and prev_rx is taken so that
12846 bus width doesnot fluctuate much */
12847 uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2;
12848 TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level;
Neelansh Mittaledafed22014-09-04 18:54:39 +053012849
Bhargav Shahd0715912015-10-01 18:17:37 +053012850 pHddCtx->prev_rx = rx_packets;
12851 if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh)
12852 next_rx_level = TP_IND_HIGH;
12853 else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow)
12854 next_rx_level = TP_IND_LOW;
12855
12856 hdd_set_delack_value(pHddCtx, next_rx_level);
12857}
12858
12859#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x)))
12860
12861/**
12862 * hdd_tcp_delack_compute_function() - get link status
12863 * @priv: Valid Global HDD context pointer
12864 *
12865 * This function find number of RX packet during timer life span.
12866 * It request tcp delack with number of RX packet and re-configure delack timer
12867 * for tcpDelAckComputeInterval timer interval.
12868 *
12869 * Return: void
12870 */
12871void hdd_tcp_delack_compute_function(void *priv)
12872{
12873 hdd_context_t *pHddCtx = (hdd_context_t *)priv;
12874 hdd_adapter_t *pAdapter = NULL;
12875 v_U32_t rx_packets = 0;
12876 hdd_adapter_list_node_t *pAdapterNode = NULL;
12877 VOS_STATUS status = 0;
12878
12879 for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12880 NULL != pAdapterNode && VOS_STATUS_SUCCESS == status;
12881 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) {
12882 if ((pAdapter = pAdapterNode->pAdapter) == NULL)
12883 continue;
12884
12885 rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets,
12886 pAdapter->prev_rx_packets);
12887 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
12888 }
12889
12890 hdd_request_tcp_delack(pHddCtx, rx_packets);
12891
12892 vos_timer_start(&pHddCtx->delack_timer,
12893 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
12894}
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070012895
12896/**---------------------------------------------------------------------------
12897
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012898 \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz
12899
12900 \param - pHddCtx - Pointer to the hdd context
12901
12902 \return - true if hardware supports 5GHz
12903
12904 --------------------------------------------------------------------------*/
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +053012905boolean hdd_is_5g_supported(hdd_context_t * pHddCtx)
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012906{
12907 /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1);
12908 * then hardware support 5Ghz.
12909 */
12910 if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode())
12911 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012912 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012913 return true;
12914 }
12915 else
12916 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012917 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz",
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012918 __func__);
12919 return false;
12920 }
12921}
12922
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012923/**---------------------------------------------------------------------------
12924
12925 \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto
12926 generate function
12927
12928 This is generate the random mac address for WLAN interface
12929
12930 \param - pHddCtx - Pointer to HDD context
12931 idx - Start interface index to get auto
12932 generated mac addr.
12933 mac_addr - Mac address
12934
12935 \return - 0 for success, < 0 for failure
12936
12937 --------------------------------------------------------------------------*/
12938
12939static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx,
12940 int idx, v_MACADDR_t mac_addr)
12941{
12942 int i;
12943 unsigned int serialno;
12944 serialno = wcnss_get_serial_number();
12945
12946 if (0 != serialno)
12947 {
12948 /* MAC address has 3 bytes of OUI so we have a maximum of 3
12949 bytes of the serial number that can be used to generate
12950 the other 3 bytes of the MAC address. Mask off all but
12951 the lower 3 bytes (this will also make sure we don't
12952 overflow in the next step) */
12953 serialno &= 0x00FFFFFF;
12954
12955 /* we need a unique address for each session */
12956 serialno *= VOS_MAX_CONCURRENCY_PERSONA;
12957
12958 /* autogen other Mac addresses */
12959 for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++)
12960 {
12961 /* start with the entire default address */
12962 pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr;
12963 /* then replace the lower 3 bytes */
12964 pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF;
12965 pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF;
12966 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF;
12967
Nachiket Kukadede2e24f2017-09-25 16:24:27 +053012968 if (0 == memcmp(&pHddCtx->cfg_ini->intfMacAddr[i].bytes[0],
12969 &mac_addr.bytes[0], VOS_MAC_ADDR_SIZE))
12970 pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] +=
12971 VOS_MAX_CONCURRENCY_PERSONA;
12972
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053012973 serialno++;
12974 hddLog(VOS_TRACE_LEVEL_ERROR,
12975 "%s: Derived Mac Addr: "
12976 MAC_ADDRESS_STR, __func__,
12977 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes));
12978 }
12979
12980 }
12981 else
12982 {
12983 hddLog(LOGE, FL("Failed to Get Serial NO"));
12984 return -1;
12985 }
12986 return 0;
12987}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053012988
Katya Nigame7b69a82015-04-28 15:24:06 +053012989int wlan_hdd_mon_open(hdd_context_t *pHddCtx)
12990{
12991 VOS_STATUS status;
12992 v_CONTEXT_t pVosContext= NULL;
12993 hdd_adapter_t *pAdapter= NULL;
12994
12995 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
12996
12997 if (NULL == pVosContext)
12998 {
12999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13000 "%s: Trying to open VOSS without a PreOpen", __func__);
13001 VOS_ASSERT(0);
13002 return VOS_STATUS_E_FAILURE;
13003 }
13004
13005 status = vos_nv_open();
13006 if (!VOS_IS_STATUS_SUCCESS(status))
13007 {
13008 /* NV module cannot be initialized */
13009 hddLog( VOS_TRACE_LEVEL_FATAL,
13010 "%s: vos_nv_open failed", __func__);
13011 return VOS_STATUS_E_FAILURE;
13012 }
13013
13014 status = vos_init_wiphy_from_nv_bin();
13015 if (!VOS_IS_STATUS_SUCCESS(status))
13016 {
13017 /* NV module cannot be initialized */
13018 hddLog( VOS_TRACE_LEVEL_FATAL,
13019 "%s: vos_init_wiphy failed", __func__);
13020 goto err_vos_nv_close;
13021 }
13022
13023 status = vos_open( &pVosContext, pHddCtx->parent_dev);
13024 if ( !VOS_IS_STATUS_SUCCESS( status ))
13025 {
13026 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
13027 goto err_vos_nv_close;
13028 }
13029
13030 status = vos_mon_start( pVosContext );
13031 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13032 {
13033 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
13034 goto err_vosclose;
13035 }
13036
13037 WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk );
13038 WDA_featureCapsExchange(pVosContext);
13039 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13040
13041 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d",
13042 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13043 if( pAdapter == NULL )
13044 {
13045 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13046 goto err_close_adapter;
13047 }
13048
13049 //Initialize the nlink service
13050 if(nl_srv_init() != 0)
13051 {
13052 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13053 goto err_close_adapter;
13054 }
13055 return VOS_STATUS_SUCCESS;
13056
13057err_close_adapter:
13058 hdd_close_all_adapters( pHddCtx );
13059 vos_mon_stop( pVosContext );
13060err_vosclose:
13061 status = vos_sched_close( pVosContext );
13062 if (!VOS_IS_STATUS_SUCCESS(status)) {
13063 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
13064 "%s: Failed to close VOSS Scheduler", __func__);
13065 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
13066 }
13067 vos_close(pVosContext );
13068
13069err_vos_nv_close:
13070 vos_nv_close();
13071
13072return status;
13073}
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013074/**---------------------------------------------------------------------------
13075
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013076 \brief hdd_11d_scan_done - callback to be executed when 11d scan is
13077 completed to flush out the scan results
13078
13079 11d scan is done during driver load and is a passive scan on all
13080 channels supported by the device, 11d scans may find some APs on
13081 frequencies which are forbidden to be used in the regulatory domain
13082 the device is operating in. If these APs are notified to the supplicant
13083 it may try to connect to these APs, thus flush out all the scan results
13084 which are present in SME after 11d scan is done.
13085
13086 \return - eHalStatus
13087
13088 --------------------------------------------------------------------------*/
13089static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext,
13090 tANI_U32 scanId, eCsrScanStatus status)
13091{
13092 ENTER();
13093
13094 sme_ScanFlushResult(halHandle, 0);
13095
13096 EXIT();
13097
13098 return eHAL_STATUS_SUCCESS;
13099}
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013100/**---------------------------------------------------------------------------
13101
13102 \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame
13103 logging is completed successfully.
13104
13105 \return - None
13106
13107 --------------------------------------------------------------------------*/
c_manjeecfd1efb2015-09-25 19:32:34 +053013108void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013109{
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013110 hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013111
13112 if (NULL == pHddCtx)
13113 {
13114 hddLog(VOS_TRACE_LEVEL_ERROR,
13115 "%s: HDD context is NULL",__func__);
13116 return;
13117 }
13118
c_manjeecfd1efb2015-09-25 19:32:34 +053013119 if ((pRsp->status == VOS_STATUS_SUCCESS) &&
Mahesh A Saptasagarfabb1a02015-06-29 12:17:04 +053013120 (TRUE == pHddCtx->cfg_ini->enableMgmtLogging))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013121 {
13122 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful"));
13123 pHddCtx->mgmt_frame_logging = TRUE;
13124 }
13125 else
13126 {
13127 hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success"));
13128 pHddCtx->mgmt_frame_logging = FALSE;
c_manjeecfd1efb2015-09-25 19:32:34 +053013129 return;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013130 }
13131
c_manjeecfd1efb2015-09-25 19:32:34 +053013132 /*Check feature supported by FW*/
13133 if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))
13134 {
13135 //Store fwr mem dump size given by firmware.
13136 wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size);
13137 }
13138 else
13139 {
13140 wlan_store_fwr_mem_dump_size(0);
13141 }
13142
13143
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013144}
13145/**---------------------------------------------------------------------------
13146
13147 \brief hdd_init_frame_logging - function to initialize frame logging.
13148 Currently only Mgmt Frames are logged in both TX
13149 and Rx direction and are sent to userspace
13150 application using logger thread when queried.
13151
13152 \return - None
13153
13154 --------------------------------------------------------------------------*/
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013155void hdd_init_frame_logging(hdd_context_t* pHddCtx)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013156{
13157 eHalStatus halStatus = eHAL_STATUS_FAILURE;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013158 tSirFWLoggingInitParam wlanFWLoggingInitParam = {0};
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013159
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013160 if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) &&
13161 TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT))
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013162 {
13163 hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW"));
13164 return;
13165 }
13166
c_manjeecfd1efb2015-09-25 19:32:34 +053013167 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__,
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013168 pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"",
13169 pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"",
c_manjeecfd1efb2015-09-25 19:32:34 +053013170 pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"",
13171 pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":"");
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013172
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013173 if (pHddCtx->cfg_ini->enableFWLogging ||
13174 pHddCtx->cfg_ini->enableContFWLogging)
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013175 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013176 wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013177 }
13178
Sushant Kaushik46804902015-07-08 14:46:03 +053013179 if (pHddCtx->cfg_ini->enableMgmtLogging)
13180 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013181 wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN;
Sushant Kaushik46804902015-07-08 14:46:03 +053013182 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013183 if (pHddCtx->cfg_ini->enableBMUHWtracing)
13184 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013185 wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013186 }
c_manjeecfd1efb2015-09-25 19:32:34 +053013187 if(pHddCtx->cfg_ini->enableFwrMemDump &&
13188 (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
13189 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013190 wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN;
c_manjeecfd1efb2015-09-25 19:32:34 +053013191 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013192 if( wlanFWLoggingInitParam.enableFlag == 0 )
c_manjeecfd1efb2015-09-25 19:32:34 +053013193 {
13194 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__);
13195 return;
13196 }
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013197 wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT;
13198 wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES;
13199 wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR;
13200 wlanFWLoggingInitParam.continuousFrameLogging =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013201 pHddCtx->cfg_ini->enableContFWLogging;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013202
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013203 wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013204
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013205 wlanFWLoggingInitParam.minLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013206 pHddCtx->cfg_ini->minLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013207 wlanFWLoggingInitParam.maxLogBufferSize =
Siddharth Bhald1be97f2015-05-27 22:39:59 +053013208 pHddCtx->cfg_ini->maxLoggingBufferSize;
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013209 wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done;
13210 wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx;
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013211
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013212 halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013213
13214 if (eHAL_STATUS_SUCCESS != halStatus)
13215 {
Sreelakshmi Konamkid8784d92016-04-14 14:59:13 +053013216 hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"),
13217 halStatus);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053013218 }
13219
13220 return;
13221}
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013222
Bhargav shah23c94942015-10-13 12:48:35 +053013223static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt)
13224{
13225 hdd_adapter_t *adapter;
13226 hdd_adapter_list_node_t *adapter_node, *next;
13227 VOS_STATUS status = VOS_STATUS_SUCCESS;
13228 struct wlan_rps_data rps_data;
13229 int count;
13230
13231 if(!hdd_ctxt->cfg_ini->rps_mask)
13232 {
13233 return;
13234 }
13235
13236 for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++)
13237 {
13238 rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask;
13239 }
13240
13241 rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES;
13242
13243 hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"),
13244 rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2],
13245 rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]);
13246
13247 status = hdd_get_front_adapter (hdd_ctxt, &adapter_node);
13248
13249 while (NULL != adapter_node && VOS_STATUS_SUCCESS == status)
13250 {
13251 adapter = adapter_node->pAdapter;
13252 if (NULL != adapter) {
13253 strlcpy(rps_data.ifname, adapter->dev->name,
13254 sizeof(rps_data.ifname));
13255 wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND,
13256 (void *)&rps_data,sizeof(rps_data));
13257 }
13258 status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next);
13259 adapter_node = next;
13260 }
13261}
13262
Masti, Narayanraddi26378462016-01-05 18:20:28 +053013263void wlan_hdd_schedule_defer_scan(struct work_struct *work)
13264{
13265 scan_context_t *scan_ctx =
13266 container_of(work, scan_context_t, scan_work.work);
13267
13268 if (NULL == scan_ctx)
13269 {
13270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13271 FL("scan_ctx is NULL"));
13272 return;
13273 }
13274
13275 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
13276 return;
13277
13278 scan_ctx->attempt++;
13279
13280 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
13281#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13282 scan_ctx->dev,
13283#endif
13284 scan_ctx->scan_request);
13285}
13286
13287int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx,
13288 struct wiphy *wiphy,
13289#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13290 struct net_device *dev,
13291#endif
13292 struct cfg80211_scan_request *request)
13293{
13294 scan_context_t *scan_ctx;
13295
13296 ENTER();
13297 if (0 != (wlan_hdd_validate_context(pHddCtx)))
13298 {
13299 return -1;
13300 }
13301
13302 scan_ctx = &pHddCtx->scan_ctxt;
13303
13304 scan_ctx->wiphy = wiphy;
13305#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13306 scan_ctx->dev = dev;
13307#endif
13308
13309 scan_ctx->scan_request = request;
13310
13311 EXIT();
13312 return 0;
13313}
13314
13315void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx,
13316 struct wiphy *wiphy,
13317#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13318 struct net_device *dev,
13319#endif
13320 struct cfg80211_scan_request *request,
13321 unsigned long delay)
13322{
13323 if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic)
13324 {
13325#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13326 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request);
13327#else
13328 wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request);
13329#endif
13330 pHddCtx->scan_ctxt.attempt = 0;
13331 pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC;
13332 }
13333 schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay);
13334}
13335
13336void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx)
13337{
13338 scan_ctx->magic = 0;
13339 scan_ctx->attempt = 0;
13340 scan_ctx->reject = 0;
13341 scan_ctx->scan_request = NULL;
13342
13343 return;
13344}
13345
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053013346/**---------------------------------------------------------------------------
13347
Jeff Johnson295189b2012-06-20 16:38:30 -070013348 \brief hdd_wlan_startup() - HDD init function
13349
13350 This is the driver startup code executed once a WLAN device has been detected
13351
13352 \param - dev - Pointer to the underlying device
13353
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013354 \return - 0 for success, < 0 for failure
Jeff Johnson295189b2012-06-20 16:38:30 -070013355
13356 --------------------------------------------------------------------------*/
13357
13358int hdd_wlan_startup(struct device *dev )
13359{
13360 VOS_STATUS status;
13361 hdd_adapter_t *pAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070013362 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013363 hdd_context_t *pHddCtx = NULL;
13364 v_CONTEXT_t pVosContext= NULL;
13365#ifdef WLAN_BTAMP_FEATURE
13366 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
13367 WLANBAP_ConfigType btAmpConfig;
13368 hdd_config_t *pConfig;
13369#endif
13370 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013371 struct wiphy *wiphy;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013372 v_MACADDR_t mac_addr;
Jeff Johnson295189b2012-06-20 16:38:30 -070013373
13374 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013375 /*
13376 * cfg80211: wiphy allocation
13377 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013378 wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070013379
13380 if(wiphy == NULL)
13381 {
13382 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013383 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013384 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013385 pHddCtx = wiphy_priv(wiphy);
13386
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 //Initialize the adapter context to zeros.
13388 vos_mem_zero(pHddCtx, sizeof( hdd_context_t ));
13389
Jeff Johnson295189b2012-06-20 16:38:30 -070013390 pHddCtx->wiphy = wiphy;
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013391 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Mihir Shete18156292014-03-11 15:38:30 +053013392 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070013393
13394 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
13395
Siddharth Bhalcd92b782015-06-29 12:25:40 +053013396 /* register for riva power on lock to platform driver
13397 * Locking power early to ensure FW doesn't reset by kernel while
13398 * host driver is busy initializing itself */
13399 if (req_riva_power_on_lock("wlan"))
13400 {
13401 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed",
13402 __func__);
13403 goto err_free_hdd_context;
13404 }
13405
Jeff Johnson295189b2012-06-20 16:38:30 -070013406 /*Get vos context here bcoz vos_open requires it*/
13407 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
13408
Madan Mohan Koyyalamudi0b78e152012-11-28 15:46:51 -080013409 if(pVosContext == NULL)
13410 {
13411 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__);
13412 goto err_free_hdd_context;
13413 }
13414
Jeff Johnson295189b2012-06-20 16:38:30 -070013415 //Save the Global VOSS context in adapter context for future.
13416 pHddCtx->pvosContext = pVosContext;
13417
13418 //Save the adapter context in global context for future.
13419 ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx;
13420
Jeff Johnson295189b2012-06-20 16:38:30 -070013421 pHddCtx->parent_dev = dev;
Sreelakshmi Konamkif0646d52016-12-09 12:35:31 +053013422 pHddCtx->last_scan_reject_session_id = 0xFF;
13423 pHddCtx->last_scan_reject_reason = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053013424 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053013425 pHddCtx->scan_reject_cnt = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013426
13427 init_completion(&pHddCtx->full_pwr_comp_var);
13428 init_completion(&pHddCtx->standby_comp_var);
13429 init_completion(&pHddCtx->req_bmps_comp_var);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070013430 init_completion(&pHddCtx->scan_info.scan_req_completion_event);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080013431 init_completion(&pHddCtx->scan_info.abortscan_event_var);
Kiet Lam46b8e4e2013-11-06 21:49:53 +053013432 init_completion(&pHddCtx->wiphy_channel_update_event);
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053013433 init_completion(&pHddCtx->ssr_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053013434 init_completion(&pHddCtx->mc_sus_event_var);
13435 init_completion(&pHddCtx->tx_sus_event_var);
13436 init_completion(&pHddCtx->rx_sus_event_var);
13437
Amar Singhala49cbc52013-10-08 18:37:44 -070013438
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013439 hdd_init_ll_stats_ctx(pHddCtx);
Anurag Chouhan6ee81542017-02-09 18:09:27 +053013440 hdd_init_nud_stats_ctx(pHddCtx);
mukul sharma4bd8d2e2015-08-13 20:33:25 +053013441
Amar Singhala49cbc52013-10-08 18:37:44 -070013442#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhalfddc28c2013-09-05 13:03:40 -070013443 init_completion(&pHddCtx->linux_reg_req);
Amar Singhala49cbc52013-10-08 18:37:44 -070013444#else
13445 init_completion(&pHddCtx->driver_crda_req);
13446#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013447
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +053013448#ifdef WLAN_FEATURE_EXTSCAN
13449 init_completion(&pHddCtx->ext_scan_context.response_event);
13450#endif /* WLAN_FEATURE_EXTSCAN */
13451
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013452 spin_lock_init(&pHddCtx->schedScan_lock);
Kapil Gupta137ef892016-12-13 19:38:00 +053013453 vos_spin_lock_init(&pHddCtx->sap_update_info_lock);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013454
Jeff Johnson295189b2012-06-20 16:38:30 -070013455 hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS );
13456
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013457 vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work,
13458 hdd_processSpoofMacAddrRequest);
Kapil Gupta137ef892016-12-13 19:38:00 +053013459 vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle);
Abhishek Singh78c691f2017-11-30 13:48:44 +053013460 vos_init_delayed_work(&pHddCtx->ecsa_chan_change_work,
13461 hdd_force_scc_with_ecsa_handle);
Padma, Santhosh Kumar9cd38332015-11-17 12:18:10 +053013462
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013463#ifdef FEATURE_WLAN_TDLS
13464 /* tdls_lock is initialized before an hdd_open_adapter ( which is
13465 * invoked by other instances also) to protect the concurrent
13466 * access for the Adapters by TDLS module.
13467 */
13468 mutex_init(&pHddCtx->tdls_lock);
13469#endif
Siddharth Bhal76972212014-10-15 16:22:51 +053013470 mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock);
Mukul Sharma1fd6efd2015-02-14 00:29:14 +053013471 mutex_init(&pHddCtx->wmmLock);
13472
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +053013473 hdd_init_offloaded_packets_ctx(pHddCtx);
Agarwal Ashish1f422872014-07-22 00:11:55 +053013474 /* By default Strict Regulatory For FCC should be false */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053013475
Agarwal Ashish1f422872014-07-22 00:11:55 +053013476 pHddCtx->nEnableStrictRegulatoryForFCC = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013477 // Load all config first as TL config is needed during vos_open
13478 pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL);
13479 if(pHddCtx->cfg_ini == NULL)
13480 {
13481 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__);
13482 goto err_free_hdd_context;
13483 }
13484
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053013485 hdd_request_manager_init();
13486
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t ));
13488
13489 // Read and parse the qcom_cfg.ini file
13490 status = hdd_parse_config_ini( pHddCtx );
13491 if ( VOS_STATUS_SUCCESS != status )
13492 {
13493 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
13494 __func__, WLAN_INI_FILE);
13495 goto err_config;
13496 }
Arif Hussaind5218912013-12-05 01:10:55 -080013497#ifdef MEMORY_DEBUG
13498 if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
13499 vos_mem_init();
13500
13501 hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
13502 __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
13503#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013504
Gopichand Nakkalab8f0f1a2013-05-23 18:19:48 +053013505 /* INI has been read, initialise the configuredMcastBcastFilter with
13506 * INI value as this will serve as the default value
13507 */
13508 pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting;
13509 hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d",
13510 pHddCtx->cfg_ini->mcastBcastFilterSetting);
Gopichand Nakkalafce506f2013-07-03 23:55:16 +053013511
13512 if (false == hdd_is_5g_supported(pHddCtx))
13513 {
13514 //5Ghz is not supported.
13515 if (1 != pHddCtx->cfg_ini->nBandCapability)
13516 {
13517 hddLog(VOS_TRACE_LEVEL_INFO,
13518 "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__);
13519 pHddCtx->cfg_ini->nBandCapability = 1;
13520 }
13521 }
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013522
13523 /* If SNR Monitoring is enabled, FW has to parse all beacons
13524 * for calcaluting and storing the average SNR, so set Nth beacon
13525 * filter to 1 to enable FW to parse all the beaocons
13526 */
13527 if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring)
13528 {
13529 /* The log level is deliberately set to WARN as overriding
13530 * nthBeaconFilter to 1 will increase power cosumption and this
13531 * might just prove helpful to detect the power issue.
13532 */
13533 hddLog(VOS_TRACE_LEVEL_WARN,
13534 "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__);
13535 pHddCtx->cfg_ini->nthBeaconFilter = 1;
13536 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013537 /*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013538 * cfg80211: Initialization ...
Jeff Johnson295189b2012-06-20 16:38:30 -070013539 */
Manjeet Singh61016fa2016-12-02 11:10:19 +053013540 if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini))
Jeff Johnson295189b2012-06-20 16:38:30 -070013541 {
Manjeet Singh61016fa2016-12-02 11:10:19 +053013542 hddLog(VOS_TRACE_LEVEL_FATAL,
13543 "%s: wlan_hdd_cfg80211_init return failure", __func__);
13544 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013545 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013546
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013547 // Update VOS trace levels based upon the cfg.ini
13548 hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
13549 pHddCtx->cfg_ini->vosTraceEnableBAP);
13550 hdd_vos_trace_enable(VOS_MODULE_ID_TL,
13551 pHddCtx->cfg_ini->vosTraceEnableTL);
13552 hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
13553 pHddCtx->cfg_ini->vosTraceEnableWDI);
13554 hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
13555 pHddCtx->cfg_ini->vosTraceEnableHDD);
13556 hdd_vos_trace_enable(VOS_MODULE_ID_SME,
13557 pHddCtx->cfg_ini->vosTraceEnableSME);
13558 hdd_vos_trace_enable(VOS_MODULE_ID_PE,
13559 pHddCtx->cfg_ini->vosTraceEnablePE);
Katya Nigam70d68332013-09-16 16:49:45 +053013560 hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
13561 pHddCtx->cfg_ini->vosTraceEnablePMC);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013562 hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
13563 pHddCtx->cfg_ini->vosTraceEnableWDA);
13564 hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
13565 pHddCtx->cfg_ini->vosTraceEnableSYS);
13566 hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
13567 pHddCtx->cfg_ini->vosTraceEnableVOSS);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013568 hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
13569 pHddCtx->cfg_ini->vosTraceEnableSAP);
13570 hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
13571 pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
Varun Reddy Yeturu587e6802013-01-24 12:21:41 -080013572
Jeff Johnson295189b2012-06-20 16:38:30 -070013573 // Update WDI trace levels based upon the cfg.ini
13574 hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
13575 pHddCtx->cfg_ini->wdiTraceEnableDAL);
13576 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
13577 pHddCtx->cfg_ini->wdiTraceEnableCTL);
13578 hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
13579 pHddCtx->cfg_ini->wdiTraceEnableDAT);
13580 hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
13581 pHddCtx->cfg_ini->wdiTraceEnablePAL);
Jeff Johnson295189b2012-06-20 16:38:30 -070013582
Jeff Johnson88ba7742013-02-27 14:36:02 -080013583 if (VOS_FTM_MODE == hdd_get_conparam())
13584 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013585 if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) )
13586 {
13587 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__);
13588 goto err_free_hdd_context;
13589 }
13590 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__);
Sachin Ahuja38ef5e02015-03-13 17:31:16 +053013591 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
c_hpothu2de0ef62014-04-15 16:16:15 +053013592 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Jeff Johnson295189b2012-06-20 16:38:30 -070013593 return VOS_STATUS_SUCCESS;
Jeff Johnson88ba7742013-02-27 14:36:02 -080013594 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013595
Katya Nigame7b69a82015-04-28 15:24:06 +053013596 if( VOS_MONITOR_MODE == hdd_get_conparam())
13597 {
13598 if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx))
13599 {
13600 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__);
13601 goto err_free_hdd_context;
13602 }
13603 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__);
13604 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
13605 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13606 return VOS_STATUS_SUCCESS;
13607 }
13608
Jeff Johnson88ba7742013-02-27 14:36:02 -080013609 //Open watchdog module
Jeff Johnson295189b2012-06-20 16:38:30 -070013610 if(pHddCtx->cfg_ini->fIsLogpEnabled)
13611 {
13612 status = vos_watchdog_open(pVosContext,
13613 &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext));
13614
13615 if(!VOS_IS_STATUS_SUCCESS( status ))
13616 {
13617 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__);
Ashish Kumar Dhanotiya532bdef2017-05-09 17:31:59 +053013618 goto err_config;
Jeff Johnson295189b2012-06-20 16:38:30 -070013619 }
13620 }
13621
13622 pHddCtx->isLogpInProgress = FALSE;
13623 vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE);
13624
Amar Singhala49cbc52013-10-08 18:37:44 -070013625#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070013626 /* initialize the NV module. This is required so that
13627 we can initialize the channel information in wiphy
13628 from the NV.bin data. The channel information in
13629 wiphy needs to be initialized before wiphy registration */
13630
13631 status = vos_nv_open();
13632 if (!VOS_IS_STATUS_SUCCESS(status))
13633 {
13634 /* NV module cannot be initialized */
13635 hddLog( VOS_TRACE_LEVEL_FATAL,
13636 "%s: vos_nv_open failed", __func__);
Vinay Krishna Eranna2025d892014-09-18 16:51:42 +053013637 goto err_wdclose;
Amar Singhal0a402232013-10-11 20:57:16 -070013638 }
13639
13640 status = vos_init_wiphy_from_nv_bin();
13641 if (!VOS_IS_STATUS_SUCCESS(status))
13642 {
13643 /* NV module cannot be initialized */
13644 hddLog( VOS_TRACE_LEVEL_FATAL,
13645 "%s: vos_init_wiphy failed", __func__);
13646 goto err_vos_nv_close;
13647 }
13648
Amar Singhala49cbc52013-10-08 18:37:44 -070013649#endif
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013650 //Initialize the nlink service
13651 if(nl_srv_init() != 0)
13652 {
13653 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__);
13654 goto err_vos_nv_close;
13655 }
13656
13657#ifdef WLAN_KD_READY_NOTIFIER
13658 pHddCtx->kd_nl_init = 1;
13659#endif /* WLAN_KD_READY_NOTIFIER */
13660
Girish Gowlibf0e1ab2015-01-19 16:05:16 +053013661 vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats);
Arun Kumar Khandavalliebb19482014-03-25 13:56:53 +053013662 status = vos_open( &pVosContext, pHddCtx->parent_dev);
Jeff Johnson295189b2012-06-20 16:38:30 -070013663 if ( !VOS_IS_STATUS_SUCCESS( status ))
13664 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013665 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053013666 goto err_nl_srv;
Jeff Johnson295189b2012-06-20 16:38:30 -070013667 }
13668
Jeff Johnson295189b2012-06-20 16:38:30 -070013669 pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext );
13670
13671 if ( NULL == pHddCtx->hHal )
13672 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013673 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013674 goto err_vosclose;
13675 }
13676
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013677 status = vos_preStart( pHddCtx->pvosContext );
13678 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13679 {
13680 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013681 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013682 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013683
Arif Hussaineaf68602013-12-30 23:10:44 -080013684 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan)
13685 {
13686 pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan;
13687 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d",
13688 __func__, enable_dfs_chan_scan);
13689 }
13690 if (0 == enable_11d || 1 == enable_11d)
13691 {
13692 pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d;
13693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d",
13694 __func__, enable_11d);
13695 }
13696
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013697 /* Note that the vos_preStart() sequence triggers the cfg download.
13698 The cfg download must occur before we update the SME config
13699 since the SME config operation must access the cfg database */
Jeff Johnson295189b2012-06-20 16:38:30 -070013700 status = hdd_set_sme_config( pHddCtx );
13701
13702 if ( VOS_STATUS_SUCCESS != status )
13703 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013704 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013705 goto err_vosclose;
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013706 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013707
Jeff Johnson295189b2012-06-20 16:38:30 -070013708 /* In the integrated architecture we update the configuration from
13709 the INI file and from NV before vOSS has been started so that
13710 the final contents are available to send down to the cCPU */
13711
13712 // Apply the cfg.ini to cfg.dat
13713 if (FALSE == hdd_update_config_dat(pHddCtx))
13714 {
13715 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013716 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013717 }
13718
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013719 // Get mac addr from platform driver
13720 ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes);
13721
13722 if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013723 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013724 /* Store the mac addr for first interface */
13725 pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr;
13726
13727 hddLog(VOS_TRACE_LEVEL_ERROR,
13728 "%s: WLAN Mac Addr: "
13729 MAC_ADDRESS_STR, __func__,
13730 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13731
13732 /* Here, passing Arg2 as 1 because we do not want to change the
13733 last 3 bytes (means non OUI bytes) of first interface mac
13734 addr.
13735 */
13736 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr))
13737 {
13738 hddLog(VOS_TRACE_LEVEL_ERROR,
13739 "%s: Failed to generate wlan interface mac addr "
13740 "using MAC from ini file ", __func__);
13741 }
13742 }
13743 else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx))
13744 {
13745 // Apply the NV to cfg.dat
13746 /* Prima Update MAC address only at here */
Jeff Johnson295189b2012-06-20 16:38:30 -070013747#ifdef WLAN_AUTOGEN_MACADDR_FEATURE
13748 /* There was not a valid set of MAC Addresses in NV. See if the
13749 default addresses were modified by the cfg.ini settings. If so,
13750 we'll use them, but if not, we'll autogenerate a set of MAC
13751 addresses based upon the device serial number */
13752
13753 static const v_MACADDR_t default_address =
13754 {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}};
Jeff Johnson295189b2012-06-20 16:38:30 -070013755
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013756 if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0],
13757 sizeof(default_address)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013758 {
13759 /* cfg.ini has the default address, invoke autogen logic */
13760
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013761 /* Here, passing Arg2 as 0 because we want to change the
13762 last 3 bytes (means non OUI bytes) of all the interfaces
13763 mac addr.
13764 */
13765 if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0,
13766 default_address))
Jeff Johnson295189b2012-06-20 16:38:30 -070013767 {
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013768 hddLog(VOS_TRACE_LEVEL_ERROR,
13769 "%s: Failed to generate wlan interface mac addr "
13770 "using MAC from ini file " MAC_ADDRESS_STR, __func__,
13771 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
Jeff Johnson295189b2012-06-20 16:38:30 -070013772 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013773 }
13774 else
13775#endif //WLAN_AUTOGEN_MACADDR_FEATURE
13776 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013777 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013778 "%s: Invalid MAC address in NV, using MAC from ini file "
13779 MAC_ADDRESS_STR, __func__,
13780 MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes));
13781 }
13782 }
13783 {
13784 eHalStatus halStatus;
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013785
13786 /* Set the MAC Address Currently this is used by HAL to
13787 * add self sta. Remove this once self sta is added as
13788 * part of session open.
13789 */
Jeff Johnson295189b2012-06-20 16:38:30 -070013790 halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID,
13791 (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0],
13792 sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) );
Hardik Kantilal Patel4d7982a2013-12-02 18:53:30 +053013793
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 if (!HAL_STATUS_SUCCESS( halStatus ))
13795 {
13796 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. "
13797 "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus );
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013798 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013799 }
13800 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013801
13802 /*Start VOSS which starts up the SME/MAC/HAL modules and everything else
13803 Note: Firmware image will be read and downloaded inside vos_start API */
13804 status = vos_start( pHddCtx->pvosContext );
13805 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13806 {
13807 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__);
Hanumantha Reddy Pothulabd9601a2016-02-12 13:22:27 +053013808 if (isSsrPanicOnFailure())
13809 VOS_BUG(0);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013810 goto err_vosclose;
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 }
13812
Leo Chang6cec3e22014-01-21 15:33:49 -080013813#ifdef FEATURE_WLAN_CH_AVOID
13814 /* Plug in avoid channel notification callback
13815 * This should happen before ADD_SELF_STA
13816 * FW will send first IND with ADD_SELF_STA REQ from host */
Pradeep Reddy POTTETI5c2e16d2014-06-27 16:47:38 +053013817
13818 /* check the Channel Avoidance is enabled */
13819 if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance)
13820 {
13821 sme_AddChAvoidCallback(pHddCtx->hHal,
13822 hdd_hostapd_ch_avoid_cb);
13823 }
Leo Chang6cec3e22014-01-21 15:33:49 -080013824#endif /* FEATURE_WLAN_CH_AVOID */
13825
Madan Mohan Koyyalamudi8612ec92012-09-28 15:53:07 -070013826 /* Exchange capability info between Host and FW and also get versioning info from FW */
13827 hdd_exchange_version_and_caps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070013828
Agarwal Ashishad9281b2014-06-10 14:57:30 +053013829#ifdef CONFIG_ENABLE_LINUX_REG
13830 status = wlan_hdd_init_channels(pHddCtx);
13831 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13832 {
13833 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed",
13834 __func__);
13835 goto err_vosstop;
13836 }
13837#endif
13838
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 status = hdd_post_voss_start_config( pHddCtx );
13840 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13841 {
13842 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed",
13843 __func__);
13844 goto err_vosstop;
13845 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013846
13847#ifndef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053013848 wlan_hdd_cfg80211_update_reg_info( wiphy );
13849
13850 /* registration of wiphy dev with cfg80211 */
13851 if (0 > wlan_hdd_cfg80211_register(wiphy))
13852 {
13853 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13854 goto err_vosstop;
13855 }
Amar Singhala49cbc52013-10-08 18:37:44 -070013856#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013857
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013858#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013859 /* registration of wiphy dev with cfg80211 */
13860 if (0 > wlan_hdd_cfg80211_register(wiphy))
13861 {
13862 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
13863 goto err_vosstop;
13864 }
13865
Agarwal Ashish6db9d532014-09-30 18:19:10 +053013866 status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053013867 if ( !VOS_IS_STATUS_SUCCESS( status ) )
13868 {
13869 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed",
13870 __func__);
13871 goto err_unregister_wiphy;
13872 }
13873#endif
13874
c_hpothu4a298be2014-12-22 21:12:51 +053013875 wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx);
13876
Jeff Johnson295189b2012-06-20 16:38:30 -070013877 if (VOS_STA_SAP_MODE == hdd_get_conparam())
13878 {
13879 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d",
13880 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13881 }
13882 else
13883 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d",
13885 wlan_hdd_get_intf_addr(pHddCtx), FALSE );
13886 if (pAdapter != NULL)
13887 {
Katya Nigama7d81d72014-11-12 12:44:34 +053013888 if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02))
Jeff Johnson295189b2012-06-20 16:38:30 -070013889 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013890 vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes,
13891 pHddCtx->cfg_ini->intfMacAddr[0].bytes,
13892 sizeof(tSirMacAddr));
Madan Mohan Koyyalamudiedfc1b72012-10-18 20:25:55 -070013893
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013894 /* Generate the P2P Device Address. This consists of the device's
13895 * primary MAC address with the locally administered bit set.
13896 */
13897 pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02;
Jeff Johnsone7245742012-09-05 17:12:55 -070013898 }
13899 else
13900 {
Gopichand Nakkala49f96f62013-02-06 14:38:17 +053013901 tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx);
13902 if (p2p_dev_addr != NULL)
13903 {
13904 vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0],
13905 p2p_dev_addr, VOS_MAC_ADDR_SIZE);
13906 }
13907 else
13908 {
13909 hddLog(VOS_TRACE_LEVEL_FATAL,
13910 "%s: Failed to allocate mac_address for p2p_device",
13911 __func__);
13912 goto err_close_adapter;
13913 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013915
13916 pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d",
13917 &pHddCtx->p2pDeviceAddress.bytes[0], FALSE );
13918 if ( NULL == pP2pAdapter )
13919 {
13920 hddLog(VOS_TRACE_LEVEL_FATAL,
13921 "%s: Failed to do hdd_open_adapter for P2P Device Interface",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013922 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013923 goto err_close_adapter;
13924 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013925 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013926 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013927
13928 if( pAdapter == NULL )
13929 {
Jeff Johnsonbc676b42013-02-14 16:04:08 -080013930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__);
13931 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013933
Arif Hussain66559122013-11-21 10:11:40 -080013934 if (country_code)
13935 {
13936 eHalStatus ret;
Arif Hussaincb607082013-12-20 11:57:42 -080013937 INIT_COMPLETION(pAdapter->change_country_code);
Arif Hussain66559122013-11-21 10:11:40 -080013938 hdd_checkandupdate_dfssetting(pAdapter, country_code);
13939#ifndef CONFIG_ENABLE_LINUX_REG
13940 hdd_checkandupdate_phymode(pAdapter, country_code);
13941#endif
Arif Hussaineaf68602013-12-30 23:10:44 -080013942 ret = sme_ChangeCountryCode(pHddCtx->hHal,
13943 (void *)(tSmeChangeCountryCallback)
13944 wlan_hdd_change_country_code_callback,
Arif Hussain66559122013-11-21 10:11:40 -080013945 country_code,
13946 pAdapter, pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053013947 eSIR_TRUE, eSIR_TRUE);
Arif Hussain66559122013-11-21 10:11:40 -080013948 if (eHAL_STATUS_SUCCESS == ret)
13949 {
Arif Hussaincb607082013-12-20 11:57:42 -080013950 ret = wait_for_completion_interruptible_timeout(
13951 &pAdapter->change_country_code,
13952 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
13953
13954 if (0 >= ret)
13955 {
13956 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13957 "%s: SME while setting country code timed out", __func__);
13958 }
Arif Hussain66559122013-11-21 10:11:40 -080013959 }
13960 else
13961 {
Arif Hussaincb607082013-12-20 11:57:42 -080013962 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13963 "%s: SME Change Country code from module param fail ret=%d",
13964 __func__, ret);
Arif Hussain66559122013-11-21 10:11:40 -080013965 }
13966 }
13967
Jeff Johnson295189b2012-06-20 16:38:30 -070013968#ifdef WLAN_BTAMP_FEATURE
13969 vStatus = WLANBAP_Open(pVosContext);
13970 if(!VOS_IS_STATUS_SUCCESS(vStatus))
13971 {
13972 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13973 "%s: Failed to open BAP",__func__);
Jeff Johnsone7245742012-09-05 17:12:55 -070013974 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070013975 }
13976
13977 vStatus = BSL_Init(pVosContext);
13978 if(!VOS_IS_STATUS_SUCCESS(vStatus))
13979 {
13980 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13981 "%s: Failed to Init BSL",__func__);
13982 goto err_bap_close;
13983 }
13984 vStatus = WLANBAP_Start(pVosContext);
13985 if (!VOS_IS_STATUS_SUCCESS(vStatus))
13986 {
13987 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
13988 "%s: Failed to start TL",__func__);
13989 goto err_bap_close;
13990 }
13991
13992 pConfig = pHddCtx->cfg_ini;
13993 btAmpConfig.ucPreferredChannel = pConfig->preferredChannel;
13994 status = WLANBAP_SetConfig(&btAmpConfig);
13995
13996#endif //WLAN_BTAMP_FEATURE
Jeff Johnsone7245742012-09-05 17:12:55 -070013997
Mihir Shete9c238772014-10-15 14:35:16 +053013998 /*
13999 * UapsdMask is 0xf if U-APSD is enbaled for all AC's...
14000 * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value)
14001 * which is greater than 0xf. So the below check is safe to make
14002 * sure that there is no entry for UapsdMask in the ini
14003 */
14004 if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask)
14005 {
14006 if(IS_DYNAMIC_WMM_PS_ENABLED)
14007 {
14008 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO",
14009 __func__);
14010 pHddCtx->cfg_ini->UapsdMask =
14011 CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT;
14012 }
14013 else
14014 {
14015 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD",
14016 __func__);
14017 pHddCtx->cfg_ini->UapsdMask =
14018 CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT;
14019 }
14020 }
14021
Varun Reddy Yeturud0a3f252013-04-15 21:58:13 -070014022#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
14023 if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE))
14024 {
14025 hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__);
14026 pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0;
14027 sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal),
14028 pHddCtx->cfg_ini->isRoamOffloadScanEnabled);
14029 }
14030#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014031
Agarwal Ashish4b87f922014-06-18 03:03:21 +053014032 wlan_hdd_tdls_init(pHddCtx);
14033
Masti, Narayanraddi26378462016-01-05 18:20:28 +053014034 wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt);
14035
14036 vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work,
14037 wlan_hdd_schedule_defer_scan);
14038
Mihir Shetefc7ff5b2014-01-27 11:30:05 +053014039 sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done);
14040
Jeff Johnson295189b2012-06-20 16:38:30 -070014041 /* Register with platform driver as client for Suspend/Resume */
14042 status = hddRegisterPmOps(pHddCtx);
14043 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14044 {
14045 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__);
14046#ifdef WLAN_BTAMP_FEATURE
14047 goto err_bap_stop;
14048#else
Jeff Johnsone7245742012-09-05 17:12:55 -070014049 goto err_close_adapter;
Jeff Johnson295189b2012-06-20 16:38:30 -070014050#endif //WLAN_BTAMP_FEATURE
14051 }
14052
Yue Ma0d4891e2013-08-06 17:01:45 -070014053 /* Open debugfs interface */
14054 if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter))
14055 {
14056 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
14057 "%s: hdd_debugfs_init failed!", __func__);
Yue Ma0d4891e2013-08-06 17:01:45 -070014058 }
14059
Jeff Johnson295189b2012-06-20 16:38:30 -070014060 /* Register TM level change handler function to the platform */
14061 status = hddDevTmRegisterNotifyCallback(pHddCtx);
14062 if ( !VOS_IS_STATUS_SUCCESS( status ) )
14063 {
14064 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__);
14065 goto err_unregister_pmops;
14066 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014067
Jeff Johnson295189b2012-06-20 16:38:30 -070014068 // register net device notifier for device change notification
14069 ret = register_netdevice_notifier(&hdd_netdev_notifier);
14070
14071 if(ret < 0)
14072 {
14073 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014074 goto err_unregister_pmops;
Jeff Johnson295189b2012-06-20 16:38:30 -070014075 }
14076
Jeff Johnson295189b2012-06-20 16:38:30 -070014077 //Initialize the BTC service
14078 if(btc_activate_service(pHddCtx) != 0)
14079 {
14080 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__);
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014081 goto err_reg_netdev;
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 }
14083
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014084#ifdef FEATURE_OEM_DATA_SUPPORT
14085 //Initialize the OEM service
14086 if (oem_activate_service(pHddCtx) != 0)
14087 {
14088 hddLog(VOS_TRACE_LEVEL_FATAL,
14089 "%s: oem_activate_service failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014090 goto err_btc_activate_service;
Padma, Santhosh Kumar2762e9d2015-10-20 15:02:57 +053014091 }
14092#endif
14093
Jeff Johnson295189b2012-06-20 16:38:30 -070014094#ifdef PTT_SOCK_SVC_ENABLE
14095 //Initialize the PTT service
14096 if(ptt_sock_activate_svc(pHddCtx) != 0)
14097 {
14098 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014099 goto err_oem_activate_service;
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 }
14101#endif
14102
Abhishek Singh00b71972016-01-07 10:51:04 +053014103#ifdef WLAN_FEATURE_RMC
14104 if (hdd_open_cesium_nl_sock() < 0)
14105 {
14106 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014107 goto err_ptt_sock_activate_svc;
Abhishek Singh00b71972016-01-07 10:51:04 +053014108 }
14109#endif
14110
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014111#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14112 if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable)
14113 {
Deepthi Gowri78083a32014-11-04 12:55:51 +053014114 if(wlan_logging_sock_activate_svc(
14115 pHddCtx->cfg_ini->wlanLoggingFEToConsole,
Sushant Kaushik33200572015-08-05 16:46:20 +053014116 pHddCtx->cfg_ini->wlanLoggingNumBuf,
14117 pHddCtx->cfg_ini->wlanPerPktStatsLogEnable,
14118 pHddCtx->cfg_ini->wlanPerPktStatsNumBuf))
Deepthi Gowri78083a32014-11-04 12:55:51 +053014119 {
14120 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc"
14121 " failed", __func__);
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014122 goto err_open_cesium_nl_sock;
Deepthi Gowri78083a32014-11-04 12:55:51 +053014123 }
14124 //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for
14125 //EAPOL and DHCP
Sachin Ahuja8c65f382014-12-12 15:34:21 +053014126 if (!pHddCtx->cfg_ini->gEnableDebugLog)
14127 pHddCtx->cfg_ini->gEnableDebugLog =
Sushant Kaushik6e4e2bc2015-10-05 17:23:07 +053014128 VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP |
14129 VOS_PKT_PROTO_TYPE_ARP;
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014130 }
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014131
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014132 if (pHddCtx->cfg_ini->wlanLoggingEnable &&
14133 (pHddCtx->cfg_ini->enableFWLogging ||
Siddharth Bhaldb963232015-06-25 19:34:35 +053014134 pHddCtx->cfg_ini->enableMgmtLogging ||
c_manjeecfd1efb2015-09-25 19:32:34 +053014135 pHddCtx->cfg_ini->enableContFWLogging ||
14136 pHddCtx->cfg_ini->enableFwrMemDump )
14137 )
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014138 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014139 hdd_init_frame_logging(pHddCtx);
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014140 }
14141 else
14142 {
Siddharth Bhald1be97f2015-05-27 22:39:59 +053014143 hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini"));
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014144 }
14145
Vinay Krishna Erannad938c422014-03-10 17:14:21 +053014146#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014147
Agrawal Ashish17ef5082016-10-17 18:33:21 +053014148#ifdef SAP_AUTH_OFFLOAD
14149 if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS))
14150 {
14151 hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW"));
14152 pHddCtx->cfg_ini->enable_sap_auth_offload = 0;
14153 }
14154#endif
Siddharth Bhalb7c421c2015-02-27 00:26:09 +053014155
Sushant Kaushik215778f2015-05-21 14:05:36 +053014156 if (vos_is_multicast_logging())
14157 wlan_logging_set_log_level();
14158
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 hdd_register_mcast_bcast_filter(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014160 if (VOS_STA_SAP_MODE != hdd_get_conparam())
Jeff Johnson295189b2012-06-20 16:38:30 -070014161 {
Madan Mohan Koyyalamudic537df22012-10-22 15:07:08 -070014162 /* Action frame registered in one adapter which will
14163 * applicable to all interfaces
14164 */
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +053014165 wlan_hdd_cfg80211_register_frames(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014166 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014167
14168 mutex_init(&pHddCtx->sap_lock);
Mahesh A Saptasagar60627942014-10-13 13:55:14 +053014169 mutex_init(&pHddCtx->roc_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014170
Jeff Johnsone7245742012-09-05 17:12:55 -070014171#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
14172 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014173 vos_wake_lock_init(&pHddCtx->rx_wake_lock,
Jeff Johnsone7245742012-09-05 17:12:55 -070014174 "qcom_rx_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014175
Jeff Johnsone7245742012-09-05 17:12:55 -070014176#endif
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014177 /* Initialize the wake lcok */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014178 vos_wake_lock_init(&pHddCtx->sap_wake_lock,
Madan Mohan Koyyalamudi69fc3ad2012-11-28 16:04:56 -080014179 "qcom_sap_wakelock");
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014180
Jeff Johnsone7245742012-09-05 17:12:55 -070014181
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014182 vos_event_init(&pHddCtx->scan_info.scan_finished_event);
14183 pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014184
Katya Nigam5c306ea2014-06-19 15:39:54 +053014185 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070014186 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014187 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Katya Nigam5c306ea2014-06-19 15:39:54 +053014188
14189#ifdef FEATURE_WLAN_SCAN_PNO
14190 /*SME must send channel update configuration to RIVA*/
14191 sme_UpdateChannelConfig(pHddCtx->hHal);
14192#endif
Abhishek Singhf644b272014-08-21 02:59:39 +053014193 /* Send the update default channel list to the FW*/
14194 sme_UpdateChannelList(pHddCtx->hHal);
Mukul Sharma45063942015-04-01 20:07:59 +053014195
14196 /* Fwr capabilities received, Set the Dot11 mode */
Abhishek Singh41ebce12016-02-03 10:43:21 +053014197 sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter),
14198 hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode));
Mukul Sharma45063942015-04-01 20:07:59 +053014199 sme_SetDefDot11Mode(pHddCtx->hHal);
14200
Abhishek Singha306a442013-11-07 18:39:01 +053014201#ifndef CONFIG_ENABLE_LINUX_REG
14202 /*updating wiphy so that regulatory user hints can be processed*/
14203 if (wiphy)
14204 {
14205 regulatory_hint(wiphy, "00");
14206 }
14207#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014208 // Initialize the restart logic
14209 wlan_hdd_restart_init(pHddCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053014210
Hanumanth Reddy Pothula146bca42016-11-08 12:01:07 +053014211 if (pHddCtx->cfg_ini->fIsLogpEnabled) {
14212 vos_wdthread_init_timer_work(vos_process_wd_timer);
14213 /* Initialize the timer to detect thread stuck issues */
14214 vos_thread_stuck_timer_init(
14215 &((VosContextType*)pVosContext)->vosWatchdog);
14216 }
14217
Sudhir Sattayappa Kohalli37620692013-08-05 14:02:26 -070014218 //Register the traffic monitor timer now
14219 if ( pHddCtx->cfg_ini->dynSplitscan)
14220 {
14221 vos_timer_init(&pHddCtx->tx_rx_trafficTmr,
14222 VOS_TIMER_TYPE_SW,
14223 hdd_tx_rx_pkt_cnt_stat_timer_handler,
14224 (void *)pHddCtx);
14225 }
Srinivas Dasari030bad32015-02-18 23:23:54 +053014226 wlan_hdd_cfg80211_nan_init(pHddCtx);
14227
Bhargav Shahd0715912015-10-01 18:17:37 +053014228 mutex_init(&pHddCtx->cur_rx_level_lock);
14229 vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW,
14230 hdd_tcp_delack_compute_function,(void *)pHddCtx);
Masti, Narayanraddi44b0db02015-12-22 11:54:35 +053014231 vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW,
14232 wlan_hdd_change_tdls_mode, (void *)pHddCtx);
Bhargav Shahd0715912015-10-01 18:17:37 +053014233
Dino Mycle6fb96c12014-06-10 11:52:40 +053014234#ifdef WLAN_FEATURE_EXTSCAN
14235 sme_EXTScanRegisterCallback(pHddCtx->hHal,
14236 wlan_hdd_cfg80211_extscan_callback,
14237 pHddCtx);
14238#endif /* WLAN_FEATURE_EXTSCAN */
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014239
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053014240#ifdef FEATURE_OEM_DATA_SUPPORT
14241 sme_OemDataRegisterCallback(pHddCtx->hHal,
14242 wlan_hdd_cfg80211_oemdata_callback,
14243 pHddCtx);
14244#endif /* FEATURE_OEM_DATA_SUPPORT */
14245
Gupta, Kapil7c34b322015-09-30 13:12:35 +053014246 sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014247#ifdef WLAN_NS_OFFLOAD
14248 // Register IPv6 notifier to notify if any change in IP
14249 // So that we can reconfigure the offload parameters
14250 pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
14251 ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier);
14252 if (ret)
14253 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014255 }
14256 else
14257 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014258 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014259 }
14260#endif
14261
Sravan Kumar Kairamb0edc612016-10-26 13:55:24 +053014262 vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0);
14263
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014264 // Register IPv4 notifier to notify if any change in IP
14265 // So that we can reconfigure the offload parameters
14266 pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
14267 ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier);
14268 if (ret)
14269 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014271 }
14272 else
14273 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053014274 hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier"));
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014275 }
c_manjeecfd1efb2015-09-25 19:32:34 +053014276 /*Fw mem dump procfs initialization*/
14277 memdump_init();
Bhargav shah23c94942015-10-13 12:48:35 +053014278 hdd_dp_util_send_rps_ind(pHddCtx);
Vinay Krishna Erannaf97ef5c2014-12-26 17:47:19 +053014279
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053014280 pHddCtx->is_ap_mode_wow_supported =
14281 sme_IsFeatureSupportedByFW(SAP_MODE_WOW);
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014282
Hanumanth Reddy Pothulae92bcc12017-05-19 13:56:35 +053014283 pHddCtx->is_fatal_event_log_sup =
14284 sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING);
14285 hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"),
14286 pHddCtx->is_fatal_event_log_sup);
14287
Sravan Kumar Kairam091e5b62017-01-23 14:14:20 +053014288 hdd_assoc_registerFwdEapolCB(pVosContext);
14289
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053014290 mutex_init(&pHddCtx->cache_channel_lock);
Jeff Johnson295189b2012-06-20 16:38:30 -070014291 goto success;
14292
Hanumanth Reddy Pothula13789c42017-09-12 15:18:13 +053014293err_open_cesium_nl_sock:
14294#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14295 hdd_close_cesium_nl_sock();
14296#endif
14297
14298err_ptt_sock_activate_svc:
14299#ifdef PTT_SOCK_SVC_ENABLE
14300 ptt_sock_deactivate_svc(pHddCtx);
14301#endif
14302
14303err_oem_activate_service:
14304#ifdef FEATURE_OEM_DATA_SUPPORT
14305 oem_deactivate_service();
14306#endif
14307
14308err_btc_activate_service:
14309 btc_deactivate_service();
14310
Jeff Johnson295189b2012-06-20 16:38:30 -070014311err_reg_netdev:
14312 unregister_netdevice_notifier(&hdd_netdev_notifier);
14313
Jeff Johnson295189b2012-06-20 16:38:30 -070014314err_unregister_pmops:
14315 hddDevTmUnregisterNotifyCallback(pHddCtx);
14316 hddDeregisterPmOps(pHddCtx);
14317
Yue Ma0d4891e2013-08-06 17:01:45 -070014318 hdd_debugfs_exit(pHddCtx);
14319
Jeff Johnson295189b2012-06-20 16:38:30 -070014320#ifdef WLAN_BTAMP_FEATURE
14321err_bap_stop:
14322 WLANBAP_Stop(pVosContext);
14323#endif
14324
14325#ifdef WLAN_BTAMP_FEATURE
14326err_bap_close:
14327 WLANBAP_Close(pVosContext);
14328#endif
14329
Jeff Johnson295189b2012-06-20 16:38:30 -070014330err_close_adapter:
14331 hdd_close_all_adapters( pHddCtx );
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014332#ifdef CONFIG_ENABLE_LINUX_REG
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053014333err_unregister_wiphy:
Mahesh A Saptasagar9ecefe42014-07-15 18:43:49 +053014334#endif
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +053014335 wiphy_unregister(wiphy) ;
Agrawal Ashish33ec71e2015-11-26 20:20:58 +053014336 hdd_wlan_free_wiphy_channels(wiphy);
14337
Jeff Johnson295189b2012-06-20 16:38:30 -070014338err_vosstop:
14339 vos_stop(pVosContext);
14340
Amar Singhala49cbc52013-10-08 18:37:44 -070014341err_vosclose:
Jeff Johnson295189b2012-06-20 16:38:30 -070014342 status = vos_sched_close( pVosContext );
14343 if (!VOS_IS_STATUS_SUCCESS(status)) {
14344 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
14345 "%s: Failed to close VOSS Scheduler", __func__);
14346 VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) );
14347 }
Amar Singhala49cbc52013-10-08 18:37:44 -070014348 vos_close(pVosContext );
14349
Mahesh A Saptasagarc3ed0122016-01-19 16:45:11 +053014350err_nl_srv:
14351#ifdef WLAN_KD_READY_NOTIFIER
14352 nl_srv_exit(pHddCtx->ptt_pid);
14353#else
14354 nl_srv_exit();
14355#endif /* WLAN_KD_READY_NOTIFIER */
Amar Singhal0a402232013-10-11 20:57:16 -070014356err_vos_nv_close:
14357
c_hpothue6a36282014-03-19 12:27:38 +053014358#ifdef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -070014359 vos_nv_close();
14360
c_hpothu70f8d812014-03-22 22:59:23 +053014361#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014362
14363err_wdclose:
14364 if(pHddCtx->cfg_ini->fIsLogpEnabled)
14365 vos_watchdog_close(pVosContext);
14366
Jeff Johnson295189b2012-06-20 16:38:30 -070014367err_config:
Hanumanth Reddy Pothula1efcd162018-03-14 14:32:27 +053014368 hdd_request_manager_deinit();
Jeff Johnson295189b2012-06-20 16:38:30 -070014369 kfree(pHddCtx->cfg_ini);
14370 pHddCtx->cfg_ini= NULL;
14371
14372err_free_hdd_context:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014373 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
Siddharth Bhalcd92b782015-06-29 12:25:40 +053014374 free_riva_power_on_lock("wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014375 wiphy_free(wiphy) ;
14376 //kfree(wdev) ;
Jeff Johnson295189b2012-06-20 16:38:30 -070014377 VOS_BUG(1);
14378
Madan Mohan Koyyalamudid57ae632012-11-06 18:42:48 -080014379 if (hdd_is_ssr_required())
14380 {
14381 /* WDI timeout had happened during load, so SSR is needed here */
14382 subsystem_restart("wcnss");
14383 msleep(5000);
14384 }
14385 hdd_set_ssr_required (VOS_FALSE);
14386
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014387 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014388
14389success:
14390 EXIT();
14391 return 0;
14392}
14393
14394/**---------------------------------------------------------------------------
14395
Jeff Johnson32d95a32012-09-10 13:15:23 -070014396 \brief hdd_driver_init() - Core Driver Init Function
Jeff Johnson295189b2012-06-20 16:38:30 -070014397
Jeff Johnson32d95a32012-09-10 13:15:23 -070014398 This is the driver entry point - called in different timeline depending
14399 on whether the driver is statically or dynamically linked
Jeff Johnson295189b2012-06-20 16:38:30 -070014400
14401 \param - None
14402
14403 \return - 0 for success, non zero for failure
14404
14405 --------------------------------------------------------------------------*/
Jeff Johnson32d95a32012-09-10 13:15:23 -070014406static int hdd_driver_init( void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014407{
14408 VOS_STATUS status;
14409 v_CONTEXT_t pVosContext = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 struct device *dev = NULL;
14411 int ret_status = 0;
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014412#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14413 int max_retries = 0;
14414#endif
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014415#ifdef HAVE_CBC_DONE
14416 int max_cbc_retries = 0;
14417#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014418
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014419#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14420 wlan_logging_sock_init_svc();
14421#endif
14422
Jeff Johnson295189b2012-06-20 16:38:30 -070014423 ENTER();
14424
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014425 vos_wake_lock_init(&wlan_wake_lock, "wlan");
Jeff Johnson295189b2012-06-20 16:38:30 -070014426
14427 pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
14428 QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
14429
Jeff Johnson295189b2012-06-20 16:38:30 -070014430#ifdef ANI_BUS_TYPE_PCI
14431
14432 dev = wcnss_wlan_get_device();
14433
14434#endif // ANI_BUS_TYPE_PCI
14435
14436#ifdef ANI_BUS_TYPE_PLATFORM
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014437
14438#ifdef HAVE_WCNSS_CAL_DOWNLOAD
14439 /* wait until WCNSS driver downloads NV */
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014440 while (!wcnss_device_ready() && 10 >= ++max_retries) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014441 msleep(1000);
14442 }
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014443
Ravi Kumar Bokka7a139e62016-11-17 21:32:55 +053014444 if (max_retries >= 10) {
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014445 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014446 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014447#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14448 wlan_logging_sock_deinit_svc();
14449#endif
14450
Sameer Thalappilf58d7ec2013-04-25 20:17:12 -070014451 return -ENODEV;
14452 }
14453#endif
14454
Siddharth Bhalc7e79b62014-10-10 22:37:38 +053014455#ifdef HAVE_CBC_DONE
14456 while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
14457 msleep(1000);
14458 }
14459 if (max_cbc_retries >= 10) {
14460 hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
14461 }
14462#endif
14463
Jeff Johnson295189b2012-06-20 16:38:30 -070014464 dev = wcnss_wlan_get_device();
14465#endif // ANI_BUS_TYPE_PLATFORM
14466
14467
14468 do {
14469 if (NULL == dev) {
14470 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
14471 ret_status = -1;
14472 break;
14473 }
14474
Jeff Johnson295189b2012-06-20 16:38:30 -070014475#ifdef TIMER_MANAGER
14476 vos_timer_manager_init();
14477#endif
14478
14479 /* Preopen VOSS so that it is ready to start at least SAL */
14480 status = vos_preOpen(&pVosContext);
14481
14482 if (!VOS_IS_STATUS_SUCCESS(status))
14483 {
14484 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
14485 ret_status = -1;
14486 break;
14487 }
14488
Sushant Kaushik02beb352015-06-04 15:15:01 +053014489 hddTraceInit();
Padma, Santhosh Kumar9093b202015-07-21 15:37:38 +053014490 hdd_register_debug_callback();
14491
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014492#ifndef MODULE
14493 /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
14494 */
14495 hdd_set_conparam((v_UINT_t)con_mode);
14496#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014497
14498 // Call our main init function
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014499 if (hdd_wlan_startup(dev))
14500 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014501 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
Jeff Johnsonbc676b42013-02-14 16:04:08 -080014502 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014503 vos_preClose( &pVosContext );
14504 ret_status = -1;
14505 break;
14506 }
14507
Jeff Johnson295189b2012-06-20 16:38:30 -070014508 } while (0);
14509
14510 if (0 != ret_status)
14511 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014512#ifdef TIMER_MANAGER
14513 vos_timer_exit();
14514#endif
14515#ifdef MEMORY_DEBUG
14516 vos_mem_exit();
14517#endif
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014518 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014519#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14520 wlan_logging_sock_deinit_svc();
14521#endif
14522
Jeff Johnson295189b2012-06-20 16:38:30 -070014523 pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
14524 }
14525 else
14526 {
14527 //Send WLAN UP indication to Nlink Service
14528 send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
14529
14530 pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 }
14532
14533 EXIT();
14534
14535 return ret_status;
14536}
14537
Jeff Johnson32d95a32012-09-10 13:15:23 -070014538/**---------------------------------------------------------------------------
14539
14540 \brief hdd_module_init() - Init Function
14541
14542 This is the driver entry point (invoked when module is loaded using insmod)
14543
14544 \param - None
14545
14546 \return - 0 for success, non zero for failure
14547
14548 --------------------------------------------------------------------------*/
14549#ifdef MODULE
14550static int __init hdd_module_init ( void)
14551{
14552 return hdd_driver_init();
14553}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014554#else /* #ifdef MODULE */
14555static int __init hdd_module_init ( void)
14556{
14557 /* Driver initialization is delayed to fwpath_changed_handler */
14558 return 0;
14559}
Jeff Johnson32d95a32012-09-10 13:15:23 -070014560#endif /* #ifdef MODULE */
14561
Jeff Johnson295189b2012-06-20 16:38:30 -070014562
14563/**---------------------------------------------------------------------------
14564
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014565 \brief hdd_driver_exit() - Exit function
Jeff Johnson295189b2012-06-20 16:38:30 -070014566
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014567 This is the driver exit point (invoked when module is unloaded using rmmod
14568 or con_mode was changed by userspace)
Jeff Johnson295189b2012-06-20 16:38:30 -070014569
14570 \param - None
14571
14572 \return - None
14573
14574 --------------------------------------------------------------------------*/
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014575static void hdd_driver_exit(void)
Jeff Johnson295189b2012-06-20 16:38:30 -070014576{
14577 hdd_context_t *pHddCtx = NULL;
14578 v_CONTEXT_t pVosContext = NULL;
Agarwal Ashish5e414792014-06-08 15:25:23 +053014579 v_REGDOMAIN_t regId;
Arun Kumar Khandavallie0b046d2014-03-01 21:54:25 +053014580 unsigned long rc = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014581
14582 pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR);
14583
14584 //Get the global vos context
14585 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
14586
14587 if(!pVosContext)
14588 {
14589 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__);
14590 goto done;
14591 }
14592
14593 //Get the HDD context.
14594 pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext );
14595
14596 if(!pHddCtx)
14597 {
14598 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__);
14599 }
Katya Nigame7b69a82015-04-28 15:24:06 +053014600 else if (VOS_MONITOR_MODE == hdd_get_conparam())
14601 {
14602 hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__);
14603 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14604 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
14605 hdd_wlan_exit(pHddCtx);
14606 vos_preClose( &pVosContext );
14607 goto done;
14608 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014609 else
14610 {
Siddharth Bhal2e5871b2015-03-24 16:20:51 +053014611 /* We wait for active entry threads to exit from driver
14612 * by waiting until rtnl_lock is available.
14613 */
14614 rtnl_lock();
14615 rtnl_unlock();
14616
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014617 INIT_COMPLETION(pHddCtx->ssr_comp_var);
14618 if ((pHddCtx->isLogpInProgress) && (FALSE ==
14619 vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL)))
14620 {
Siddharth Bhala204f572015-01-17 02:03:36 +053014621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014622 "%s:SSR in Progress; block rmmod !!!", __func__);
Siddharth Bhala204f572015-01-17 02:03:36 +053014623 rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var,
14624 msecs_to_jiffies(30000));
14625 if(!rc)
14626 {
14627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14628 "%s:SSR timedout, fatal error", __func__);
14629 VOS_BUG(0);
14630 }
14631 }
14632
Siddharth Bhal3c29dca2015-02-19 00:41:40 +053014633 pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS;
14634 vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070014635
c_hpothu8adb97b2014-12-08 19:38:20 +053014636 /* Driver Need to send country code 00 in below condition
14637 * 1) If gCountryCodePriority is set to 1; and last country
14638 * code set is through 11d. This needs to be done in case
14639 * when NV country code is 00.
14640 * This Needs to be done as when kernel store last country
14641 * code and if stored country code is not through 11d,
14642 * in sme_HandleChangeCountryCodeByUser we will disable 11d
14643 * in next load/unload as soon as we get any country through
14644 * 11d. In sme_HandleChangeCountryCodeByUser
14645 * pMsg->countryCode will be last countryCode and
14646 * pMac->scan.countryCode11d will be country through 11d so
14647 * due to mismatch driver will disable 11d.
14648 *
14649 */
Agarwal Ashish8db39882014-07-30 21:56:07 +053014650
c_hpothu8adb97b2014-12-08 19:38:20 +053014651 if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) &&
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014652 pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority &&
Abhishek Singh2a705962014-10-30 14:47:28 +053014653 sme_Is11dSupported(pHddCtx->hHal)))
c_hpothu8adb97b2014-12-08 19:38:20 +053014654 {
14655 hddLog(VOS_TRACE_LEVEL_INFO,
Agarwal Ashish8dcd2862014-07-25 11:58:52 +053014656 FL("CountryCode 00 is being set while unloading driver"));
c_hpothu8adb97b2014-12-08 19:38:20 +053014657 vos_nv_getRegDomainFromCountryCode(&regId , "00", COUNTRY_USER);
14658 }
Agarwal Ashish5e414792014-06-08 15:25:23 +053014659
c_hpothu8adb97b2014-12-08 19:38:20 +053014660 //Do all the cleanup before deregistering the driver
14661 hdd_wlan_exit(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070014662 }
14663
Jeff Johnson295189b2012-06-20 16:38:30 -070014664 vos_preClose( &pVosContext );
14665
14666#ifdef TIMER_MANAGER
14667 vos_timer_exit();
14668#endif
14669#ifdef MEMORY_DEBUG
14670 vos_mem_exit();
14671#endif
14672
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014673#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
14674 wlan_logging_sock_deinit_svc();
14675#endif
14676
Jeff Johnson295189b2012-06-20 16:38:30 -070014677done:
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014678 vos_wake_lock_destroy(&wlan_wake_lock);
Vinay Krishna Eranna273ec5a2014-05-10 18:05:25 +053014679
Jeff Johnson295189b2012-06-20 16:38:30 -070014680 pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME);
14681}
14682
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014683/**---------------------------------------------------------------------------
14684
14685 \brief hdd_module_exit() - Exit function
14686
14687 This is the driver exit point (invoked when module is unloaded using rmmod)
14688
14689 \param - None
14690
14691 \return - None
14692
14693 --------------------------------------------------------------------------*/
14694static void __exit hdd_module_exit(void)
14695{
14696 hdd_driver_exit();
14697}
14698
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014699#ifdef MODULE
14700static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014701 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014702{
Jeff Johnson76052702013-04-16 13:55:05 -070014703 return param_set_copystring(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014704}
14705
14706static int con_mode_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014707 const struct kernel_param *kp)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014708{
Madan Mohan Koyyalamudif2f8d8b2012-10-11 17:06:59 -070014709 return param_set_int(kmessage, kp);
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014710}
14711#else /* #ifdef MODULE */
14712/**---------------------------------------------------------------------------
14713
Jeff Johnson76052702013-04-16 13:55:05 -070014714 \brief kickstart_driver
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014715
Jeff Johnson76052702013-04-16 13:55:05 -070014716 This is the driver entry point
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014717 - delayed driver initialization when driver is statically linked
Jeff Johnson76052702013-04-16 13:55:05 -070014718 - invoked when module parameter fwpath is modified from userspace to signal
14719 initializing the WLAN driver or when con_mode is modified from userspace
14720 to signal a switch in operating mode
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014721
14722 \return - 0 for success, non zero for failure
14723
14724 --------------------------------------------------------------------------*/
Jeff Johnson76052702013-04-16 13:55:05 -070014725static int kickstart_driver(void)
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014726{
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014727 int ret_status;
14728
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014729 if (!wlan_hdd_inited) {
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014730 ret_status = hdd_driver_init();
14731 wlan_hdd_inited = ret_status ? 0 : 1;
14732 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014733 }
14734
14735 hdd_driver_exit();
Jeff Johnson76052702013-04-16 13:55:05 -070014736
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014737 msleep(200);
Jeff Johnson76052702013-04-16 13:55:05 -070014738
Madan Mohan Koyyalamudi62e60052012-10-05 14:27:22 -070014739 ret_status = hdd_driver_init();
14740 wlan_hdd_inited = ret_status ? 0 : 1;
14741 return ret_status;
Madan Mohan Koyyalamudic2ec3bd2012-09-18 19:49:40 -070014742}
14743
Jeff Johnson295189b2012-06-20 16:38:30 -070014744/**---------------------------------------------------------------------------
14745
Jeff Johnson76052702013-04-16 13:55:05 -070014746 \brief fwpath_changed_handler() - Handler Function
14747
14748 Handle changes to the fwpath parameter
14749
14750 \return - 0 for success, non zero for failure
14751
14752 --------------------------------------------------------------------------*/
14753static int fwpath_changed_handler(const char *kmessage,
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014754 const struct kernel_param *kp)
Jeff Johnson76052702013-04-16 13:55:05 -070014755{
14756 int ret;
14757
14758 ret = param_set_copystring(kmessage, kp);
14759 if (0 == ret)
14760 ret = kickstart_driver();
14761 return ret;
14762}
14763
14764/**---------------------------------------------------------------------------
14765
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014766 \brief con_mode_handler() -
14767
14768 Handler function for module param con_mode when it is changed by userspace
14769 Dynamically linked - do nothing
14770 Statically linked - exit and init driver, as in rmmod and insmod
14771
Jeff Johnson76052702013-04-16 13:55:05 -070014772 \param -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014773
Jeff Johnson76052702013-04-16 13:55:05 -070014774 \return -
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014775
14776 --------------------------------------------------------------------------*/
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053014777static int con_mode_handler(const char *kmessage,
14778 const struct kernel_param *kp)
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014779{
Jeff Johnson76052702013-04-16 13:55:05 -070014780 int ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014781
Jeff Johnson76052702013-04-16 13:55:05 -070014782 ret = param_set_int(kmessage, kp);
14783 if (0 == ret)
14784 ret = kickstart_driver();
14785 return ret;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014786}
14787#endif /* #ifdef MODULE */
14788
14789/**---------------------------------------------------------------------------
14790
Jeff Johnson295189b2012-06-20 16:38:30 -070014791 \brief hdd_get_conparam() -
14792
14793 This is the driver exit point (invoked when module is unloaded using rmmod)
14794
14795 \param - None
14796
14797 \return - tVOS_CON_MODE
14798
14799 --------------------------------------------------------------------------*/
14800tVOS_CON_MODE hdd_get_conparam ( void )
14801{
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014802#ifdef MODULE
Jeff Johnson295189b2012-06-20 16:38:30 -070014803 return (tVOS_CON_MODE)con_mode;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014804#else
14805 return (tVOS_CON_MODE)curr_con_mode;
14806#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014807}
14808void hdd_set_conparam ( v_UINT_t newParam )
14809{
14810 con_mode = newParam;
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070014811#ifndef MODULE
14812 curr_con_mode = con_mode;
14813#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014814}
14815/**---------------------------------------------------------------------------
14816
14817 \brief hdd_softap_sta_deauth() - function
14818
14819 This to take counter measure to handle deauth req from HDD
14820
14821 \param - pAdapter - Pointer to the HDD
14822
14823 \param - enable - boolean value
14824
14825 \return - None
14826
14827 --------------------------------------------------------------------------*/
14828
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014829VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter,
14830 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014831{
Jeff Johnson295189b2012-06-20 16:38:30 -070014832 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014833 VOS_STATUS vosStatus = VOS_STATUS_E_FAULT;
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014834 struct hdd_cache_sta_info *cache_sta_info;
14835 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014836
14837 ENTER();
14838
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014839 hddLog(LOG1, "hdd_softap_sta_deauth:(%pK, false)",
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014840 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014841
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014842 if (!pSapCtx) {
14843 hddLog(LOGE, "sap context is NULL");
14844 return vosStatus;
14845 }
14846
14847 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14848 pDelStaParams->peerMacAddr);
14849 if (cache_sta_info) {
14850 cache_sta_info->reason_code = pDelStaParams->reason_code;
14851 cache_sta_info->rx_rate =
14852 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14853 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14854 &cache_sta_info->rssi);
14855 }
14856
Jeff Johnson295189b2012-06-20 16:38:30 -070014857 //Ignore request to deauth bcmc station
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014858 if (pDelStaParams->peerMacAddr[0] & 0x1)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014859 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014860
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014861 vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams);
Jeff Johnson295189b2012-06-20 16:38:30 -070014862
14863 EXIT();
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014864 return vosStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -070014865}
14866
14867/**---------------------------------------------------------------------------
14868
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014869 \brief hdd_del_all_sta() - function
14870
14871 This function removes all the stations associated on stopping AP/P2P GO.
14872
14873 \param - pAdapter - Pointer to the HDD
14874
14875 \return - None
14876
14877 --------------------------------------------------------------------------*/
14878
14879int hdd_del_all_sta(hdd_adapter_t *pAdapter)
14880{
14881 v_U16_t i;
14882 VOS_STATUS vos_status;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014883 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14884 ptSapContext pSapCtx = NULL;
14885 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14886 if(pSapCtx == NULL){
14887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14888 FL("psapCtx is NULL"));
14889 return 1;
14890 }
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014891 ENTER();
14892
14893 hddLog(VOS_TRACE_LEVEL_INFO,
14894 "%s: Delete all STAs associated.",__func__);
14895 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
14896 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
14897 )
14898 {
14899 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14900 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014901 if ((pSapCtx->aStaInfo[i].isUsed) &&
14902 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014903 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014904 struct tagCsrDelStaParams delStaParams;
14905
14906 WLANSAP_PopulateDelStaParams(
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014907 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014908 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
14909 SIR_MAC_MGMT_DEAUTH >> 4,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014910 &delStaParams);
14911 vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams);
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014912 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014913 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053014914 }
14915 }
14916 }
14917
14918 EXIT();
14919 return 0;
14920}
14921
14922/**---------------------------------------------------------------------------
14923
Jeff Johnson295189b2012-06-20 16:38:30 -070014924 \brief hdd_softap_sta_disassoc() - function
14925
14926 This to take counter measure to handle deauth req from HDD
14927
14928 \param - pAdapter - Pointer to the HDD
14929
14930 \param - enable - boolean value
14931
14932 \return - None
14933
14934 --------------------------------------------------------------------------*/
14935
14936void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress)
14937{
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014938 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14939 struct hdd_cache_sta_info *cache_sta_info;
14940 ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014941
14942 ENTER();
14943
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014944 hddLog( LOGE, "hdd_softap_sta_disassoc:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014945
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014946 if (!pSapCtx) {
14947 hddLog(LOGE, "sap context is NULL");
14948 return ;
14949 }
14950
Jeff Johnson295189b2012-06-20 16:38:30 -070014951 //Ignore request to disassoc bcmc station
14952 if( pDestMacAddress[0] & 0x1 )
14953 return;
14954
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053014955 cache_sta_info = hdd_get_cache_stainfo(pSapCtx->cache_sta_info,
14956 pDestMacAddress);
14957 if (cache_sta_info) {
14958 cache_sta_info->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
14959 cache_sta_info->rx_rate =
14960 wlan_tl_get_sta_rx_rate(pVosContext, cache_sta_info->ucSTAId);
14961 WLANTL_GetSAPStaRSSi(pVosContext, cache_sta_info->ucSTAId,
14962 &cache_sta_info->rssi);
14963 }
14964
Jeff Johnson295189b2012-06-20 16:38:30 -070014965 WLANSAP_DisassocSta(pVosContext,pDestMacAddress);
14966}
14967
14968void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable)
14969{
14970 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14971
14972 ENTER();
14973
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014974 hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%pK, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext);
Jeff Johnson295189b2012-06-20 16:38:30 -070014975
14976 WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable);
14977}
14978
Jeff Johnson295189b2012-06-20 16:38:30 -070014979/**---------------------------------------------------------------------------
14980 *
14981 * \brief hdd_get__concurrency_mode() -
14982 *
14983 *
14984 * \param - None
14985 *
14986 * \return - CONCURRENCY MODE
14987 *
14988 * --------------------------------------------------------------------------*/
14989tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void )
14990{
14991 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
14992 hdd_context_t *pHddCtx;
14993
14994 if (NULL != pVosContext)
14995 {
14996 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
14997 if (NULL != pHddCtx)
14998 {
14999 return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode;
15000 }
15001 }
15002
15003 /* we are in an invalid state :( */
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015004 hddLog(LOGE, "%s: Invalid context", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015005 return VOS_STA;
15006}
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015007v_BOOL_t
15008wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx)
15009{
15010 hdd_adapter_t *pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015011
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015012 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO);
15013 if (pAdapter == NULL)
15014 {
15015 hddLog(VOS_TRACE_LEVEL_INFO,
15016 FL("GO doesn't exist"));
15017 return TRUE;
15018 }
15019 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
15020 {
15021 hddLog(VOS_TRACE_LEVEL_INFO,
15022 FL("GO started"));
15023 return TRUE;
15024 }
15025 else
15026 /* wait till GO changes its interface to p2p device */
15027 hddLog(VOS_TRACE_LEVEL_INFO,
15028 FL("Del_bss called, avoid apps suspend"));
15029 return FALSE;
15030
15031}
Jeff Johnson295189b2012-06-20 16:38:30 -070015032/* Decide whether to allow/not the apps power collapse.
15033 * Allow apps power collapse if we are in connected state.
15034 * if not, allow only if we are in IMPS */
15035v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx)
15036{
15037 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
Srikant Kuppafef66a72013-01-30 17:32:44 -080015038 tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal);
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015039 tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070015040 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15041 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15042 hdd_adapter_t *pAdapter = NULL;
15043 VOS_STATUS status;
Yathish9f22e662012-12-10 14:21:35 -080015044 tVOS_CONCURRENCY_MODE concurrent_state = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015045
Jeff Johnson295189b2012-06-20 16:38:30 -070015046 if (VOS_STA_SAP_MODE == hdd_get_conparam())
15047 return TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015048
Yathish9f22e662012-12-10 14:21:35 -080015049 concurrent_state = hdd_get_concurrency_mode();
15050
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015051 if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) &&
15052 !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx)))
15053 return FALSE;
Yathish9f22e662012-12-10 14:21:35 -080015054#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015055
Yathish9f22e662012-12-10 14:21:35 -080015056 if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) ||
Sushant Kaushikabb7ee62014-07-18 16:20:12 +053015057 (concurrent_state == (VOS_STA | VOS_P2P_GO)))&&
Yathish9f22e662012-12-10 14:21:35 -080015058 (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE))
15059 return TRUE;
15060#endif
15061
Jeff Johnson295189b2012-06-20 16:38:30 -070015062 /*loop through all adapters. TBD fix for Concurrency */
15063 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15064 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15065 {
15066 pAdapter = pAdapterNode->pAdapter;
15067 if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15068 || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15069 {
Srikant Kuppafef66a72013-01-30 17:32:44 -080015070 if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled)
c_hpothu4e8faac2014-05-16 17:38:44 +053015071 && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD
c_hpothu1c6957d2015-01-06 18:19:47 +053015072 && pmcState != STOPPED && pmcState != STANDBY &&
15073 pmcState != WOWL)) ||
Srinivas Girigowdaa553c462013-03-07 19:42:52 -080015074 (eANI_BOOLEAN_TRUE == scanRspPending) ||
15075 (eANI_BOOLEAN_TRUE == inMiddleOfRoaming))
Jeff Johnson295189b2012-06-20 16:38:30 -070015076 {
Mukul Sharma4be88422015-03-09 20:29:07 +053015077 if(pmcState == FULL_POWER &&
15078 sme_IsCoexScoIndicationSet(pHddCtx->hHal))
15079 {
15080 /*
15081 * When SCO indication comes from Coex module , host will
15082 * enter in to full power mode, but this should not prevent
15083 * apps processor power collapse.
15084 */
15085 hddLog(LOG1,
15086 FL("Allow apps power collapse"
15087 "even when sco indication is set"));
15088 return TRUE;
15089 }
Srikant Kuppafef66a72013-01-30 17:32:44 -080015090 hddLog( LOGE, "%s: do not allow APPS power collapse-"
Deepthi Gowri03a979f2016-11-03 15:20:19 +053015091 "pmcState = %d scanRspPending = %d "
15092 "inMiddleOfRoaming = %d connected = %d",
15093 __func__, pmcState, scanRspPending,
15094 inMiddleOfRoaming, hdd_connIsConnected(
15095 WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )));
15096 wlan_hdd_get_tdls_stats(pAdapter);
15097 return FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015098 }
15099 }
15100 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15101 pAdapterNode = pNext;
15102 }
15103 return TRUE;
15104}
15105
Madan Mohan Koyyalamudic72a4d62012-11-08 14:59:34 -080015106/* Decides whether to send suspend notification to Riva
15107 * if any adapter is in BMPS; then it is required */
15108v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx)
15109{
15110 tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal);
15111 hdd_config_t *pConfig = pHddCtx->cfg_ini;
15112
15113 if (pConfig->fIsBmpsEnabled && (pmcState == BMPS))
15114 {
15115 return TRUE;
15116 }
15117 return FALSE;
15118}
15119
Jeff Johnson295189b2012-06-20 16:38:30 -070015120void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15121{
15122 switch(mode)
15123 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015124 case VOS_STA_MODE:
15125 case VOS_P2P_CLIENT_MODE:
15126 case VOS_P2P_GO_MODE:
15127 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015128 case VOS_MONITOR_MODE:
Jeff Johnsone7245742012-09-05 17:12:55 -070015129 pHddCtx->concurrency_mode |= (1 << mode);
Agarwal Ashish51325b52014-06-16 16:50:49 +053015130 pHddCtx->no_of_open_sessions[mode]++;
Jeff Johnson295189b2012-06-20 16:38:30 -070015131 break;
15132 default:
15133 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015134 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015135 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15136 "Number of open sessions for mode %d = %d"),
15137 pHddCtx->concurrency_mode, mode,
15138 pHddCtx->no_of_open_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015139}
15140
15141
15142void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15143{
15144 switch(mode)
15145 {
Chilam Ngc4244af2013-04-01 15:37:32 -070015146 case VOS_STA_MODE:
15147 case VOS_P2P_CLIENT_MODE:
15148 case VOS_P2P_GO_MODE:
15149 case VOS_STA_SAP_MODE:
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015150 case VOS_MONITOR_MODE:
Agarwal Ashish51325b52014-06-16 16:50:49 +053015151 pHddCtx->no_of_open_sessions[mode]--;
15152 if (!(pHddCtx->no_of_open_sessions[mode]))
15153 pHddCtx->concurrency_mode &= (~(1 << mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015154 break;
15155 default:
15156 break;
15157 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053015158 hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x "
15159 "Number of open sessions for mode %d = %d"),
15160 pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]);
15161
15162}
15163/**---------------------------------------------------------------------------
15164 *
15165 * \brief wlan_hdd_incr_active_session()
15166 *
15167 * This function increments the number of active sessions
15168 * maintained per device mode
15169 * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented
15170 * Incase of SAP/P2P GO upon bss start it is incremented
15171 *
15172 * \param pHddCtx - HDD Context
15173 * \param mode - device mode
15174 *
15175 * \return - None
15176 *
15177 * --------------------------------------------------------------------------*/
15178void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15179{
15180 switch (mode) {
15181 case VOS_STA_MODE:
15182 case VOS_P2P_CLIENT_MODE:
15183 case VOS_P2P_GO_MODE:
15184 case VOS_STA_SAP_MODE:
15185 pHddCtx->no_of_active_sessions[mode]++;
15186 break;
15187 default:
15188 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15189 break;
15190 }
15191 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15192 mode,
15193 pHddCtx->no_of_active_sessions[mode]);
15194}
15195
15196/**---------------------------------------------------------------------------
15197 *
15198 * \brief wlan_hdd_decr_active_session()
15199 *
15200 * This function decrements the number of active sessions
15201 * maintained per device mode
15202 * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented
15203 * Incase of SAP/P2P GO upon bss stop it is decremented
15204 *
15205 * \param pHddCtx - HDD Context
15206 * \param mode - device mode
15207 *
15208 * \return - None
15209 *
15210 * --------------------------------------------------------------------------*/
15211void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode)
15212{
Bhargav Shahd0715912015-10-01 18:17:37 +053015213
Agarwal Ashish51325b52014-06-16 16:50:49 +053015214 switch (mode) {
15215 case VOS_STA_MODE:
15216 case VOS_P2P_CLIENT_MODE:
15217 case VOS_P2P_GO_MODE:
15218 case VOS_STA_SAP_MODE:
Agarwal Ashish5325f522014-08-06 00:58:44 +053015219 if (pHddCtx->no_of_active_sessions[mode] > 0)
15220 pHddCtx->no_of_active_sessions[mode]--;
15221 else
15222 hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions"
15223 "is already Zero"));
Agarwal Ashish51325b52014-06-16 16:50:49 +053015224 break;
15225 default:
15226 hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode);
15227 break;
15228 }
15229 hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"),
15230 mode,
15231 pHddCtx->no_of_active_sessions[mode]);
Jeff Johnson295189b2012-06-20 16:38:30 -070015232}
15233
Jeff Johnsone7245742012-09-05 17:12:55 -070015234/**---------------------------------------------------------------------------
15235 *
15236 * \brief wlan_hdd_restart_init
15237 *
15238 * This function initalizes restart timer/flag. An internal function.
15239 *
15240 * \param - pHddCtx
15241 *
15242 * \return - None
15243 *
15244 * --------------------------------------------------------------------------*/
15245
15246static void wlan_hdd_restart_init(hdd_context_t *pHddCtx)
15247{
15248 /* Initialize */
15249 pHddCtx->hdd_restart_retries = 0;
15250 atomic_set(&pHddCtx->isRestartInProgress, 0);
15251 vos_timer_init(&pHddCtx->hdd_restart_timer,
15252 VOS_TIMER_TYPE_SW,
15253 wlan_hdd_restart_timer_cb,
15254 pHddCtx);
15255}
15256/**---------------------------------------------------------------------------
15257 *
15258 * \brief wlan_hdd_restart_deinit
15259 *
15260 * This function cleans up the resources used. An internal function.
15261 *
15262 * \param - pHddCtx
15263 *
15264 * \return - None
15265 *
15266 * --------------------------------------------------------------------------*/
15267
15268static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx)
15269{
15270
15271 VOS_STATUS vos_status;
15272 /* Block any further calls */
15273 atomic_set(&pHddCtx->isRestartInProgress, 1);
15274 /* Cleanup */
15275 vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer );
15276 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015277 hddLog(LOGE, FL("Failed to stop HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015278 vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer);
15279 if (!VOS_IS_STATUS_SUCCESS(vos_status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015280 hddLog(LOGE, FL("Failed to destroy HDD restart timer"));
Jeff Johnsone7245742012-09-05 17:12:55 -070015281
15282}
15283
15284/**---------------------------------------------------------------------------
15285 *
15286 * \brief wlan_hdd_framework_restart
15287 *
15288 * This function uses a cfg80211 API to start a framework initiated WLAN
15289 * driver module unload/load.
15290 *
15291 * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT).
15292 *
15293 *
15294 * \param - pHddCtx
15295 *
15296 * \return - VOS_STATUS_SUCCESS: Success
15297 * VOS_STATUS_E_EMPTY: Adapter is Empty
15298 * VOS_STATUS_E_NOMEM: No memory
15299
15300 * --------------------------------------------------------------------------*/
15301
15302static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx)
15303{
15304 VOS_STATUS status = VOS_STATUS_SUCCESS;
15305 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015306 int len = (sizeof (struct ieee80211_mgmt));
15307 struct ieee80211_mgmt *mgmt = NULL;
15308
15309 /* Prepare the DEAUTH managment frame with reason code */
15310 mgmt = kzalloc(len, GFP_KERNEL);
15311 if(mgmt == NULL)
15312 {
15313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15314 "%s: memory allocation failed (%d bytes)", __func__, len);
15315 return VOS_STATUS_E_NOMEM;
15316 }
15317 mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK;
Jeff Johnsone7245742012-09-05 17:12:55 -070015318
15319 /* Iterate over all adapters/devices */
15320 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015321 if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status))
15322 {
15323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015324 FL("fail to get adapter: %pK %d"), pAdapterNode, status);
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015325 goto end;
15326 }
15327
Jeff Johnsone7245742012-09-05 17:12:55 -070015328 do
15329 {
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015330 if(pAdapterNode->pAdapter &&
15331 WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic)
Jeff Johnsone7245742012-09-05 17:12:55 -070015332 {
15333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
15334 "restarting the driver(intf:\'%s\' mode:%d :try %d)",
15335 pAdapterNode->pAdapter->dev->name,
15336 pAdapterNode->pAdapter->device_mode,
15337 pHddCtx->hdd_restart_retries + 1);
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015338 /*
15339 * CFG80211 event to restart the driver
15340 *
15341 * 'cfg80211_send_unprot_deauth' sends a
15342 * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state
15343 * of SME(Linux Kernel) state machine.
15344 *
15345 * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart
15346 * the driver.
15347 *
15348 */
Abhishek Singh00b71972016-01-07 10:51:04 +053015349
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015350#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
15351 cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len);
15352#else
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015353 cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len );
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053015354#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070015355 }
15356 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15357 pAdapterNode = pNext;
15358 } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status));
15359
Hanumantha Reddy Pothulada0fe362015-02-27 18:37:03 +053015360 end:
Madan Mohan Koyyalamudifc19e442013-05-09 18:24:08 -070015361 /* Free the allocated management frame */
15362 kfree(mgmt);
15363
Jeff Johnsone7245742012-09-05 17:12:55 -070015364 /* Retry until we unload or reach max count */
15365 if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT)
15366 vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS);
15367
15368 return status;
15369
15370}
15371/**---------------------------------------------------------------------------
15372 *
15373 * \brief wlan_hdd_restart_timer_cb
15374 *
15375 * Restart timer callback. An internal function.
15376 *
15377 * \param - User data:
15378 *
15379 * \return - None
15380 *
15381 * --------------------------------------------------------------------------*/
15382
15383void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback)
15384{
15385 hdd_context_t *pHddCtx = usrDataForCallback;
15386 wlan_hdd_framework_restart(pHddCtx);
15387 return;
15388
15389}
15390
15391
15392/**---------------------------------------------------------------------------
15393 *
15394 * \brief wlan_hdd_restart_driver
15395 *
15396 * This function sends an event to supplicant to restart the WLAN driver.
15397 *
15398 * This function is called from vos_wlanRestart.
15399 *
15400 * \param - pHddCtx
15401 *
15402 * \return - VOS_STATUS_SUCCESS: Success
15403 * VOS_STATUS_E_EMPTY: Adapter is Empty
15404 * VOS_STATUS_E_ALREADY: Request already in progress
15405
15406 * --------------------------------------------------------------------------*/
15407VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx)
15408{
15409 VOS_STATUS status = VOS_STATUS_SUCCESS;
15410
15411 /* A tight check to make sure reentrancy */
15412 if(atomic_xchg(&pHddCtx->isRestartInProgress, 1))
15413 {
Mihir Shetefd528652014-06-23 19:07:50 +053015414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnsone7245742012-09-05 17:12:55 -070015415 "%s: WLAN restart is already in progress", __func__);
15416
15417 return VOS_STATUS_E_ALREADY;
15418 }
Sameer Thalappil0c164f52013-03-28 15:27:56 -070015419 /* Send reset FIQ to WCNSS to invoke SSR. */
Madan Mohan Koyyalamudie388b342012-11-08 15:03:16 -080015420#ifdef HAVE_WCNSS_RESET_INTR
Siddharth Bhal864e7e82015-04-07 20:07:24 +053015421 wcnss_reset_fiq(TRUE);
Madan Mohan Koyyalamudibb8f0172012-09-28 15:36:06 -070015422#endif
Madan Mohan Koyyalamudi5aef2af2012-10-05 11:56:27 -070015423
Jeff Johnsone7245742012-09-05 17:12:55 -070015424 return status;
15425}
15426
Bhargav Shahd0715912015-10-01 18:17:37 +053015427/**
15428 * hdd_get_total_sessions() - provide total number of active sessions
15429 * @pHddCtx: Valid Global HDD context pointer
15430 *
15431 * This function iterates through pAdaptors and find the number of all active
15432 * sessions. This active sessions includes connected sta, p2p client and number
15433 * of client connected to sap/p2p go.
15434 *
15435 * Return: Total number of active sessions.
15436 */
15437v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx)
15438{
15439 v_U8_t active_session = 0;
15440 hdd_station_ctx_t *pHddStaCtx;
15441 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15442 hdd_adapter_t *pAdapter;
15443 VOS_STATUS status;
15444
15445 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15446 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15447 pAdapter = pAdapterNode->pAdapter;
15448 switch (pAdapter->device_mode) {
15449 case VOS_STA_MODE:
15450 case VOS_P2P_CLIENT_MODE:
15451 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15452 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
15453 active_session += 1;
15454 break;
15455 case VOS_STA_SAP_MODE:
15456 case VOS_P2P_GO_MODE:
15457 active_session += hdd_softap_get_connected_sta(pAdapter);
15458 break;
15459 default:
15460 break;
15461 }
15462
15463 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
15464 pAdapterNode = pNext;
15465 }
15466
15467 return active_session;
15468}
15469
15470/**
15471 * hdd_set_delack_value() - Set delack value
15472 * @pHddCtx: Valid Global HDD context pointer
15473 * @next_rx_level: Value to set for delack
15474 *
15475 * This function compare present value and next value of delack. If the both
15476 * are diffrent then it sets next value .
15477 *
15478 * Return: void.
15479 */
15480void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level)
15481{
15482 if (pHddCtx->cur_rx_level != next_rx_level) {
15483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15484 "%s: TCP DELACK trigger level %d",
15485 __func__, next_rx_level);
15486 mutex_lock(&pHddCtx->cur_rx_level_lock);
15487 pHddCtx->cur_rx_level = next_rx_level;
15488 mutex_unlock(&pHddCtx->cur_rx_level_lock);
15489 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level,
15490 sizeof(next_rx_level));
15491 }
15492}
15493
15494/**
15495 * hdd_set_default_stop_delack_timer() - Start delack timer
15496 * @pHddCtx: Valid Global HDD context pointer
15497 *
15498 * This function stop delack timer and set delack value to default..
15499 *
15500 * Return: void.
15501 */
15502
15503void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx)
15504{
15505 if (VOS_TIMER_STATE_RUNNING !=
15506 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15508 "%s: Can not stop timer", __func__);
15509 return;
15510 }
15511
15512 vos_timer_stop(&pHddCtx->delack_timer);
15513 hdd_set_delack_value(pHddCtx, TP_IND_LOW);
15514}
15515
15516/**
15517 * hdd_start_delack_timer() - Start delack timer
15518 * @pHddCtx: Valid Global HDD context pointer
15519 *
15520 * This function starts the delack timer for tcpDelAckComputeInterval time
15521 * interval.The default timer value is 2 second.
15522 *
15523 * Return: void.
15524 */
15525void hdd_start_delack_timer(hdd_context_t *pHddCtx)
15526{
15527 if (VOS_TIMER_STATE_RUNNING ==
15528 vos_timer_getCurrentState(&pHddCtx->delack_timer)) {
15529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15530 "%s: Timer is already running", __func__);
15531 return;
15532 }
15533
15534 vos_timer_start(&pHddCtx->delack_timer,
15535 pHddCtx->cfg_ini->tcpDelAckComputeInterval);
15536}
15537
15538/**
15539 * hdd_update_prev_rx_packet_count() - Update previous rx packet count
15540 * @pHddCtx: Valid Global HDD context pointer
15541 *
15542 * This function updates the prev_rx_packets count from the corresponding
15543 * pAdapter states. This prev_rx_packets will diffed with the packet count
15544 * at the end of delack timer. That can give number of RX packet is spacific
15545 * time.
15546 *
15547 * Return: void.
15548 */
15549void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx)
15550{
15551 hdd_adapter_list_node_t *pAdapterNode, *pNext;
15552 hdd_adapter_t *pAdapter;
15553 VOS_STATUS status;
15554
15555 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15556 while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
15557 pAdapter = pAdapterNode->pAdapter;
15558 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
15559 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15560 pAdapterNode = pNext;
15561 }
15562}
15563
15564/**
15565 * hdd_manage_delack_timer() - start\stop delack timer
15566 * @pHddCtx: Valid Global HDD context pointer
15567 *
15568 * This function check the number of concerent session present, it starts the
15569 * delack timer if only one session is present.
15570 * In the case of BT_COEX and TDLS mode it blindly stop delack functionality.
15571 *
15572 * Return: void.
15573 */
15574void hdd_manage_delack_timer(hdd_context_t *pHddCtx)
15575{
15576 uint8_t sessions;
15577
15578 if (!pHddCtx->cfg_ini->enable_delack) {
15579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG,
15580 "%s: TCP DELACK is not enabled", __func__);
15581 return;
15582 }
15583
15584 /* Blindly stop timer of BTCOEX and TDLS Session is up */
15585 if (pHddCtx->mode != 0) {
15586 hdd_set_default_stop_delack_timer(pHddCtx);
15587 return;
15588 }
15589
15590 sessions = hdd_get_total_sessions(pHddCtx);
15591 if (sessions == 1) {
15592 hdd_update_prev_rx_packet_count(pHddCtx);
15593 hdd_start_delack_timer(pHddCtx);
15594 } else {
15595 hdd_set_default_stop_delack_timer(pHddCtx);
15596 }
15597}
15598
Mihir Shetee1093ba2014-01-21 20:13:32 +053015599/**---------------------------------------------------------------------------
15600 *
15601 * \brief wlan_hdd_init_channels
15602 *
15603 * This function is used to initialize the channel list in CSR
15604 *
15605 * This function is called from hdd_wlan_startup
15606 *
15607 * \param - pHddCtx: HDD context
15608 *
15609 * \return - VOS_STATUS_SUCCESS: Success
15610 * VOS_STATUS_E_FAULT: Failure reported by SME
15611
15612 * --------------------------------------------------------------------------*/
15613static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx)
15614{
15615 eHalStatus status;
15616
15617 status = sme_InitChannels(pHddCtx->hHal);
15618 if (HAL_STATUS_SUCCESS(status))
15619 {
15620 return VOS_STATUS_SUCCESS;
15621 }
15622 else
15623 {
15624 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)",
15625 __func__, status);
15626 return VOS_STATUS_E_FAULT;
15627 }
15628}
15629
Mihir Shete04206452014-11-20 17:50:58 +053015630#ifdef CONFIG_ENABLE_LINUX_REG
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015631VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init )
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015632{
15633 eHalStatus status;
15634
Agarwal Ashish6db9d532014-09-30 18:19:10 +053015635 status = sme_InitChannelsForCC(pHddCtx->hHal, init);
Mahesh A Saptasagar74289d22014-05-14 12:43:37 +053015636 if (HAL_STATUS_SUCCESS(status))
15637 {
15638 return VOS_STATUS_SUCCESS;
15639 }
15640 else
15641 {
15642 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)",
15643 __func__, status);
15644 return VOS_STATUS_E_FAULT;
15645 }
15646}
Mihir Shete04206452014-11-20 17:50:58 +053015647#endif
Sudhir Sattayappa Kohallib1d8c3a2013-06-18 14:47:20 -070015648/*
15649 * API to find if there is any STA or P2P-Client is connected
15650 */
15651VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx)
15652{
15653 return sme_isSta_p2p_clientConnected(pHddCtx->hHal);
15654}
Jeff Johnsone7245742012-09-05 17:12:55 -070015655
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015656
15657/*
15658 * API to find if the firmware will send logs using DXE channel
15659 */
15660v_U8_t hdd_is_fw_logging_enabled(void)
15661{
15662 hdd_context_t *pHddCtx;
15663
15664 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15665 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15666
Sachin Ahuja084313e2015-05-21 17:57:10 +053015667 return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging);
Mihir Shetee2ae82a2015-03-16 14:08:49 +053015668}
15669
Agarwal Ashish57e84372014-12-05 18:26:53 +053015670/*
Mihir Shetebe94ebb2015-05-26 12:07:14 +053015671 * API to find if the firmware will send trace logs using DXE channel
15672 */
15673v_U8_t hdd_is_fw_ev_logging_enabled(void)
15674{
15675 hdd_context_t *pHddCtx;
15676
15677 pHddCtx = vos_get_context(VOS_MODULE_ID_HDD,
15678 vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
15679
15680 return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging);
15681}
15682/*
Agarwal Ashish57e84372014-12-05 18:26:53 +053015683 * API to find if there is any session connected
15684 */
15685VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx)
15686{
15687 return sme_is_any_session_connected(pHddCtx->hHal);
15688}
15689
15690
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015691int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter)
15692{
15693 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15694 hdd_scaninfo_t *pScanInfo = NULL;
Girish Gowli4bf7a632014-06-12 13:42:11 +053015695 long status = 0;
c_hpothua3d45d52015-01-05 14:11:17 +053015696 tSirAbortScanStatus abortScanStatus;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015697
15698 pScanInfo = &pHddCtx->scan_info;
Ratnam Rachuric7681132015-06-30 10:35:13 +053015699 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015700 if (pScanInfo->mScanPending)
15701 {
c_hpothua3d45d52015-01-05 14:11:17 +053015702 abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
15703 eCSR_SCAN_ABORT_DEFAULT);
15704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15705 FL("abortScanStatus: %d"), abortScanStatus);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015706
c_hpothua3d45d52015-01-05 14:11:17 +053015707 /* If there is active scan command lets wait for the completion else
15708 * there is no need to wait as scan command might be in the SME pending
15709 * command list.
15710 */
15711 if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY)
15712 {
Mukul Sharmab392b642017-08-17 17:45:29 +053015713 status = wait_for_completion_timeout(
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015714 &pScanInfo->abortscan_event_var,
15715 msecs_to_jiffies(5000));
c_hpothua3d45d52015-01-05 14:11:17 +053015716 if (0 >= status)
15717 {
15718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowli4bf7a632014-06-12 13:42:11 +053015719 "%s: Timeout or Interrupt occurred while waiting for abort"
15720 "scan, status- %ld", __func__, status);
c_hpothua3d45d52015-01-05 14:11:17 +053015721 return -ETIMEDOUT;
15722 }
15723 }
15724 else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE)
15725 {
15726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15727 FL("hdd_abort_mac_scan failed"));
15728 return -VOS_STATUS_E_FAILURE;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015729 }
15730 }
Girish Gowli4bf7a632014-06-12 13:42:11 +053015731 return 0;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015732}
15733
Abhishek Singh7d624e12015-11-30 14:29:27 +053015734/**
15735 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
15736 * user space
15737 * @frame_ind: Management frame data to be informed.
15738 *
15739 * This function is used to indicate management frame to
15740 * user space
15741 *
15742 * Return: None
15743 *
15744 */
15745void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
15746{
15747 hdd_context_t *hdd_ctx = NULL;
15748 hdd_adapter_t *adapter = NULL;
15749 v_CONTEXT_t vos_context = NULL;
15750
15751 /* Get the global VOSS context.*/
15752 vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
15753 if (!vos_context) {
15754 hddLog(LOGE, FL("Global VOS context is Null"));
15755 return;
15756 }
15757 /* Get the HDD context.*/
15758 hdd_ctx =
15759 (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context );
15760
15761 if (0 != wlan_hdd_validate_context(hdd_ctx))
15762 {
15763 return;
15764 }
15765 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
15766 frame_ind->sessionId);
15767
15768 if ((NULL != adapter) &&
15769 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
15770 __hdd_indicate_mgmt_frame(adapter,
15771 frame_ind->frameLen,
15772 frame_ind->frameBuf,
15773 frame_ind->frameType,
15774 frame_ind->rxChan,
15775 frame_ind->rxRssi);
15776 return;
15777
15778}
15779
c_hpothu225aa7c2014-10-22 17:45:13 +053015780VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx)
15781{
15782 hdd_adapter_t *pAdapter;
15783 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15784 VOS_STATUS vosStatus;
15785
15786 vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15787 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15788 {
15789 pAdapter = pAdapterNode->pAdapter;
15790 if (NULL != pAdapter)
15791 {
15792 if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ||
15793 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ||
15794 WLAN_HDD_P2P_GO == pAdapter->device_mode)
15795 {
15796 hddLog(LOG1, FL("abort ROC deviceMode: %d"),
15797 pAdapter->device_mode);
15798 if (VOS_STATUS_SUCCESS !=
15799 wlan_hdd_cancel_existing_remain_on_channel(pAdapter))
15800 {
15801 hddLog(LOGE, FL("failed to abort ROC"));
15802 return VOS_STATUS_E_FAILURE;
15803 }
15804 }
15805 }
15806 vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15807 pAdapterNode = pNext;
15808 }
15809 return VOS_STATUS_SUCCESS;
15810}
Mahesh A Saptasagard477b092015-02-06 15:12:16 +053015811
Mihir Shete0be28772015-02-17 18:42:14 +053015812hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx)
15813{
15814 hdd_adapter_t *pAdapter;
15815 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15816 hdd_cfg80211_state_t *cfgState;
15817 hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL;
15818 VOS_STATUS vosStatus;
15819
15820 vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode);
15821 while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus)
15822 {
15823 pAdapter = pAdapterNode->pAdapter;
15824 if (NULL != pAdapter)
15825 {
15826 cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter);
15827 pRemainChanCtx = cfgState->remain_on_chan_ctx;
15828 if (pRemainChanCtx)
15829 break;
15830 }
15831 vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
15832 pAdapterNode = pNext;
15833 }
15834 return pRemainChanCtx;
15835}
15836
Padma, Santhosh Kumar778d8382015-03-04 17:41:22 +053015837/**
15838 * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels
15839 *
15840 * @pHddCtx: HDD context within host driver
15841 * @dfsScanMode: dfsScanMode passed from ioctl
15842 *
15843 */
15844
15845VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx,
15846 tANI_U8 dfsScanMode)
15847{
15848 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15849 hdd_adapter_t *pAdapter;
15850 VOS_STATUS vosStatus;
15851 hdd_station_ctx_t *pHddStaCtx;
15852 eHalStatus status = eHAL_STATUS_SUCCESS;
15853
15854 if(!pHddCtx)
15855 {
15856 hddLog(LOGE, FL("HDD context is Null"));
15857 return eHAL_STATUS_FAILURE;
15858 }
15859
15860 if (pHddCtx->scan_info.mScanPending)
15861 {
15862 hddLog(LOG1, FL("Aborting scan for sessionId: %d"),
15863 pHddCtx->scan_info.sessionId);
15864 hdd_abort_mac_scan(pHddCtx,
15865 pHddCtx->scan_info.sessionId,
15866 eCSR_SCAN_ABORT_DEFAULT);
15867 }
15868
15869 if (!dfsScanMode)
15870 {
15871 vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
15872 while ((NULL != pAdapterNode) &&
15873 (VOS_STATUS_SUCCESS == vosStatus))
15874 {
15875 pAdapter = pAdapterNode->pAdapter;
15876
15877 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
15878 {
15879 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15880
15881 if(!pHddStaCtx)
15882 {
15883 hddLog(LOGE, FL("HDD STA context is Null"));
15884 return eHAL_STATUS_FAILURE;
15885 }
15886
15887 /* if STA is already connected on DFS channel,
15888 disconnect immediately*/
15889 if (hdd_connIsConnected(pHddStaCtx) &&
15890 (NV_CHANNEL_DFS ==
15891 vos_nv_getChannelEnabledState(
15892 pHddStaCtx->conn_info.operationChannel)))
15893 {
15894 status = sme_RoamDisconnect(pHddCtx->hHal,
15895 pAdapter->sessionId,
15896 eCSR_DISCONNECT_REASON_UNSPECIFIED);
15897 hddLog(LOG1, FL("Client connected on DFS channel %d,"
15898 "sme_RoamDisconnect returned with status: %d"
15899 "for sessionid: %d"), pHddStaCtx->conn_info.
15900 operationChannel, status, pAdapter->sessionId);
15901 }
15902 }
15903
15904 vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode,
15905 &pNext);
15906 pAdapterNode = pNext;
15907 }
15908 }
15909
15910 sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode);
15911 sme_UpdateDFSRoamMode(pHddCtx->hHal,
15912 (dfsScanMode != DFS_CHNL_SCAN_DISABLED));
15913
15914 status = sme_HandleDFSChanScan(pHddCtx->hHal);
15915 if (!HAL_STATUS_SUCCESS(status))
15916 {
15917 hddLog(LOGE,
15918 FL("Failed in sme_HandleDFSChanScan (err=%d)"), status);
15919 return status;
15920 }
15921
15922 return status;
15923}
15924
Nirav Shah7e3c8132015-06-22 23:51:42 +053015925static int hdd_log2_ceil(unsigned value)
15926{
15927 /* need to switch to unsigned math so that negative values
15928 * will right-shift towards 0 instead of -1
15929 */
15930 unsigned tmp = value;
15931 int log2 = -1;
15932
15933 if (value == 0)
15934 return 0;
15935
15936 while (tmp) {
15937 log2++;
15938 tmp >>= 1;
15939 }
15940 if (1U << log2 != value)
15941 log2++;
15942
15943 return log2;
15944}
15945
15946/**
15947 * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash
15948 * @pAdapter: adapter handle
15949 *
15950 * Return: vos status
15951 */
15952VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter)
15953{
15954 int hash_elem, log2, i;
15955
15956 spin_lock_bh( &pAdapter->sta_hash_lock);
15957 if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) {
15958 spin_unlock_bh( &pAdapter->sta_hash_lock);
15959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15960 "%s: hash already attached for session id %d",
15961 __func__, pAdapter->sessionId);
15962 return VOS_STATUS_SUCCESS;
15963 }
15964 spin_unlock_bh( &pAdapter->sta_hash_lock);
15965
15966 hash_elem = WLAN_MAX_STA_COUNT;
15967 hash_elem *= HDD_STA_ID_HASH_MULTIPLIER;
15968 log2 = hdd_log2_ceil(hash_elem);
15969 hash_elem = 1 << log2;
15970
15971 pAdapter->sta_id_hash.mask = hash_elem - 1;
15972 pAdapter->sta_id_hash.idx_bits = log2;
15973 pAdapter->sta_id_hash.bins =
15974 vos_mem_malloc(hash_elem *sizeof(hdd_list_t));
15975 if (!pAdapter->sta_id_hash.bins) {
15976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15977 "%s: malloc failed for session %d",
15978 __func__, pAdapter->sessionId);
15979 return VOS_STATUS_E_NOMEM;
15980 }
15981
15982 for (i = 0; i < hash_elem; i++)
15983 hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT);
15984
15985 spin_lock_bh( &pAdapter->sta_hash_lock);
15986 pAdapter->is_sta_id_hash_initialized = VOS_TRUE;
15987 spin_unlock_bh( &pAdapter->sta_hash_lock);
15988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15989 "%s: Station ID Hash attached for session id %d",
15990 __func__, pAdapter->sessionId);
15991
15992 return VOS_STATUS_SUCCESS;
15993}
15994
15995/**
15996 * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash
15997 * @pAdapter: adapter handle
15998 *
15999 * Return: vos status
16000 */
16001VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter)
16002{
16003 int hash_elem, i;
16004 v_SIZE_t size;
16005
16006 spin_lock_bh( &pAdapter->sta_hash_lock);
16007 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16008 spin_unlock_bh( &pAdapter->sta_hash_lock);
16009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16010 "%s: hash not initialized for session id %d",
16011 __func__, pAdapter->sessionId);
16012 return VOS_STATUS_SUCCESS;
16013 }
16014
16015 pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
16016 spin_unlock_bh( &pAdapter->sta_hash_lock);
16017
16018 hash_elem = 1 << pAdapter->sta_id_hash.idx_bits;
16019
16020 /* free all station info*/
16021 for (i = 0; i < hash_elem; i++) {
16022 hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size);
16023 if (size != 0) {
16024 VOS_STATUS status;
16025 hdd_staid_hash_node_t *sta_info_node = NULL;
16026 hdd_staid_hash_node_t *next_node = NULL;
16027 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i],
16028 (hdd_list_node_t**) &sta_info_node );
16029
16030 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16031 {
16032 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i],
16033 &sta_info_node->node);
16034 vos_mem_free(sta_info_node);
16035
16036 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i],
16037 (hdd_list_node_t*)sta_info_node,
16038 (hdd_list_node_t**)&next_node);
16039 sta_info_node = next_node;
16040 }
16041 }
16042 }
16043
16044 vos_mem_free(pAdapter->sta_id_hash.bins);
16045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16046 "%s: Station ID Hash detached for session id %d",
16047 __func__, pAdapter->sessionId);
16048 return VOS_STATUS_SUCCESS;
16049}
16050
16051/**
16052 * hdd_sta_id_hash_calculate_index() - derive index from macaddr
16053 * @pAdapter: adapter handle
16054 * @mac_addr_in: input mac address
16055 *
16056 * Return: index derived from mac address
16057 */
16058int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter,
16059 v_MACADDR_t *mac_addr_in)
16060{
16061 uint16 index;
16062 struct hdd_align_mac_addr_t * mac_addr =
16063 (struct hdd_align_mac_addr_t *)mac_addr_in;
16064
16065 index = mac_addr->bytes_ab ^
16066 mac_addr->bytes_cd ^ mac_addr->bytes_ef;
16067 index ^= index >> pAdapter->sta_id_hash.idx_bits;
16068 index &= pAdapter->sta_id_hash.mask;
16069 return index;
16070}
16071
16072/**
16073 * hdd_sta_id_hash_add_entry() - add entry in hash
16074 * @pAdapter: adapter handle
16075 * @sta_id: station id
16076 * @mac_addr: mac address
16077 *
16078 * Return: vos status
16079 */
16080VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter,
16081 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16082{
16083 uint16 index;
16084 hdd_staid_hash_node_t *sta_info_node = NULL;
16085
Nirav Shah7e3c8132015-06-22 23:51:42 +053016086 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16087 sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t));
16088 if (!sta_info_node) {
Nirav Shah7e3c8132015-06-22 23:51:42 +053016089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16090 "%s: malloc failed", __func__);
16091 return VOS_STATUS_E_NOMEM;
16092 }
16093
16094 sta_info_node->sta_id = sta_id;
16095 vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t));
16096
Nirav Shah303ed5c2015-08-24 10:29:25 +053016097 spin_lock_bh( &pAdapter->sta_hash_lock);
16098 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16099 spin_unlock_bh( &pAdapter->sta_hash_lock);
16100 vos_mem_free(sta_info_node);
16101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16102 "%s: hash is not initialized for session id %d",
16103 __func__, pAdapter->sessionId);
16104 return VOS_STATUS_E_FAILURE;
16105 }
16106
Nirav Shah7e3c8132015-06-22 23:51:42 +053016107 hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index],
16108 (hdd_list_node_t*) sta_info_node );
16109 spin_unlock_bh( &pAdapter->sta_hash_lock);
16110 return VOS_STATUS_SUCCESS;
16111}
16112
16113/**
16114 * hdd_sta_id_hash_remove_entry() - remove entry from hash
16115 * @pAdapter: adapter handle
16116 * @sta_id: station id
16117 * @mac_addr: mac address
16118 *
16119 * Return: vos status
16120 */
16121VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter,
16122 v_U8_t sta_id, v_MACADDR_t *mac_addr)
16123{
16124 uint16 index;
16125 VOS_STATUS status;
16126 hdd_staid_hash_node_t *sta_info_node = NULL;
16127 hdd_staid_hash_node_t *next_node = NULL;
16128
16129 spin_lock_bh( &pAdapter->sta_hash_lock);
16130 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16131 spin_unlock_bh( &pAdapter->sta_hash_lock);
16132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16133 "%s: hash is not initialized for session id %d",
16134 __func__, pAdapter->sessionId);
16135 return VOS_STATUS_E_FAILURE;
16136 }
16137
16138 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr);
16139 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16140 (hdd_list_node_t**) &sta_info_node );
16141
16142 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16143 {
16144 if (sta_info_node->sta_id == sta_id) {
16145 status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index],
16146 &sta_info_node->node);
16147 vos_mem_free(sta_info_node);
16148 break;
16149 }
16150 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16151 (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node);
16152 sta_info_node = next_node;
16153 }
16154 spin_unlock_bh( &pAdapter->sta_hash_lock);
16155 return status;
16156}
16157
16158/**
16159 * hdd_sta_id_find_from_mac_addr() - find sta id from mac address
16160 * @pAdapter: adapter handle
16161 * @mac_addr_in: mac address
16162 *
16163 * Return: station id
16164 */
16165int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter,
16166 v_MACADDR_t *mac_addr_in)
16167{
16168 uint8 is_found = 0;
16169 uint8 sta_id = HDD_WLAN_INVALID_STA_ID;
16170 uint16 index;
16171 VOS_STATUS status;
16172 hdd_staid_hash_node_t *sta_info_node = NULL;
16173 hdd_staid_hash_node_t *next_node = NULL;
16174
16175 spin_lock_bh( &pAdapter->sta_hash_lock);
16176 if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) {
16177 spin_unlock_bh( &pAdapter->sta_hash_lock);
Bhargav Shahce3b32c2015-08-10 12:29:24 +053016178 hddLog(VOS_TRACE_LEVEL_INFO,
Nirav Shah7e3c8132015-06-22 23:51:42 +053016179 FL("hash is not initialized for session id %d"),
16180 pAdapter->sessionId);
16181 return HDD_WLAN_INVALID_STA_ID;
16182 }
16183
16184 index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in);
16185 status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index],
16186 (hdd_list_node_t**) &sta_info_node );
16187
16188 while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status )
16189 {
16190 if (vos_mem_compare(&sta_info_node->mac_addr,
16191 mac_addr_in, sizeof(v_MACADDR_t))) {
16192 is_found = 1;
16193 sta_id = sta_info_node->sta_id;
16194 break;
16195 }
16196 status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index],
16197 (hdd_list_node_t*)sta_info_node,
16198 (hdd_list_node_t**)&next_node);
16199 sta_info_node = next_node;
16200 }
16201 spin_unlock_bh( &pAdapter->sta_hash_lock);
16202 return sta_id;
16203}
16204
c_manjeecfd1efb2015-09-25 19:32:34 +053016205/*FW memory dump feature*/
16206/**
16207 * This structure hold information about the /proc file
16208 *
16209 */
16210static struct proc_dir_entry *proc_file, *proc_dir;
16211
16212/**
16213 * memdump_read() - perform read operation in memory dump proc file
16214 *
16215 * @file - handle for the proc file.
16216 * @buf - pointer to user space buffer.
16217 * @count - number of bytes to be read.
16218 * @pos - offset in the from buffer.
16219 *
16220 * This function performs read operation for the memory dump proc file.
16221 *
16222 * Return: number of bytes read on success, error code otherwise.
16223 */
16224static ssize_t memdump_read(struct file *file, char __user *buf,
16225 size_t count, loff_t *pos)
16226{
16227 int status;
16228 hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file));
16229 size_t ret_count;
c_manjeef1495642015-10-13 18:35:01 +053016230 loff_t bytes_left;
c_manjeecfd1efb2015-09-25 19:32:34 +053016231 ENTER();
16232
16233 hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos);
16234 status = wlan_hdd_validate_context(hdd_ctx);
16235 if (0 != status) {
16236 return -EINVAL;
16237 }
16238
16239 if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) {
16240 hddLog(LOGE, FL("Current mem dump request timed out/failed"));
16241 return -EINVAL;
16242 }
16243
16244 /* run fs_read_handler in an atomic context*/
16245 vos_ssr_protect(__func__);
c_manjeef1495642015-10-13 18:35:01 +053016246 ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left);
16247 if(bytes_left == 0)
c_manjeecfd1efb2015-09-25 19:32:34 +053016248 {
16249 /*Free the fwr mem dump buffer */
16250 wlan_free_fwr_mem_dump_buffer();
16251 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
c_manjeef1495642015-10-13 18:35:01 +053016252 ret_count=0;
c_manjeecfd1efb2015-09-25 19:32:34 +053016253 }
16254 /*if SSR/unload code is waiting for memdump_read to finish,signal it*/
16255 vos_ssr_unprotect(__func__);
16256 EXIT();
16257 return ret_count;
16258}
16259
16260/**
16261 * struct memdump_fops - file operations for memory dump feature
16262 * @read - read function for memory dump operation.
16263 *
16264 * This structure initialize the file operation handle for memory
16265 * dump feature
16266 */
16267static const struct file_operations memdump_fops = {
16268 read: memdump_read
16269};
16270
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016271struct fw_mem_dump_priv {
16272 uint32_t status;
16273};
16274
c_manjeecfd1efb2015-09-25 19:32:34 +053016275/*
16276* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request
16277* To be passed by HDD to WDA and called upon receiving of response
16278* from firmware
16279* @fwMemDumpReqContext : memory dump request context
16280* @dump_rsp : dump response from HAL
16281* Returns none
16282*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016283void wlan_hdd_fw_mem_dump_cb(void *context,
c_manjeecfd1efb2015-09-25 19:32:34 +053016284 tAniFwrDumpRsp *dump_rsp)
16285{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016286 struct hdd_request *request;
16287 struct fw_mem_dump_priv *priv;
c_manjeecfd1efb2015-09-25 19:32:34 +053016288
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016289 request = hdd_request_get(context);
16290 if (!request) {
16291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16292 return;
16293 }
c_manjeecfd1efb2015-09-25 19:32:34 +053016294
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016295 ENTER();
16296
16297 priv = hdd_request_priv(request);
16298 priv->status = dump_rsp->dump_status;
16299
16300 /* report the status to requesting function and free mem.*/
16301 if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) {
16302 hddLog(LOGE, FL("fw dump request declined by fwr"));
16303 //set the request completion variable
16304 hdd_request_complete(request);
16305 //Free the allocated fwr dump
16306 wlan_free_fwr_mem_dump_buffer();
16307 wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE);
16308 } else {
16309 hddLog(LOG1, FL("fw dump request accepted by fwr"));
16310 /* register the HDD callback which will be called by SVC */
16311 wlan_set_svc_fw_mem_dump_req_cb(
16312 (void*)wlan_hdd_fw_mem_dump_req_cb,
16313 context);
16314 }
16315
16316 hdd_request_put(request);
16317
16318 EXIT();
c_manjeecfd1efb2015-09-25 19:32:34 +053016319}
16320
16321/**
16322 * memdump_procfs_remove() - Remove file/dir under procfs for memory dump
16323 *
16324 * This function removes file/dir under proc file system that was
16325 * processing firmware memory dump
16326 *
16327 * Return: None
16328 */
16329static void memdump_procfs_remove(void)
16330{
16331 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16332 hddLog(LOG1 , FL("/proc/%s/%s removed\n"),
16333 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16334 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16335 hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR);
16336}
16337
16338/**
16339 * memdump_procfs_init() - Initialize procfs for memory dump
16340 *
16341 * @vos_ctx - Global vos context.
16342 *
16343 * This function create file under proc file system to be used later for
16344 * processing firmware memory dump
16345 *
16346 * Return: 0 on success, error code otherwise.
16347 */
16348static int memdump_procfs_init(void *vos_ctx)
16349{
16350 hdd_context_t *hdd_ctx;
16351
16352 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16353 if (!hdd_ctx) {
16354 hddLog(LOGE , FL("Invalid HDD context"));
16355 return -EINVAL;
16356 }
16357
16358 proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL);
16359 if (proc_dir == NULL) {
16360 remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL);
16361 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16362 PROCFS_MEMDUMP_DIR);
16363 return -ENOMEM;
16364 }
16365
16366 proc_file = proc_create_data(PROCFS_MEMDUMP_NAME,
16367 S_IRUSR | S_IWUSR, proc_dir,
16368 &memdump_fops, hdd_ctx);
16369 if (proc_file == NULL) {
16370 remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir);
16371 hddLog(LOGE , FL("Error: Could not initialize /proc/%s"),
16372 PROCFS_MEMDUMP_NAME);
16373 return -ENOMEM;
16374 }
16375
16376 hddLog(LOG1 , FL("/proc/%s/%s created"),
16377 PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME);
16378
16379 return 0;
16380}
16381
16382/**
16383 * memdump_init() - Initialization function for memory dump feature
16384 *
16385 * This function creates proc file for memdump feature and registers
16386 * HDD callback function with SME.
16387 *
16388 * Return - 0 on success, error otherwise
16389 */
16390int memdump_init(void)
16391{
16392 hdd_context_t *hdd_ctx;
16393 void *vos_ctx;
16394 int status = 0;
16395
16396 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16397 if (!vos_ctx) {
16398 hddLog(LOGE, FL("Invalid VOS context"));
16399 return -EINVAL;
16400 }
16401
16402 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16403 if (!hdd_ctx) {
16404 hddLog(LOGE , FL("Invalid HDD context"));
16405 return -EINVAL;
16406 }
16407
16408 status = memdump_procfs_init(vos_ctx);
16409 if (status) {
16410 hddLog(LOGE , FL("Failed to create proc file"));
16411 return status;
16412 }
16413
16414 return 0;
16415}
16416
16417/**
16418 * memdump_deinit() - De initialize memdump feature
16419 *
16420 * This function removes proc file created for memdump feature.
16421 *
16422 * Return: None
16423 */
16424int memdump_deinit(void)
16425{
16426 hdd_context_t *hdd_ctx;
16427 void *vos_ctx;
16428
16429 vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
16430 if (!vos_ctx) {
16431 hddLog(LOGE, FL("Invalid VOS context"));
16432 return -EINVAL;
16433 }
16434
16435 hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
16436 if(!hdd_ctx) {
16437 hddLog(LOGE , FL("Invalid HDD context"));
16438 return -EINVAL;
16439 }
16440
16441 memdump_procfs_remove();
16442 return 0;
16443}
16444
16445/**
16446 * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME
16447 * Return: HAL status
16448 */
16449
16450int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx)
16451{
16452 tAniFwrDumpReq fw_mem_dump_req={0};
16453 eHalStatus status = eHAL_STATUS_FAILURE;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016454 int ret=0, dump_status;
16455 void *cookie;
16456 struct hdd_request *request;
16457 struct fw_mem_dump_priv *priv;
16458 static const struct hdd_request_params params = {
16459 .priv_size = sizeof(*priv),
16460 .timeout_ms = FW_MEM_DUMP_TIMEOUT_MS,
16461 };
16462
c_manjeecfd1efb2015-09-25 19:32:34 +053016463 ENTER();
c_manjeef1495642015-10-13 18:35:01 +053016464
c_manjeecfd1efb2015-09-25 19:32:34 +053016465 /*Check whether a dump request is already going on
16466 *Caution this function will free previously held memory if new dump request is allowed*/
16467 if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) {
16468 hddLog(LOGE, FL("Fw memdump already in progress"));
16469 return -EBUSY;
16470 }
16471 //Allocate memory for fw mem dump buffer
16472 ret = wlan_fwr_mem_dump_buffer_allocation();
16473 if(ret == -EFAULT)
16474 {
16475 hddLog(LOGE, FL("Fwr mem dump not supported by FW"));
16476 return ret;
16477 }
16478 if (0 != ret) {
16479 hddLog(LOGE, FL("Fwr mem Allocation failed"));
16480 return -ENOMEM;
16481 }
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016482
16483 request = hdd_request_alloc(&params);
16484 if (!request) {
16485 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request allocation failure"));
16486 return VOS_STATUS_E_NOMEM;
16487 }
16488 cookie = hdd_request_cookie(request);
c_manjeef1495642015-10-13 18:35:01 +053016489
c_manjeecfd1efb2015-09-25 19:32:34 +053016490 fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016491 fw_mem_dump_req.fwMemDumpReqContext = cookie;
c_manjeecfd1efb2015-09-25 19:32:34 +053016492 status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req);
16493 if(eHAL_STATUS_SUCCESS != status)
16494 {
16495 hddLog(VOS_TRACE_LEVEL_ERROR,
16496 "%s: fw_mem_dump_req failed ", __func__);
16497 wlan_free_fwr_mem_dump_buffer();
c_manjeef1495642015-10-13 18:35:01 +053016498 ret = -EFAULT;
16499 goto cleanup;
c_manjeecfd1efb2015-09-25 19:32:34 +053016500 }
c_manjeef1495642015-10-13 18:35:01 +053016501 /*wait for fw mem dump completion to send event to userspace*/
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016502 ret = hdd_request_wait_for_response(request);
16503 if (ret)
c_manjeef1495642015-10-13 18:35:01 +053016504 {
16505 hddLog(VOS_TRACE_LEVEL_ERROR,
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016506 "%s: fw_mem_dump_req timeout %d ", __func__,ret);
Abhishek Singh4eca9822015-12-09 18:07:34 +053016507 ret = -ETIMEDOUT;
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016508 }else {
16509 priv = hdd_request_priv(request);
16510 dump_status = priv->status;
c_manjeef1495642015-10-13 18:35:01 +053016511 }
16512cleanup:
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016513 hdd_request_put(request);
16514 if(!ret && !dump_status)
Abhishek Singh4eca9822015-12-09 18:07:34 +053016515 ret = -EFAULT;
c_manjeecfd1efb2015-09-25 19:32:34 +053016516
c_manjeef1495642015-10-13 18:35:01 +053016517 EXIT();
Abhishek Singh4eca9822015-12-09 18:07:34 +053016518 return ret;
c_manjeef1495642015-10-13 18:35:01 +053016519}
16520
16521/**
16522 * HDD callback which will be called by SVC to indicate mem dump completion.
16523 */
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016524void wlan_hdd_fw_mem_dump_req_cb(void *context)
c_manjeef1495642015-10-13 18:35:01 +053016525{
Hanumanth Reddy Pothulae856bc22018-04-11 15:35:36 +053016526 struct hdd_request *request;
16527 struct fw_mem_dump_priv *priv;
16528
16529 request = hdd_request_get(context);
16530 if (!request) {
16531 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Obsolete request"));
16532 return;
16533 }
16534
16535 priv = hdd_request_priv(request);
16536 priv->status = true;
16537
16538 hdd_request_complete(request);
16539 hdd_request_put(request);
c_manjeecfd1efb2015-09-25 19:32:34 +053016540}
16541
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016542void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter)
16543{
16544 if (NULL == pAdapter)
16545 {
16546 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__);
16547 return;
16548 }
16549 init_completion(&pAdapter->session_open_comp_var);
16550 init_completion(&pAdapter->session_close_comp_var);
16551 init_completion(&pAdapter->disconnect_comp_var);
16552 init_completion(&pAdapter->linkup_event_var);
16553 init_completion(&pAdapter->cancel_rem_on_chan_var);
16554 init_completion(&pAdapter->rem_on_chan_ready_event);
16555 init_completion(&pAdapter->pno_comp_var);
16556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16557 init_completion(&pAdapter->offchannel_tx_event);
16558#endif
16559 init_completion(&pAdapter->tx_action_cnf_event);
16560#ifdef FEATURE_WLAN_TDLS
16561 init_completion(&pAdapter->tdls_add_station_comp);
16562 init_completion(&pAdapter->tdls_del_station_comp);
16563 init_completion(&pAdapter->tdls_mgmt_comp);
16564 init_completion(&pAdapter->tdls_link_establish_req_comp);
16565#endif
16566
16567#ifdef WLAN_FEATURE_RMC
16568 init_completion(&pAdapter->ibss_peer_info_comp);
16569#endif /* WLAN_FEATURE_RMC */
16570 init_completion(&pAdapter->ula_complete);
16571 init_completion(&pAdapter->change_country_code);
16572
16573#ifdef FEATURE_WLAN_BATCH_SCAN
16574 init_completion(&pAdapter->hdd_set_batch_scan_req_var);
16575 init_completion(&pAdapter->hdd_get_batch_scan_req_var);
16576#endif
Kapil Gupta2b44acb2016-12-30 16:49:51 +053016577 init_completion(&pAdapter->wlan_suspend_comp_var);
Mahesh A Saptasagar67ab9222015-10-21 15:38:41 +053016578
16579 return;
16580}
c_manjeecfd1efb2015-09-25 19:32:34 +053016581
Anurag Chouhan0b29de02016-12-16 13:18:40 +053016582#ifdef MDNS_OFFLOAD
16583
16584/**
16585 * hdd_mdns_enable_offload_done() - mdns enable offload response api
16586 * @padapter: holds adapter
16587 * @status: response status
16588 *
16589 * Return - None
16590 */
16591void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
16592{
16593 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16594
16595 ENTER();
16596
16597 if (NULL == adapter)
16598 {
16599 hddLog(VOS_TRACE_LEVEL_ERROR,
16600 "%s: adapter is NULL",__func__);
16601 return;
16602 }
16603
16604 adapter->mdns_status.mdns_enable_status = status;
16605 vos_event_set(&adapter->mdns_status.vos_event);
16606 return;
16607}
16608
16609/**
16610 * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
16611 * @padapter: holds adapter
16612 * @status: responce status
16613 *
16614 * Return - None
16615 */
16616void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
16617{
16618 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16619
16620 ENTER();
16621
16622 if (NULL == adapter)
16623 {
16624 hddLog(VOS_TRACE_LEVEL_ERROR,
16625 "%s: adapter is NULL",__func__);
16626 return;
16627 }
16628
16629 adapter->mdns_status.mdns_fqdn_status = status;
16630 return;
16631}
16632
16633/**
16634 * hdd_mdns_resp_offload_done() - mdns resp offload response api
16635 * @padapter: holds adapter
16636 * @status: responce status
16637 *
16638 * Return - None
16639 */
16640void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
16641{
16642 hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
16643
16644 ENTER();
16645
16646 if (NULL == adapter)
16647 {
16648 hddLog(VOS_TRACE_LEVEL_ERROR,
16649 "%s: adapter is NULL",__func__);
16650 return;
16651 }
16652
16653 adapter->mdns_status.mdns_resp_status = status;
16654 return;
16655}
16656
16657/**
16658 * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
16659 * @response: Pointer to a struct hdd_mdns_resp_info
16660 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16661 *
16662 * This function will pack the whole domain name without compression. It will
16663 * add the leading len for each field and add zero length octet to terminate
16664 * the domain name.
16665 *
16666 * Return: Return boolean. TRUE for success, FALSE for fail.
16667 */
16668static bool
16669wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
16670 sir_mdns_resp_info resp_info)
16671{
16672 uint8_t num;
16673 uint16_t idx;
16674 uint8_t len = 0;
16675
16676 if ((response == NULL) || (response->data == NULL) ||
16677 (response->offset == NULL)) {
16678 hddLog(LOGE, FL("Either data or offset in response is NULL!"));
16679 return FALSE;
16680 }
16681
16682 if ((resp_info == NULL) ||
16683 (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
16684 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16685 return FALSE;
16686 }
16687
16688 for (num = 0; num < response->num_entries; num++) {
16689 response->offset[num] =
16690 resp_info->resp_len + MDNS_HEADER_LEN;
16691 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16692 len = strlen((char *)&response->data[idx]);
16693 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16694 hddLog(LOGE, FL("resp_len exceeds %d!"),
16695 MAX_MDNS_RESP_LEN);
16696 return FALSE;
16697 }
16698 resp_info->resp_data[resp_info->resp_len] = len;
16699 resp_info->resp_len++;
16700 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16701 &response->data[idx], len);
16702 resp_info->resp_len += len;
16703 }
16704
16705 /* The domain name terminates with the zero length octet */
16706 if (num == response->num_entries) {
16707 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16708 hddLog(LOGE, FL("resp_len exceeds %d!"),
16709 MAX_MDNS_RESP_LEN);
16710 return FALSE;
16711 }
16712 resp_info->resp_data[resp_info->resp_len] = 0;
16713 resp_info->resp_len++;
16714 }
16715
16716 return TRUE;
16717}
16718
16719/**
16720 * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
16721 * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
16722 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16723 *
16724 * Return: None
16725 */
16726static void wlan_hdd_mdns_format_response_u16(uint16_t value,
16727 sir_mdns_resp_info resp_info)
16728{
16729 uint8_t val_u8;
16730
16731 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16732 return;
16733 val_u8 = (value & 0xff00) >> 8;
16734 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16735 val_u8 = value & 0xff;
16736 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16737}
16738
16739/**
16740 * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
16741 * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
16742 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16743 *
16744 * Return: None
16745 */
16746static void wlan_hdd_mdns_format_response_u32(uint32_t value,
16747 sir_mdns_resp_info resp_info)
16748{
16749 uint8_t val_u8;
16750
16751 if ((resp_info == NULL) || (resp_info->resp_data == NULL))
16752 return;
16753 val_u8 = (value & 0xff000000) >> 24;
16754 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16755 val_u8 = (value & 0xff0000) >> 16;
16756 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16757 val_u8 = (value & 0xff00) >> 8;
16758 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16759 val_u8 = value & 0xff;
16760 resp_info->resp_data[resp_info->resp_len++] = val_u8;
16761}
16762
16763/**
16764 * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
16765 * @resp_type: Response type for mDNS
16766 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16767 *
16768 * This function will pack the response type, class and TTL (Time To Live).
16769 *
16770 * Return: Return boolean. TRUE for success, FALSE for fail.
16771 */
16772static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
16773 sir_mdns_resp_info resp_info)
16774{
16775 uint16_t len;
16776
16777 if (resp_info == NULL) {
16778 hddLog(LOGE, FL("resp_info is NULL!"));
16779 return FALSE;
16780 }
16781
16782 len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
16783 if (len >= MAX_MDNS_RESP_LEN) {
16784 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16785 return FALSE;
16786 }
16787
16788 /* Fill Type, Class, TTL */
16789 wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
16790 wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
16791 wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
16792
16793 return TRUE;
16794}
16795
16796/**
16797 * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
16798 * @resp_info: Pointer to a struct tSirMDNSResponseInfo
16799 * @response_dst: The response which domain name is compressed.
16800 * @response_src: The response which domain name is matched with response_dst.
16801 * Its offset is used for data compression.
16802 * @num_matched: The number of matched entries between response_dst and
16803 * response_src
16804 *
16805 * This function will form the different fields of domain name in response_dst
16806 * if any. Then use the offset of the matched domain name in response_src to
16807 * compress the matched domain name.
16808 *
16809 * Return: Return boolean. TRUE for success, FALSE for fail.
16810 */
16811static bool
16812wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
16813 struct hdd_mdns_resp_info *response_dst,
16814 struct hdd_mdns_resp_info *response_src,
16815 uint8_t num_matched)
16816{
16817 uint8_t num, num_diff;
16818 uint16_t value, idx;
16819 uint8_t len = 0;
16820
16821 if ((response_src == NULL) || (response_dst == NULL) ||
16822 (resp_info == NULL)) {
16823 hddLog(LOGE, FL("response info is NULL!"));
16824 return FALSE;
16825 }
16826
16827 if (response_dst->num_entries < num_matched) {
16828 hddLog(LOGE, FL("num_entries is less than num_matched!"));
16829 return FALSE;
16830 }
16831
16832 if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
16833 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
16834 return FALSE;
16835 }
16836
16837 num_diff = response_dst->num_entries - num_matched;
16838 if ((num_diff > 0) && (response_dst->data == NULL)) {
16839 hddLog(LOGE, FL("response_dst->data is NULL!"));
16840 return FALSE;
16841 }
16842
16843 /*
16844 * Handle the unmatched string at the beginning
16845 * Store the length of octets and the octets
16846 */
16847 for (num = 0; num < num_diff; num++) {
16848 response_dst->offset[num] =
16849 resp_info->resp_len + MDNS_HEADER_LEN;
16850 idx = num * MAX_LEN_DOMAINNAME_FIELD;
16851 len = strlen((char *)&response_dst->data[idx]);
16852 if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
16853 hddLog(LOGE, FL("resp_len exceeds %d!"),
16854 MAX_MDNS_RESP_LEN);
16855 return FALSE;
16856 }
16857 resp_info->resp_data[resp_info->resp_len] = len;
16858 resp_info->resp_len++;
16859 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
16860 &response_dst->data[idx], len);
16861 resp_info->resp_len += len;
16862 }
16863 /*
16864 * Handle the matched string from the end
16865 * Just keep the offset and mask the leading two bit
16866 */
16867 if (response_src->num_entries >= num_matched) {
16868 num_diff = response_src->num_entries - num_matched;
16869 value = response_src->offset[num_diff];
16870 if (value > 0) {
16871 value |= 0xc000;
16872 if ((resp_info->resp_len + sizeof(uint16_t)) >=
16873 MAX_MDNS_RESP_LEN) {
16874 hddLog(LOGE, FL("resp_len exceeds %d!"),
16875 MAX_MDNS_RESP_LEN);
16876 return FALSE;
16877 }
16878 wlan_hdd_mdns_format_response_u16(value, resp_info);
16879 return TRUE;
16880 }
16881 }
16882 return FALSE;
16883}
16884
16885/**
16886 * wlan_hdd_mdns_reset_response() - Reset the response info
16887 * @response: The response which info is reset.
16888 *
16889 * Return: None
16890 */
16891static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
16892{
16893 if (response == NULL)
16894 return;
16895 response->num_entries = 0;
16896 response->data = NULL;
16897 response->offset = NULL;
16898}
16899
16900/**
16901 * wlan_hdd_mdns_init_response() - Initialize the response info
16902 * @response: The response which info is initiatized.
16903 * @resp_dname: The domain name string which might be tokenized.
16904 *
16905 * This function will allocate the memory for both response->data and
16906 * response->offset. Besides, it will also tokenize the domain name to some
16907 * entries and fill response->num_entries with the num of entries.
16908 *
16909 * Return: Return boolean. TRUE for success, FALSE for fail.
16910 */
16911static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
16912 uint8_t *resp_dname, char separator)
16913{
16914 uint16_t size;
16915
16916 if ((resp_dname == NULL) || (response == NULL)) {
16917 hddLog(LOGE, FL("resp_dname or response is NULL!"));
16918 return FALSE;
16919 }
16920
16921 size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
16922 response->data = vos_mem_malloc(size);
16923 if (response->data) {
16924 vos_mem_zero(response->data, size);
16925 if (VOS_STATUS_SUCCESS !=
16926 hdd_string_to_string_array((char *)resp_dname,
16927 response->data,
16928 separator,
16929 &response->num_entries,
16930 MAX_NUM_FIELD_DOMAINNAME,
16931 MAX_LEN_DOMAINNAME_FIELD)) {
16932 hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
16933 goto err_init_resp;
16934 }
16935
16936 if ((response->num_entries > 0) &&
16937 (strlen((char *)&response->data[0]) > 0)) {
16938 size = sizeof(uint16_t) * response->num_entries;
16939 response->offset = vos_mem_malloc(size);
16940 if (response->offset) {
16941 vos_mem_zero(response->offset, size);
16942 return TRUE;
16943 }
16944 }
16945 }
16946
16947err_init_resp:
16948 if (response->data)
16949 vos_mem_free(response->data);
16950 wlan_hdd_mdns_reset_response(response);
16951 return FALSE;
16952}
16953
16954/**
16955 * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
16956 * @response1: The response info is used to be compared.
16957 * @response2: The response info is used to be compared.
16958 *
16959 * This function will find the matched entries from the end.
16960 *
16961 * Return: Return the number of the matched entries.
16962 */
16963static uint8_t
16964wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
16965 struct hdd_mdns_resp_info *response2)
16966{
16967 uint8_t min, len1, i;
16968 uint16_t num1, num2;
16969 uint8_t num_matched = 0;
16970
16971 min = VOS_MIN(response1->num_entries, response2->num_entries);
16972
16973 for (i = 1; i <= min; i++) {
16974 num1 = (response1->num_entries - i);
16975 num1 *= MAX_LEN_DOMAINNAME_FIELD;
16976 num2 = (response2->num_entries - i);
16977 num2 *= MAX_LEN_DOMAINNAME_FIELD;
16978 len1 = strlen((char *)&response1->data[num1]);
16979
16980 if ((len1 == 0) ||
16981 (len1 != strlen((char *)&response2->data[num2])))
16982 break;
16983 if (memcmp(&response1->data[num1],
16984 &response2->data[num2], len1))
16985 break;
16986 else
16987 num_matched++;
16988 }
16989
16990 return num_matched;
16991}
16992
16993/**
16994 * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
16995 * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
16996 * @numlist: The number of the elements in the array matchedlist.
16997 *
16998 * Find the max number of the matched entries among the array matchedlist.
16999 *
17000 * Return: None
17001 */
17002static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
17003 uint8_t numlist)
17004{
17005 int j;
17006 struct hdd_mdns_resp_matched tmp;
17007
17008 /* At least two values are used for sorting */
17009 if ((numlist < 2) || (matchedlist == NULL)) {
17010 hddLog(LOGE, FL("At least two values are used for sorting!"));
17011 return;
17012 }
17013
17014 for (j = 0; j < numlist-1; j++) {
17015 if (matchedlist[j].num_matched >
17016 matchedlist[j+1].num_matched) {
17017 vos_mem_copy(&tmp, &matchedlist[j],
17018 sizeof(struct hdd_mdns_resp_matched));
17019 vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
17020 sizeof(struct hdd_mdns_resp_matched));
17021 vos_mem_copy(&matchedlist[j+1], &tmp,
17022 sizeof(struct hdd_mdns_resp_matched));
17023 }
17024 }
17025}
17026
17027/**
17028 * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
17029 * @ini_config: Pointer to the struct hdd_config_t
17030 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17031 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17032 *
17033 * Type A response include QName, response type, class, TTL and Ipv4.
17034 *
17035 * Return: Return boolean. TRUE for success, FALSE for fail.
17036 */
17037static bool
17038wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
17039 sir_mdns_resp_info resp_info,
17040 struct hdd_mdns_resp_info *resptype_a)
17041{
17042 uint16_t value;
17043 uint32_t len;
17044
17045 ENTER();
17046 if ((ini_config == NULL) || (resp_info == NULL) ||
17047 (resptype_a == NULL)) {
17048 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17049 return FALSE;
17050 }
17051
17052 /* No Type A response */
17053 if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
17054 return TRUE;
17055
17056 /* Wrong response is assigned, just ignore this response */
17057 if (!wlan_hdd_mdns_init_response(resptype_a,
17058 ini_config->mdns_resp_type_a, '.'))
17059 return TRUE;
17060
17061 /* Process response domain name */
17062 if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
17063 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17064 MDNS_TYPE_A);
17065 return FALSE;
17066 }
17067
17068 /* Process response Type, Class, TTL */
17069 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
17070 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17071 MDNS_TYPE_A);
17072 return FALSE;
17073 }
17074
17075 /* Process response RDLength, RData */
17076 len = sizeof(uint16_t) + sizeof(uint32_t);
17077 len += resp_info->resp_len;
17078 if (len >= MAX_MDNS_RESP_LEN) {
17079 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17080 return FALSE;
17081 }
17082 value = sizeof(uint32_t);
17083 wlan_hdd_mdns_format_response_u16(value, resp_info);
17084 wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
17085 resp_info);
17086
17087 EXIT();
17088 return TRUE;
17089}
17090
17091/**
17092 * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
17093 * @ini_config: Pointer to the struct hdd_config_t
17094 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17095 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
17096 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17097 *
17098 * Type Txt response include QName, response type, class, TTL and text content.
17099 * Also, it will find the matched QName from resptype_A and compress the data.
17100 *
17101 * Return: Return boolean. TRUE for success, FALSE for fail.
17102 */
17103static bool
17104wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
17105 sir_mdns_resp_info resp_info,
17106 struct hdd_mdns_resp_info *resptype_txt,
17107 struct hdd_mdns_resp_info *resptype_a)
17108{
17109 uint8_t num_matched;
17110 uint8_t num;
17111 uint16_t idx;
17112 uint16_t value = 0;
17113 uint32_t len;
17114 uint32_t total_len;
17115 bool status;
17116 struct hdd_mdns_resp_info resptype_content;
17117
17118 ENTER();
17119
17120 if ((ini_config == NULL) || (resp_info == NULL) ||
17121 (resptype_txt == NULL)) {
17122 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17123 return FALSE;
17124 }
17125
17126 /* No Type Txt response */
17127 if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
17128 return TRUE;
17129
17130 /* Wrong response is assigned, just ignore this response */
17131 if (!wlan_hdd_mdns_init_response(resptype_txt,
17132 ini_config->mdns_resp_type_txt, '.'))
17133 return TRUE;
17134
17135 /*
17136 * For data compression
17137 * Check if any strings are matched with Type A response
17138 */
17139 if (resptype_a && (resptype_a->num_entries > 0)) {
17140 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
17141 resptype_a);
17142 if (num_matched > 0) {
17143 if (!wlan_hdd_mdns_compress_data(resp_info,
17144 resptype_txt, resptype_a, num_matched)) {
17145 hddLog(LOGE, FL("Fail to compress mDNS "
17146 "response (%d)!"), MDNS_TYPE_TXT);
17147 return FALSE;
17148 }
17149 } else {
17150 /*
17151 * num_matched is zero. Error!
17152 * At least ".local" is needed.
17153 */
17154 hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
17155 "response (%d)!"), MDNS_TYPE_TXT);
17156 return FALSE;
17157 }
17158 } else {
17159 /* no TypeA response, so show the whole data */
17160 if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
17161 resp_info)) {
17162 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17163 MDNS_TYPE_TXT);
17164 return FALSE;
17165 }
17166 }
17167
17168 /* Process response Type, Class, TTL */
17169 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
17170 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17171 MDNS_TYPE_TXT);
17172 return FALSE;
17173 }
17174
17175 /*
17176 * Process response RDLength, RData.
17177 * TypeTxt RData include len.
17178 */
17179 status = wlan_hdd_mdns_init_response(&resptype_content,
17180 ini_config->mdns_resp_type_txt_content,
17181 '/');
17182 if (status == FALSE) {
17183 hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
17184 return FALSE;
17185 }
17186
17187 for (num = 0; num < resptype_content.num_entries; num++) {
17188 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17189 value += strlen((char *)&resptype_content.data[idx]);
17190 }
17191
17192 /* content len is uint16_t */
17193 total_len = sizeof(uint16_t);
17194 total_len += resp_info->resp_len + value +
17195 resptype_content.num_entries;
17196
17197 if (total_len >= MAX_MDNS_RESP_LEN) {
17198 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17199 return FALSE;
17200 }
17201 wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
17202 resp_info);
17203
17204 for (num = 0; num < resptype_content.num_entries; num++) {
17205 idx = num * MAX_LEN_DOMAINNAME_FIELD;
17206 len = strlen((char *)&resptype_content.data[idx]);
17207 resp_info->resp_data[resp_info->resp_len] = len;
17208 resp_info->resp_len++;
17209
17210 vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
17211 &resptype_content.data[idx], len);
17212
17213 resp_info->resp_len += len;
17214 hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
17215 num, len, &resptype_content.data[idx]);
17216 }
17217
17218 EXIT();
17219 return TRUE;
17220}
17221
17222/**
17223 * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
17224 * @ini_config: Pointer to the struct hdd_config_t
17225 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17226 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17227 * domain name
17228 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17229 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17230 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17231 *
17232 * The Type Ptr response include Type PTR domain name in its data field.
17233 * Also, it will find the matched QName from the existing resptype_ptr,
17234 * resptype_txt, resptype_a and then compress the data.
17235 *
17236 * Return: Return boolean. TRUE for success, FALSE for fail.
17237 */
17238static bool
17239wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
17240 sir_mdns_resp_info resp_info,
17241 struct hdd_mdns_resp_info *resptype_ptr_dn,
17242 struct hdd_mdns_resp_info *resptype_ptr,
17243 struct hdd_mdns_resp_info *resptype_txt,
17244 struct hdd_mdns_resp_info *resptype_a)
17245{
17246 uint8_t num_matched, numlist, size;
17247 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17248 struct hdd_mdns_resp_info *resp;
17249
17250 if ((ini_config == NULL) || (resp_info == NULL) ||
17251 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17252 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17253 return FALSE;
17254 }
17255
17256 /* No Type Ptr domain name response */
17257 if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
17258 return TRUE;
17259
17260 /* Wrong response is assigned, just ignore this response */
17261 if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
17262 ini_config->mdns_resp_type_ptr_dname, '.'))
17263 return TRUE;
17264
17265 /*
17266 * For data compression
17267 * Check if any strings are matched with previous
17268 * response.
17269 */
17270 numlist = 0;
17271 size = (MAX_MDNS_RESP_TYPE-1);
17272 size *= sizeof(struct hdd_mdns_resp_matched);
17273 vos_mem_zero(matchedlist, size);
17274 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
17275 resptype_ptr);
17276 if (num_matched > 0) {
17277 matchedlist[numlist].num_matched = num_matched;
17278 matchedlist[numlist].type = MDNS_TYPE_PTR;
17279 numlist++;
17280 }
17281 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17282 num_matched = wlan_hdd_mdns_find_entries_from_end(
17283 resptype_ptr_dn, resptype_txt);
17284 if (num_matched > 0) {
17285 matchedlist[numlist].num_matched = num_matched;
17286 matchedlist[numlist].type = MDNS_TYPE_TXT;
17287 numlist++;
17288 }
17289 }
17290 if (resptype_a && (resptype_a->num_entries > 0)) {
17291 num_matched = wlan_hdd_mdns_find_entries_from_end(
17292 resptype_ptr_dn,resptype_a);
17293 if (num_matched > 0) {
17294 matchedlist[numlist].num_matched = num_matched;
17295 matchedlist[numlist].type = MDNS_TYPE_A;
17296 numlist++;
17297 }
17298 }
17299 if (numlist > 0) {
17300 if (numlist > 1)
17301 wlan_hdd_mdns_find_max(matchedlist, numlist);
17302 resp = NULL;
17303 switch (matchedlist[numlist-1].type) {
17304 case MDNS_TYPE_A:
17305 resp = resptype_a;
17306 break;
17307 case MDNS_TYPE_TXT:
17308 resp = resptype_txt;
17309 break;
17310 case MDNS_TYPE_PTR:
17311 resp = resptype_ptr;
17312 break;
17313 default:
17314 hddLog(LOGE, FL("Fail to compress mDNS response "
17315 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17316 return FALSE;
17317 }
17318 num_matched = matchedlist[numlist-1].num_matched;
17319 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
17320 resp, num_matched)) {
17321 hddLog(LOGE, FL("Fail to compress mDNS response "
17322 "(%d)!"), MDNS_TYPE_PTR_DNAME);
17323 return FALSE;
17324 }
17325 } else {
17326 /* num = 0 -> no matched string */
17327 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
17328 resp_info)) {
17329 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17330 MDNS_TYPE_PTR_DNAME);
17331 return FALSE;
17332 }
17333 }
17334
17335 return TRUE;
17336}
17337
17338/**
17339 * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
17340 * @ini_config: Pointer to the struct hdd_config_t
17341 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17342 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17343 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17344 * domain name
17345 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17346 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17347 *
17348 * The Type Ptr response include QName, response type, class, TTL and
17349 * Type PTR domain name. Also, it will find the matched QName from the
17350 * existing resptype_txt, resptype_a and then compress the data.
17351 *
17352 * Return: Return boolean. TRUE for success, FALSE for fail.
17353 */
17354static bool
17355wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
17356 sir_mdns_resp_info resp_info,
17357 struct hdd_mdns_resp_info *resptype_ptr,
17358 struct hdd_mdns_resp_info *resptype_ptr_dn,
17359 struct hdd_mdns_resp_info *resptype_txt,
17360 struct hdd_mdns_resp_info *resptype_a)
17361{
17362 uint8_t num_matched, num_matched1;
17363 uint16_t value;
17364 uint8_t val_u8;
17365 uint32_t offset_data_len, len;
17366
17367 ENTER();
17368 if ((ini_config == NULL) || (resp_info == NULL) ||
17369 (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
17370 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17371 return FALSE;
17372 }
17373
17374 /* No Type Ptr response */
17375 if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
17376 return TRUE;
17377
17378 /* Wrong response is assigned, just ignore this response */
17379 if (!wlan_hdd_mdns_init_response(resptype_ptr,
17380 ini_config->mdns_resp_type_ptr, '.'))
17381 return TRUE;
17382
17383 /*
17384 * For data compression
17385 * Check if any strings are matched with Type A response
17386 */
17387 num_matched = 0;
17388 num_matched1 = 0;
17389 if (resptype_a && (resptype_a->num_entries > 0)) {
17390 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
17391 resptype_a);
17392 }
17393 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17394 num_matched1 = wlan_hdd_mdns_find_entries_from_end(
17395 resptype_ptr, resptype_txt);
17396 }
17397 if ((num_matched != num_matched1) ||
17398 ((num_matched > 0) && (num_matched1 > 0))) {
17399 if (num_matched >= num_matched1) {
17400 if (!wlan_hdd_mdns_compress_data(resp_info,
17401 resptype_ptr, resptype_a, num_matched)) {
17402 hddLog(LOGE, FL("Fail to compress mDNS "
17403 "response (%d)!"), MDNS_TYPE_PTR);
17404 return FALSE;
17405 }
17406 } else {
17407 /* num_matched is less than num_matched1 */
17408 if (!wlan_hdd_mdns_compress_data(resp_info,
17409 resptype_ptr, resptype_txt, num_matched1)) {
17410 hddLog(LOGE, FL("Fail to compress mDNS "
17411 "response (%d)!"), MDNS_TYPE_PTR);
17412 return FALSE;
17413 }
17414 }
17415 } else {
17416 /*
17417 * Both num_matched and num_matched1 are zero.
17418 * no TypeA & TypeTxt
17419 */
17420 if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
17421 resp_info)) {
17422 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17423 MDNS_TYPE_PTR);
17424 return FALSE;
17425 }
17426 }
17427
17428 /* Process response Type, Class, TTL */
17429 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
17430 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17431 MDNS_TYPE_PTR);
17432 return FALSE;
17433 }
17434
17435 /*
17436 * Process response RDLength, RData (Ptr domain name)
17437 * Save the offset of RData length
17438 */
17439 offset_data_len = resp_info->resp_len;
17440 resp_info->resp_len += sizeof(uint16_t);
17441
17442 if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
17443 resptype_ptr_dn, resptype_ptr,
17444 resptype_txt, resptype_a)) {
17445 return FALSE;
17446 }
17447 /* Set the RData length */
17448 len = offset_data_len + sizeof(uint16_t);
17449 if ((resptype_ptr_dn->num_entries > 0) &&
17450 (resp_info->resp_len > len)) {
17451 value = resp_info->resp_len - len;
17452 val_u8 = (value & 0xff00) >> 8;
17453 resp_info->resp_data[offset_data_len] = val_u8;
17454 val_u8 = value & 0xff;
17455 resp_info->resp_data[offset_data_len+1] = val_u8;
17456 } else {
17457 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17458 MDNS_TYPE_PTR);
17459 return FALSE;
17460 }
17461
17462 EXIT();
17463 return TRUE;
17464}
17465
17466/**
17467 * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
17468 * @ini_config: Pointer to the struct hdd_config_t
17469 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17470 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17471 * target
17472 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17473 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17474 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17475 * domain name
17476 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17477 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17478 *
17479 * The Type service target is one of the data field in the Type SRV response.
17480 * Also, it will find the matched QName from the existing resptype_srv,
17481 * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
17482 * the data.
17483 *
17484 * Return: Return boolean. TRUE for success, FALSE for fail.
17485 */
17486static bool
17487wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
17488 sir_mdns_resp_info resp_info,
17489 struct hdd_mdns_resp_info *resptype_srv_tgt,
17490 struct hdd_mdns_resp_info *resptype_srv,
17491 struct hdd_mdns_resp_info *resptype_ptr,
17492 struct hdd_mdns_resp_info *resptype_ptr_dn,
17493 struct hdd_mdns_resp_info *resptype_txt,
17494 struct hdd_mdns_resp_info *resptype_a)
17495{
17496 uint8_t num_matched, num, size;
17497 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17498 struct hdd_mdns_resp_info *resp;
17499
17500 if ((ini_config == NULL) || (resp_info == NULL) ||
17501 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17502 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17503 return FALSE;
17504 }
17505
17506 /* No Type Srv Target response */
17507 if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
17508 return TRUE;
17509
17510 /* Wrong response is assigned, just ignore this response */
17511 if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
17512 ini_config->mdns_resp_type_srv_target, '.'))
17513 return TRUE;
17514
17515 /*
17516 * For data compression
17517 * Check if any strings are matched with previous response.
17518 */
17519 num = 0;
17520 size = (MAX_MDNS_RESP_TYPE-1);
17521 size *= sizeof(struct hdd_mdns_resp_matched);
17522 vos_mem_zero(matchedlist, size);
17523 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
17524 resptype_srv);
17525 if (num_matched > 0) {
17526 matchedlist[num].num_matched = num_matched;
17527 matchedlist[num].type = MDNS_TYPE_SRV;
17528 num++;
17529 }
17530 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17531 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17532 num_matched = wlan_hdd_mdns_find_entries_from_end(
17533 resptype_srv_tgt, resptype_ptr_dn);
17534 if (num_matched > 0) {
17535 matchedlist[num].num_matched = num_matched;
17536 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17537 num++;
17538 }
17539 }
17540 num_matched = wlan_hdd_mdns_find_entries_from_end(
17541 resptype_srv_tgt, resptype_ptr);
17542 if (num_matched > 0) {
17543 matchedlist[num].num_matched = num_matched;
17544 matchedlist[num].type = MDNS_TYPE_PTR;
17545 num++;
17546 }
17547 }
17548 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17549 num_matched = wlan_hdd_mdns_find_entries_from_end(
17550 resptype_srv_tgt, resptype_txt);
17551 if (num_matched > 0) {
17552 matchedlist[num].num_matched = num_matched;
17553 matchedlist[num].type = MDNS_TYPE_TXT;
17554 num++;
17555 }
17556 }
17557 if (resptype_a && (resptype_a->num_entries > 0)) {
17558 num_matched = wlan_hdd_mdns_find_entries_from_end(
17559 resptype_srv_tgt, resptype_a);
17560 if (num_matched > 0) {
17561 matchedlist[num].num_matched = num_matched;
17562 matchedlist[num].type = MDNS_TYPE_A;
17563 num++;
17564 }
17565 }
17566 if (num > 0) {
17567 if (num > 1)
17568 wlan_hdd_mdns_find_max(matchedlist, num);
17569 resp = NULL;
17570 switch (matchedlist[num-1].type) {
17571 case MDNS_TYPE_A:
17572 resp = resptype_a;
17573 break;
17574 case MDNS_TYPE_TXT:
17575 resp = resptype_txt;
17576 break;
17577 case MDNS_TYPE_PTR:
17578 resp = resptype_ptr;
17579 break;
17580 case MDNS_TYPE_PTR_DNAME:
17581 resp = resptype_ptr_dn;
17582 break;
17583 case MDNS_TYPE_SRV:
17584 resp = resptype_srv;
17585 break;
17586 default:
17587 hddLog(LOGE, FL("Fail to compress mDNS response "
17588 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17589 return FALSE;
17590 }
17591 num_matched = matchedlist[num-1].num_matched;
17592 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
17593 resp, num_matched)) {
17594 hddLog(LOGE, FL("Fail to compress mDNS response "
17595 "(%d)!"), MDNS_TYPE_SRV_TARGET);
17596 return FALSE;
17597 }
17598 } else {
17599 /* num = 0 -> no matched string */
17600 if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
17601 resp_info)) {
17602 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17603 MDNS_TYPE_SRV_TARGET);
17604 return FALSE;
17605 }
17606 }
17607
17608 return TRUE;
17609}
17610
17611/**
17612 * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
17613 * @ini_config: Pointer to the struct hdd_config_t
17614 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17615 * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
17616 * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
17617 * target
17618 * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17619 * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
17620 * domain name
17621 * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
17622 * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
17623 *
17624 * The Type SRV (Service) response include QName, response type, class, TTL
17625 * and four kinds of data fields. Also, it will find the matched QName from
17626 * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
17627 * then compress the data.
17628 *
17629 * Return: Return boolean. TRUE for success, FALSE for fail.
17630 */
17631static bool
17632wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
17633 sir_mdns_resp_info resp_info,
17634 struct hdd_mdns_resp_info *resptype_srv,
17635 struct hdd_mdns_resp_info *resptype_srv_tgt,
17636 struct hdd_mdns_resp_info *resptype_ptr,
17637 struct hdd_mdns_resp_info *resptype_ptr_dn,
17638 struct hdd_mdns_resp_info *resptype_txt,
17639 struct hdd_mdns_resp_info *resptype_a)
17640{
17641 uint8_t num_matched, num, size;
17642 uint16_t value;
17643 uint8_t val_u8;
17644 uint32_t offset_data_len, len;
17645 struct hdd_mdns_resp_info *resp;
17646 struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
17647
17648 ENTER();
17649
17650 if ((ini_config == NULL) || (resp_info == NULL) ||
17651 (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
17652 hddLog(LOGE, FL("ini_config or response info is NULL!"));
17653 return FALSE;
17654 }
17655
17656 /* No Type Srv response */
17657 if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
17658 return TRUE;
17659
17660 /* Wrong response is assigned, just ignore this response */
17661 if (!wlan_hdd_mdns_init_response(resptype_srv,
17662 ini_config->mdns_resp_type_srv, '.'))
17663 return TRUE;
17664
17665 /*
17666 * For data compression
17667 * Check if any strings are matched with Type A response
17668 */
17669 num = 0;
17670 size = (MAX_MDNS_RESP_TYPE-1);
17671 size *= sizeof(struct hdd_mdns_resp_matched);
17672 vos_mem_zero(matchedlist, size);
17673 if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
17674 if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
17675 num_matched = wlan_hdd_mdns_find_entries_from_end(
17676 resptype_srv,
17677 resptype_ptr_dn);
17678 if (num_matched > 0) {
17679 matchedlist[num].num_matched = num_matched;
17680 matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
17681 num++;
17682 }
17683 }
17684 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17685 resptype_ptr);
17686 if (num_matched > 0) {
17687 matchedlist[num].num_matched = num_matched;
17688 matchedlist[num].type = MDNS_TYPE_PTR;
17689 num++;
17690 }
17691 }
17692 if (resptype_txt && (resptype_txt->num_entries > 0)) {
17693 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17694 resptype_txt);
17695 if (num_matched > 0) {
17696 matchedlist[num].num_matched =num_matched;
17697 matchedlist[num].type = MDNS_TYPE_TXT;
17698 num++;
17699 }
17700 }
17701 if (resptype_a && (resptype_a->num_entries > 0)) {
17702 num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
17703 resptype_a);
17704 if (num_matched > 0) {
17705 matchedlist[num].num_matched = num_matched;
17706 matchedlist[num].type = MDNS_TYPE_A;
17707 num++;
17708 }
17709 }
17710 if (num > 0) {
17711 if (num > 1)
17712 wlan_hdd_mdns_find_max(matchedlist, num);
17713 resp = NULL;
17714 switch (matchedlist[num-1].type) {
17715 case MDNS_TYPE_A:
17716 resp = resptype_a;
17717 break;
17718 case MDNS_TYPE_TXT:
17719 resp = resptype_txt;
17720 break;
17721 case MDNS_TYPE_PTR:
17722 resp = resptype_ptr;
17723 break;
17724 case MDNS_TYPE_PTR_DNAME:
17725 resp = resptype_ptr_dn;
17726 break;
17727 default:
17728 hddLog(LOGE, FL("Fail to compress mDNS response "
17729 "(%d)!"), MDNS_TYPE_SRV);
17730 return FALSE;
17731 }
17732 num_matched = matchedlist[num-1].num_matched;
17733 if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
17734 resp, num_matched)) {
17735 hddLog(LOGE, FL("Fail to compress mDNS response "
17736 "(%d)!"), MDNS_TYPE_SRV);
17737 return FALSE;
17738 }
17739 } else {
17740 /* num = 0 -> no matched string */
17741 if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
17742 resp_info)) {
17743 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17744 MDNS_TYPE_SRV);
17745 return FALSE;
17746 }
17747 }
17748
17749 /* Process response Type, Class, TTL */
17750 if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
17751 hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
17752 MDNS_TYPE_SRV);
17753 return FALSE;
17754 }
17755
17756 /*
17757 * Process response RDLength, RData (Srv target name)
17758 * Save the offset of RData length
17759 */
17760 offset_data_len = resp_info->resp_len;
17761 resp_info->resp_len += sizeof(uint16_t);
17762
17763 len = resp_info->resp_len + (3 * sizeof(uint16_t));
17764 if (len >= MAX_MDNS_RESP_LEN) {
17765 hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
17766 return FALSE;
17767 }
17768
17769 /* set Srv Priority */
17770 value = ini_config->mdns_resp_type_srv_priority;
17771 wlan_hdd_mdns_format_response_u16(value, resp_info);
17772 /* set Srv Weight */
17773 value = ini_config->mdns_resp_type_srv_weight;
17774 wlan_hdd_mdns_format_response_u16(value, resp_info);
17775 /* set Srv Port */
17776 value = ini_config->mdns_resp_type_srv_port;
17777 wlan_hdd_mdns_format_response_u16(value, resp_info);
17778
17779 if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
17780 resptype_srv_tgt, resptype_srv,
17781 resptype_ptr, resptype_ptr_dn,
17782 resptype_txt, resptype_a)) {
17783 return FALSE;
17784 }
17785 /* Set the RData length */
17786 len = offset_data_len + sizeof(uint16_t);
17787 if ((resptype_srv_tgt->num_entries > 0) &&
17788 (resp_info->resp_len > len)) {
17789 value = resp_info->resp_len - len;
17790 val_u8 = (value & 0xff00) >> 8;
17791 resp_info->resp_data[offset_data_len] = val_u8;
17792 val_u8 = value & 0xff;
17793 resp_info->resp_data[offset_data_len+1] = val_u8;
17794 } else {
17795 hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
17796 MDNS_TYPE_SRV);
17797 return FALSE;
17798 }
17799
17800 EXIT();
17801 return TRUE;
17802}
17803
17804/**
17805 * wlan_hdd_mdns_free_mem() - Free the allocated memory
17806 * @response: Pointer to the struct hdd_mdns_resp_info
17807 *
17808 * Return: None
17809 */
17810static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
17811{
17812 if (response && response->data)
17813 vos_mem_free(response->data);
17814 if (response && response->offset)
17815 vos_mem_free(response->offset);
17816}
17817
17818/**
17819 * wlan_hdd_mdns_pack_response() - Pack mDNS response
17820 * @ini_config: Pointer to the struct hdd_config_t
17821 * @resp_info: Pointer to the struct tSirMDNSResponseInfo
17822 *
17823 * This function will pack four types of responses (Type A, Type Txt, Type Ptr
17824 * and Type Service). Each response contains QName, response type, class, TTL
17825 * and data fields.
17826 *
17827 * Return: Return boolean. TRUE for success, FALSE for fail.
17828 */
17829static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
17830 sir_mdns_resp_info resp_info)
17831{
17832 struct hdd_mdns_resp_info resptype_a, resptype_txt;
17833 struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
17834 struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
17835 uint32_t num_res_records = 0;
17836 bool status = FALSE;
17837
17838 ENTER();
17839
17840 wlan_hdd_mdns_reset_response(&resptype_a);
17841 wlan_hdd_mdns_reset_response(&resptype_txt);
17842 wlan_hdd_mdns_reset_response(&resptype_ptr);
17843 wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
17844 wlan_hdd_mdns_reset_response(&resptype_srv);
17845 wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
17846
17847 resp_info->resp_len = 0;
17848
17849 /* Process Type A response */
17850 if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
17851 &resptype_a))
17852 goto err_resptype_a;
17853
17854 if ((resptype_a.num_entries > 0) &&
17855 (strlen((char *)&resptype_a.data[0]) > 0))
17856 num_res_records++;
17857
17858 /* Process Type TXT response */
17859 if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
17860 &resptype_txt, &resptype_a))
17861 goto err_resptype_txt;
17862
17863 if ((resptype_txt.num_entries > 0) &&
17864 (strlen((char *)&resptype_txt.data[0]) > 0))
17865 num_res_records++;
17866
17867 /* Process Type PTR response */
17868 if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
17869 &resptype_ptr, &resptype_ptr_dn,
17870 &resptype_txt, &resptype_a))
17871 goto err_resptype_ptr;
17872
17873 if ((resptype_ptr.num_entries > 0) &&
17874 (strlen((char *)&resptype_ptr.data[0]) > 0))
17875 num_res_records++;
17876
17877 /* Process Type SRV response */
17878 if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
17879 &resptype_srv, &resptype_srv_tgt,
17880 &resptype_ptr, &resptype_ptr_dn,
17881 &resptype_txt, &resptype_a))
17882 goto err_resptype_srv;
17883
17884 if ((resptype_srv.num_entries > 0) &&
17885 (strlen((char *)&resptype_srv.data[0]) > 0))
17886 num_res_records++;
17887
17888 resp_info->resourceRecord_count = num_res_records;
17889 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
17890 "%s: Pack mDNS response data successfully!", __func__);
17891 status = TRUE;
17892
17893err_resptype_srv:
17894 wlan_hdd_mdns_free_mem(&resptype_srv);
17895 wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
17896
17897err_resptype_ptr:
17898 wlan_hdd_mdns_free_mem(&resptype_ptr);
17899 wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
17900
17901err_resptype_txt:
17902 wlan_hdd_mdns_free_mem(&resptype_txt);
17903
17904err_resptype_a:
17905 wlan_hdd_mdns_free_mem(&resptype_a);
17906
17907 EXIT();
17908 return status;
17909}
17910
17911/**
17912 * wlan_hdd_set_mdns_offload() - Enable mDNS offload
17913 * @hostapd_adapter: Pointer to the struct hdd_adapter_t
17914 *
17915 * This function will set FQDN/unique FQDN (full qualified domain name)
17916 * and the mDNS response. Then send them to SME.
17917 *
17918 * Return: Return boolean. TRUE for success, FALSE for fail.
17919 */
17920bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
17921{
17922 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
17923 sir_mdns_offload_info mdns_offload_info;
17924 sir_mdns_fqdn_info mdns_fqdn_info;
17925 sir_mdns_resp_info mdns_resp_info;
17926 uint32_t fqdn_len, ufqdn_len;
17927
17928 ENTER();
17929
17930 /* 1. Prepare the MDNS fqdn request to send to SME */
17931 fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
17932 ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
17933 if ((fqdn_len == 0) && (ufqdn_len == 0)) {
17934 hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
17935 "ufqdn_len %d!"), fqdn_len, ufqdn_len);
17936 return FALSE;
17937 }
17938
17939 mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
17940 if (NULL == mdns_fqdn_info) {
17941 hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
17942 return FALSE;
17943 }
17944 /* MDNS fqdn request */
17945 if (fqdn_len > 0) {
17946 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17947 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17948 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
17949 mdns_fqdn_info->fqdn_len = fqdn_len;
17950 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17951 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17952 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17953 hdd_ctx->cfg_ini->mdns_fqdn,
17954 mdns_fqdn_info->fqdn_len);
17955
17956 if (eHAL_STATUS_SUCCESS !=
17957 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17958 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17959 vos_mem_free(mdns_fqdn_info);
17960 return FALSE;
17961 }
17962 }
17963 /* MDNS unique fqdn request */
17964 if (ufqdn_len > 0) {
17965 vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
17966 mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
17967 mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
17968 mdns_fqdn_info->fqdn_len = ufqdn_len;
17969 mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
17970 mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
17971 vos_mem_copy(mdns_fqdn_info->fqdn_data,
17972 hdd_ctx->cfg_ini->mdns_uniquefqdn,
17973 mdns_fqdn_info->fqdn_len);
17974 if (eHAL_STATUS_SUCCESS !=
17975 sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
17976 hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
17977 vos_mem_free(mdns_fqdn_info);
17978 return FALSE;
17979 }
17980 }
17981 vos_mem_free(mdns_fqdn_info);
17982
17983 /* 2. Prepare the MDNS response request to send to SME */
17984 mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
17985 if (NULL == mdns_resp_info) {
17986 hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
17987 return FALSE;
17988 }
17989
17990 vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
17991 mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
17992 mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
17993 mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
17994 if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
17995 hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
17996 vos_mem_free(mdns_resp_info);
17997 return FALSE;
17998 }
17999 if (eHAL_STATUS_SUCCESS !=
18000 sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
18001 hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
18002 vos_mem_free(mdns_resp_info);
18003 return FALSE;
18004 }
18005 vos_mem_free(mdns_resp_info);
18006
18007 /* 3. Prepare the MDNS Enable request to send to SME */
18008 mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
18009 if (NULL == mdns_offload_info) {
18010 hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
18011 return FALSE;
18012 }
18013
18014 vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
18015
18016 mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
18017 mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
18018 mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
18019 mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
18020 if (eHAL_STATUS_SUCCESS !=
18021 sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
18022 hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
18023 vos_mem_free(mdns_offload_info);
18024 return FALSE;
18025 }
18026
18027 vos_mem_free(mdns_offload_info);
18028 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
18029 "%s: enable mDNS offload successfully!", __func__);
18030 return TRUE;
18031}
Manjeet Singh3ed79242017-01-11 19:04:32 +053018032
18033
Anurag Chouhan0b29de02016-12-16 13:18:40 +053018034#endif /* MDNS_OFFLOAD */
c_manjeecfd1efb2015-09-25 19:32:34 +053018035
Hanumanth Reddy Pothulad864f312017-01-18 16:16:08 +053018036/**
18037 * wlan_hdd_start_sap() - This function starts bss of SAP.
18038 * @ap_adapter: SAP adapter
18039 *
18040 * This function will process the starting of sap adapter.
18041 *
18042 * Return: void.
18043 */
18044void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
18045{
18046 hdd_ap_ctx_t *hdd_ap_ctx;
18047 hdd_hostapd_state_t *hostapd_state;
18048 VOS_STATUS vos_status;
18049 hdd_context_t *hdd_ctx;
18050 tsap_Config_t *pConfig;
18051
18052 if (NULL == ap_adapter) {
18053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18054 FL("ap_adapter is NULL here"));
18055 return;
18056 }
18057
18058 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
18059 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
18060 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
18061 pConfig = &ap_adapter->sessionCtx.ap.sapConfig;
18062
18063 mutex_lock(&hdd_ctx->sap_lock);
18064 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
18065 goto end;
18066
18067 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
18068 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
18069 goto end;
18070 }
18071
18072 vos_event_reset(&hostapd_state->vosEvent);
18073 if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB,
18074 &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev)
18075 != VOS_STATUS_SUCCESS) {
18076 goto end;
18077 }
18078
18079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18080 FL("Waiting for SAP to start"));
18081 vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000);
18082 if (!VOS_IS_STATUS_SUCCESS(vos_status)) {
18083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18084 FL("SAP Start failed"));
18085 goto end;
18086 }
18087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
18088 FL("SAP Start Success"));
18089 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
18090
18091 wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode);
18092 hostapd_state->bCommit = TRUE;
18093
18094end:
18095 mutex_unlock(&hdd_ctx->sap_lock);
18096 return;
18097}
18098
Manjeet Singh3ed79242017-01-11 19:04:32 +053018099#ifdef WLAN_FEATURE_TSF
18100
18101/**
18102 * hdd_tsf_cb() - handle tsf request callback
18103 *
18104 * @pcb_cxt: pointer to the hdd_contex
18105 * @ptsf: pointer to struct stsf
18106 *
18107 * Based on the request sent .
18108 *
18109 * Return: Describe the execute result of this routine
18110 */
18111static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf)
18112{
18113 hdd_context_t *hddctx;
18114 int status;
18115 hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx;
18116
18117 if (pcb_ctx == NULL || ptsf == NULL) {
18118 hddLog(VOS_TRACE_LEVEL_ERROR,
18119 FL("HDD context is not valid"));
18120 return -EINVAL;
18121 }
18122
18123 hddctx = (hdd_context_t *)pcb_ctx;
18124 status = wlan_hdd_validate_context(hddctx);
18125 if (0 != status)
18126 return -EINVAL;
18127
18128 if (NULL == adapter) {
18129 hddLog(VOS_TRACE_LEVEL_ERROR,
18130 FL("failed to find adapter"));
18131 return -EINVAL;
18132 }
18133
18134 hddLog(VOS_TRACE_LEVEL_INFO,
18135 FL("tsf cb handle event, device_mode is %d"),
18136 adapter->device_mode);
18137
18138 /* copy the return value to hdd_tsf_ctx in adapter*/
18139 if (ptsf->tsf_req_status) {
18140
18141 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18142 adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW;
18143 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18144 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18145 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18146
18147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"),
18148 ptsf->tsf_req_status);
18149 return ptsf->tsf_req_status;
18150 }
18151 /* If this is a get request.Store the tsf values in adapter. */
18152 if (!ptsf->set_tsf_req) {
18153 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18154 adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low;
18155 adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high;
18156 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18157 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18158 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18159
18160 hddLog(VOS_TRACE_LEVEL_INFO,
18161 FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"),
18162 adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high);
18163 }
18164 else {
18165 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18166 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18167 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18168 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18169 }
18170 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18171 vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event);
18172 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18173
18174 /* free allocated mem */
18175 vos_mem_free(ptsf);
18176
18177 return 0;
18178}
18179
18180/**
18181 * hdd_capture_tsf() - capture tsf
18182 *
18183 * @adapter: pointer to adapter
18184 * @buf: pointer to upper layer buf
18185 * @len : the length of buf
18186 *
18187 * This function returns tsf value to uplayer.
18188 *
18189 * Return: Describe the execute result of this routine
18190 */
18191int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18192{
18193 int ret = 0;
18194 hdd_station_ctx_t *hdd_sta_ctx;
18195 hdd_context_t *hdd_ctx;
18196 tSirCapTsfParams cap_tsf_params;
18197 VOS_STATUS status;
18198
18199 if (adapter == NULL || buf == NULL) {
18200 hddLog(VOS_TRACE_LEVEL_ERROR,
18201 FL("invalid pointer"));
18202 return -EINVAL;
18203 }
18204 if (len != 1)
18205 return -EINVAL;
18206
18207 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18208
18209 if (wlan_hdd_validate_context(hdd_ctx)) {
18210 hddLog(VOS_TRACE_LEVEL_ERROR,
18211 FL("invalid hdd ctx"));
18212 return -EINVAL;
18213 }
18214 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18215 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18216 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18217 if (hdd_sta_ctx->conn_info.connState !=
18218 eConnectionState_Associated) {
18219
18220 hddLog(VOS_TRACE_LEVEL_INFO,
18221 FL("failed to cap tsf, not connect with ap"));
18222 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18223 return ret;
18224 }
18225 }
18226 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18227 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18228 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18229 hddLog(VOS_TRACE_LEVEL_INFO,
18230 FL("Soft AP / P2p GO not beaconing"));
18231 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18232 return ret;
18233 }
18234 if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) {
18235 hddLog(VOS_TRACE_LEVEL_INFO,
18236 FL("current in capture state, pls reset"));
18237 buf[0] = TSF_CURRENT_IN_CAP_STATE;
18238 } else {
18239 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18240 buf[0] = TSF_RETURN;
18241 cap_tsf_params.session_id = adapter->sessionId;
18242 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18243 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18244
18245 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18246 adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE;
18247 adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE;
18248 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18249
18250 ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18251
18252 if (ret != VOS_STATUS_SUCCESS) {
18253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18254 buf[0] = TSF_CAPTURE_FAIL;
18255 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18256 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18257 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18258 return -EINVAL;
18259 }
18260 /* wait till we get a response from fw */
18261 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18262 tsf_capture_done_event,
18263 HDD_TSF_CAP_REQ_TIMEOUT);
18264
18265 if (!VOS_IS_STATUS_SUCCESS(status)) {
18266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18267 ("capture tsf vos wait for single_event failed!! %d"),
18268 adapter->tsf_cap_ctx.tsf_get_state);
18269
18270 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18271 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18272 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18273
18274 return -EINVAL;
18275 }
18276 }
18277 buf[0] = TSF_RETURN;
18278 hddLog(VOS_TRACE_LEVEL_INFO,
18279 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18280 return ret;
18281}
18282
18283/**
18284 * hdd_indicate_tsf() - return tsf to uplayer
18285 *
18286 * @adapter: pointer to adapter
18287 * @buf: pointer to uplayer buf
18288 * @len : the length of buf
18289 *
18290 * This function returns tsf value to uplayer.
18291 *
18292 * Return: Describe the execute result of this routine
18293 */
18294int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len)
18295{
18296 int ret = 0;
18297 hdd_station_ctx_t *hdd_sta_ctx;
18298 hdd_context_t *hdd_ctx;
18299 tSirCapTsfParams cap_tsf_params;
18300 VOS_STATUS status;
18301
18302 if (adapter == NULL || buf == NULL) {
18303 hddLog(VOS_TRACE_LEVEL_ERROR,
18304 FL("invalid pointer"));
18305 return -EINVAL;
18306 }
18307 if (len != 3)
18308 return -EINVAL;
18309
18310 buf [1] = 0;
18311 buf [2] = 0;
18312 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
18313
18314 if (wlan_hdd_validate_context(hdd_ctx)) {
18315 hddLog(VOS_TRACE_LEVEL_ERROR,
18316 FL("invalid hdd ctx"));
18317 return -EINVAL;
18318 }
18319 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
18320 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
18321 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18322 if (hdd_sta_ctx->conn_info.connState !=
18323 eConnectionState_Associated) {
18324
18325 hddLog(VOS_TRACE_LEVEL_INFO,
18326 FL("failed to cap tsf, not connect with ap"));
18327 buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF;
18328 return ret;
18329 }
18330 }
18331 if ((adapter->device_mode == WLAN_HDD_SOFTAP ||
18332 adapter->device_mode == WLAN_HDD_P2P_GO) &&
18333 !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) {
18334 hddLog(VOS_TRACE_LEVEL_INFO,
18335 FL("Soft AP / P2p GO not beaconing"));
18336 buf[0] = TSF_SAP_NOT_STARTED_NO_TSF;
18337 return ret;
18338 }
18339
18340 if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE ||
18341 adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) {
18342 hddLog(VOS_TRACE_LEVEL_INFO,
18343 FL("Not in capture state,Enter capture state first"));
18344 buf[0] = TSF_GET_FAIL;
18345 } else {
18346 hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd"));
18347 cap_tsf_params.session_id = adapter->sessionId;
18348 cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb;
18349 cap_tsf_params.tsf_rsp_cb_ctx = adapter;
18350
18351 ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params);
18352
18353 if (ret != VOS_STATUS_SUCCESS) {
18354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail"));
18355 buf[0] = TSF_CAPTURE_FAIL;
18356 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18357 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18358 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18359 return -EINVAL;
18360 }
18361 /* wait till we get a response from fw */
18362 status = vos_wait_single_event(&adapter->tsf_cap_ctx.
18363 tsf_capture_done_event,
18364 HDD_TSF_GET_REQ_TIMEOUT);
18365
18366 if (!VOS_IS_STATUS_SUCCESS(status)) {
18367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18368 ("capture tsf vos wait for single_event failed!! %d"),
18369 status);
18370
18371 vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock);
18372 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18373 vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock);
18374 return status;
18375 }
18376 buf[1] = adapter->tsf_cap_ctx.tsf_low;
18377 buf[2] = adapter->tsf_cap_ctx.tsf_high;
18378
18379 hddLog(VOS_TRACE_LEVEL_INFO,
18380 FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"),
18381 buf[0], buf[1], buf[2]);
18382 }
18383 hddLog(VOS_TRACE_LEVEL_INFO,
18384 FL("ioctl return cap tsf cmd, ret = %d"), ret);
18385 return ret;
18386}
18387
18388void wlan_hdd_tsf_init(hdd_adapter_t *adapter)
18389{
18390
18391 if (adapter == NULL) {
18392 hddLog(VOS_TRACE_LEVEL_ERROR,
18393 FL("TSF init on a null adapter!"));
18394 return;
18395 }
18396
18397 adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN;
18398 adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE;
18399 vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event);
18400 vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock);
18401 adapter->tsf_cap_ctx.tsf_high = 0;
18402 adapter->tsf_cap_ctx.tsf_low = 0;
18403}
18404
18405#endif
18406
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +053018407bool hdd_is_memdump_supported(void)
18408{
18409#ifdef WLAN_FEATURE_MEMDUMP
18410 return true;
18411#endif
18412 return false;
18413}
18414
Jeff Johnson295189b2012-06-20 16:38:30 -070018415//Register the module init/exit functions
18416module_init(hdd_module_init);
18417module_exit(hdd_module_exit);
18418
18419MODULE_LICENSE("Dual BSD/GPL");
18420MODULE_AUTHOR("Qualcomm Atheros, Inc.");
18421MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
18422
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018423static const struct kernel_param_ops con_mode_ops = {
18424 .set = con_mode_handler,
18425 .get = param_get_int,
18426};
18427
18428static const struct kernel_param_ops fwpath_ops = {
18429 .set = fwpath_changed_handler,
18430 .get = param_get_string,
18431};
18432
18433module_param_cb(con_mode, &con_mode_ops, &con_mode,
Madan Mohan Koyyalamudi2331c8a2012-09-18 18:14:48 -070018434 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Jeff Johnson32d95a32012-09-10 13:15:23 -070018435
Ashish Kumar Dhanotiyafb3fd972018-04-30 12:46:52 +053018436module_param_cb(fwpath, &fwpath_ops, &fwpath,
Jeff Johnson32d95a32012-09-10 13:15:23 -070018437 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Arif Hussain66559122013-11-21 10:11:40 -080018438
18439module_param(enable_dfs_chan_scan, int,
18440 S_IRUSR | S_IRGRP | S_IROTH);
18441
18442module_param(enable_11d, int,
18443 S_IRUSR | S_IRGRP | S_IROTH);
18444
18445module_param(country_code, charp,
18446 S_IRUSR | S_IRGRP | S_IROTH);